curl -C, --continue-at在管道标准输出时是否有效?

问题描述 投票:2回答:1

curl的网页

使用"-C - "告诉curl自动找出恢复传输的方法。然后它使用给定的outputinput文件来计算。

因此,如果使用"-C-"来告诉curl自动找到恢复传输的方法,那么它就会使用给定的输出文件来计算。

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

和下载失败(一次)的半途而废,而服务器支持范围请求,会通过一个范围请求,进行curl重试,所以说 target-program 接收全字节的 some.file.bin 作为它的输入?

bash http curl pipe
1个回答
1
投票

根据测试,curl会 使用范围请求重试。

我写了一个破损的HTTP服务器,要求客户端使用range-request重试以获得完整的响应。使用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())
© www.soinside.com 2019 - 2024. All rights reserved.