11from functools import wraps
22from core .config import Config
3+ from core .classes import Storage
4+ from typing import Any , List
5+ from aiohttp import web
6+ import random
37import aiohttp
4- import aiohttp .web
58import asyncio
69import base64
710import hashlib
811import time
912
1013class Router :
11- def __init__ (self , https : bool , app : aiohttp . web .Application ) -> None :
14+ def __init__ (self , https : bool , app : web .Application ) -> None :
1215 self .https = https
1316 self .app = app
1417 self .secret = Config .get ('cluster.secret' )
@@ -27,16 +30,20 @@ async def _():
2730 pass
2831
2932 @route ("/download/{hash}" )
30- async def _ (self , request : aiohttp .web .Request ) -> aiohttp .web .Response :
31- response = aiohttp .web .Response
33+ async def _ (self , request : web .Request , storages : List [Storage ]) -> web .Response | web .StreamResponse :
3234 def check_sign (hash : str , secret : str , query : dict ) -> bool :
3335 if not (s := query .get ('s' )) or not (e := query .get ('e' )): return False
3436 sign = base64 .urlsafe_b64encode (hashlib .sha1 (f"{ secret } { hash } { e } " .encode ('utf-8' )).digest ()).decode ('utf-8' ).rstrip ('=' )
3537 return sign == s and time .time () < int (e , 36 )
3638
3739 hash = request .match_info .get ('hash' ).lower ()
38- async with aiohttp .ClientSession () as session :
39- valid = check_sign (hash , self .secret , request .query )
40- if not valid :
41- return response (text = "invalid sign" , status = 403 )
42- response .
40+ valid = check_sign (hash , self .secret , request .query )
41+ if not valid :
42+ return web .Response (text = "invalid sign" , status = 403 )
43+ response = web .StreamResponse (status = 200 )
44+ response .headers ['x-bmclapi-hash' ] = hash
45+ storage = random .randint (0 , len (storages ) - 1 )
46+ data = storages [storage ].express (hash , request , response )
47+ return response
48+
49+
0 commit comments