Срабатывает ли curl - C, - - при работе по стандарту? - PullRequest
3 голосов
/ 02 мая 2020

Из справочная страница curl

Используйте "- C -", чтобы указать curl, чтобы автоматически выяснить, где / как возобновить передачу. Затем он использует заданные файлы вывода / ввода, чтобы выяснить это.

Так что, если использовать

curl \
    --retry 9999 \
    --continue-at - \
    https://mydomain.test/some.file.bin \
| target-program

, и загрузка не удалась (один раз) на полпути, и сервер поддерживает запросы диапазона, будет ли повторная попытка прокрутки через запрос диапазона, поэтому target-program получает в качестве входных данных полные байты some.file.bin?

1 Ответ

1 голос
/ 02 мая 2020

После тестирования curl будет не повторяться с использованием запроса диапазона.

Я написал неработающий HTTP-сервер, требуя от клиента повторной попытки с использованием запроса диапазона для получения полного ответа. Использование wget

wget -O - http://127.0.0.1:8888/ | less

приводит к полному ответу

abcdefghijklmnopqrstuvwxyz

, и на стороне сервера я вижу способ запроса с 'Range': 'bytes=24-' в заголовках запроса.

Тем не менее, использование curl

curl --retry 9999 --continue-at - http://127.0.0.1:8888/ | less

приводит к получению только неполного ответа и без запроса диапазона в журнале сервера.

abcdefghijklmnopqrstuvwx

Используемый сервер Python

import asyncio
import re
from aiohttp import web

async def main():
    data = b'abcdefghijklmnopqrstuvwxyz'

    async def handle(request):
        print(request.headers)

        # A too-short response with an exception that will close the
        # connection, so the client should retry
        if 'Range' not in request.headers:
            start = 0
            end = len(data) - 2
            data_to_send = data[start:end]
            headers = {
                'Content-Length': str(len(data)),
                'Accept-Ranges': 'bytes',
            }
            print('Sending headers', headers)
            print('Sending data', data_to_send)
            response = web.StreamResponse(
                headers=headers,
                status=200,
            )
            await response.prepare(request)
            await response.write(data_to_send)
            raise Exception()

        # Any range request
        match = re.match(r'^bytes=(?P<start>\d+)-(?P<end>\d+)?$', request.headers['Range'])
        start = int(match['start'])
        end = \
            int(match['end']) + 1 if match['end'] else \
            len(data)
        data_to_send = data[start:end + 1]
        headers = {
            'Content-Range': 'bytes {}-{}/{}'.format(start, end - 1, len(data)),
            'Content-Length': str(len(data_to_send)),
        }
        print('Sending headers', headers)
        print('Sending data', data_to_send)
        response = web.StreamResponse(
            headers=headers,
            status=206
        )
        await response.prepare(request)
        await response.write(data_to_send)
        await response.write_eof()
        return response

    app = web.Application()
    app.add_routes([web.get(r'/', handle)])

    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, '0.0.0.0', 8888)
    await site.start()
    await asyncio.Future()

asyncio.run(main())
...