使用 aiohttp 和 python 下载具有恢复功能的文件



我想使用aiohttp流式传输和下载文件。 Chrome可以支持下载链接的恢复功能 但下载管理器无法下载具有恢复功能的文件。

在下面的代码中,我使用 aiohttp 框架来流式传输和下载文件, 我还设置了标头参数("接受范围"(以支持恢复功能。

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给出的消息是:"尝试恢复下载时,互联网下载管理器收到服务器的响应,它不支持恢复下载......">

基于此流处理器实现,您似乎缺少指示部分内容的Content-Rangestatus=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

最新更新