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)
|
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}',
|
||||||
|
|
Loading…
Reference in New Issue