Загрузите файл с возможностью возобновления, используя aiohttp и python - PullRequest
0 голосов
/ 18 октября 2019

Я хочу транслировать и скачивать файл, используя aiohttp. Chrome может поддерживать возможность возобновления ссылки для скачивания, но менеджер загрузки не может загрузить файл с возможностью возобновления.

В приведенном ниже коде я использовал фреймворк aiohttp для потоковой передачи и загрузки файла, я также установил заголовокпараметр ('Accept-Ranges') для поддержки возможности возобновления.

from telethon import TelegramClient, events
client = TelegramClient(name, api_id,api_hash)

@routes.get('/{userid}/{msgid}')
async def handle(request):
    ...
    response = web.StreamResponse(
        status=200,
        reason='OK',
        headers={
            'Content-Type': content_type,
            'Content-Length':str(file_size),
            'Accept-Ranges': 'bytes',
            'Connection': 'keep-alive',
        }
    )
    await response.prepare(request)
    async for chunk in client.iter_download(msg.media, chunk_size=512):
        await response.write(chunk)
    return response

app = web.Application()
app.add_routes(routes)
web.run_app(app,host='0.0.0.0')

Когда ссылка на скачивание нажата в браузере, файл хорошо транслируется. Возможность возобновления хорошо поддерживается в Chrome, я ожидаю, что менеджер загрузок будет хорошо поддерживать возможность возобновления, но после того, как пауза достигает и начинает загрузку снова, диспетчер загрузки не может продолжить загрузку и требует, чтобы пользователь перезапустил загрузку. В сообщении IDM указано: «При попытке возобновить загрузку интернет-менеджер загрузки получил от сервера ответ о том, что он не поддерживает возобновление загрузки ...»

1 Ответ

0 голосов
/ 19 октября 2019

Основываясь на этой реализации стримера , кажется, что вам не хватает Content-Range и status=206, чтобы указать Частичное содержимое .

Возможно, что-то вродеСледующее может сработать. Обратите внимание, что он не выполняет достаточную проверку (т. Е. Range из заголовков может быть недействительным).

import re

...

async def handle(request):
    offset = request.headers.get('Range', 0)
    if not isinstance(offset, int):
        offset = int(re.match(r'bytes=(\d+)', offset).group(1))

    size = message.file.size
    response = web.StreamResponse(
        headers={
            'Content-Type': 'application/octet-stream',
            'Accept-Ranges': 'bytes',
            'Content-Range': f'bytes {offset}-{size}/{size}'
        },
        status=206 if offset else 200,
    )
    await response.prepare(request)

    async for part in client.iter_download(message.media, offset=offset):
        await response.write(part)

    return response
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...