Use built-in Range parser
This commit is contained in:
parent
2765fd36e3
commit
10a15f33c8
56
streamtg.py
56
streamtg.py
|
@ -2,6 +2,7 @@ import logging
|
|||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
import os
|
||||
import re
|
||||
import yaml
|
||||
import hmac
|
||||
from aiohttp import web
|
||||
|
@ -16,6 +17,7 @@ client = TelegramClient('streamtg', config['telegram']['api_id'], config['telegr
|
|||
authorized_tokens = config.get('authorized_tokens')
|
||||
hmacs = [hmac.new(i['key'].encode(), digestmod=i['digest']) for i in config.get('hmac', ())]
|
||||
port = os.environ.get('PORT', 8080)
|
||||
bytes_regex = re.compile(r'^(\d*)-(\d*)$')
|
||||
|
||||
def verify_token(token):
|
||||
return token in authorized_tokens
|
||||
|
@ -69,19 +71,45 @@ async def handler(request):
|
|||
max_size = 0
|
||||
for i in messages:
|
||||
max_size += _get_file_info(i).size
|
||||
http_range = request.http_range
|
||||
offset = http_range.start or 0
|
||||
if offset < 0:
|
||||
end = offset
|
||||
offset = max_size - offset
|
||||
else:
|
||||
end = http_range.stop
|
||||
if end is None:
|
||||
end = max_size
|
||||
elif end > max_size:
|
||||
return web.Response(status=416, text='Range end size is bigger than file sizes', headers={'Content-Range': f'bytes */{max_size}'})
|
||||
else:
|
||||
end -= 1
|
||||
status = 200
|
||||
offset = 0
|
||||
end = max_size - 1
|
||||
if range := request.headers.get('Range'):
|
||||
if range.startswith('bytes='):
|
||||
match = bytes_regex.match(range[6:])
|
||||
if not match:
|
||||
return web.Response(status=416,
|
||||
text='Failed to match range with regex',
|
||||
headers={
|
||||
'Content-Range': f'bytes */{max_size}',
|
||||
'Accept-Ranges': 'bytes'
|
||||
}
|
||||
)
|
||||
tmp_offset = match.group(1)
|
||||
tmp_end = match.group(2)
|
||||
if tmp_offset:
|
||||
offset = int(tmp_offset)
|
||||
if tmp_end:
|
||||
end = int(tmp_end)
|
||||
elif tmp_end:
|
||||
offset = max_size - int(tmp_end)
|
||||
else:
|
||||
return web.Response(status=400,
|
||||
text='Both range sides missing',
|
||||
headers={
|
||||
'Content-Range': f'bytes */{max_size}',
|
||||
'Accept-Ranges': 'bytes'
|
||||
}
|
||||
)
|
||||
if offset < 0 or offset > max_size or end >= max_size or offset > end:
|
||||
return web.Response(status=416,
|
||||
text='Range not satisfiable',
|
||||
headers={
|
||||
'Content-Range': f'bytes */{max_size}',
|
||||
'Accept-Ranges': 'bytes'
|
||||
}
|
||||
)
|
||||
status = 206
|
||||
length = end - offset + 1
|
||||
|
||||
async def download():
|
||||
|
@ -101,7 +129,7 @@ async def handler(request):
|
|||
break
|
||||
tmp_offset = 0
|
||||
|
||||
return web.Response(status=206 if (length != max_size) else 200,
|
||||
return web.Response(status=status,
|
||||
body=download(),
|
||||
headers={
|
||||
'Content-Range': f'bytes {offset}-{end}/{max_size}',
|
||||
|
|
Loading…
Reference in New Issue