Use built-in Range parser

This commit is contained in:
blank X 2021-05-06 09:42:10 +07:00
parent 2765fd36e3
commit 10a15f33c8
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
1 changed files with 42 additions and 14 deletions

View File

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