2626PATTERN_ID_FIRST = re .compile (r"^(\d+)(?:/.*)?$" )
2727VALID_HASH_REGEX = re .compile (r'^[a-zA-Z0-9_-]+$' )
2828
29+ CORS_HEADERS = {
30+ "Access-Control-Allow-Origin" : "*" ,
31+ "Access-Control-Allow-Methods" : "GET, HEAD, OPTIONS" ,
32+ "Access-Control-Allow-Headers" : "Range, Content-Type, *" ,
33+ "Access-Control-Expose-Headers" : "Content-Length, Content-Range, Content-Disposition" ,
34+ }
35+
2936streamers = {}
3037
3138
@@ -101,7 +108,8 @@ def parse_range_header(range_header: str, file_size: int) -> tuple[int, int]:
101108 raise web .HTTPBadRequest (text = f"Invalid range header: { range_header } " )
102109 suffix_len = int (end_str )
103110 if suffix_len <= 0 :
104- raise web .HTTPRequestRangeNotSatisfiable (headers = {"Content-Range" : f"bytes */{ file_size } " })
111+ raise web .HTTPRequestRangeNotSatisfiable (
112+ headers = {"Content-Range" : f"bytes */{ file_size } " })
105113 start = max (file_size - suffix_len , 0 )
106114 end = file_size - 1
107115
@@ -114,7 +122,6 @@ def parse_range_header(range_header: str, file_size: int) -> tuple[int, int]:
114122
115123
116124@routes .get ("/" , allow_head = True )
117-
118125async def root_redirect (request ):
119126 raise web .HTTPFound ("https://github.com/fyaz05/FileToLink" )
120127
@@ -126,21 +133,39 @@ async def status_endpoint(request):
126133
127134 workload_distribution = {str (k ): v for k , v in sorted (work_loads .items ())}
128135
129- return web .json_response ({
130- "server" : {
131- "status" : "operational" ,
132- "version" : __version__ ,
133- "uptime" : get_readable_time (uptime )
134- },
135- "telegram_bot" : {
136- "username" : f"@{ StreamBot .username } " ,
137- "active_clients" : len (multi_clients )
136+ return web .json_response (
137+ {
138+ "server" : {
139+ "status" : "operational" ,
140+ "version" : __version__ ,
141+ "uptime" : get_readable_time (uptime )
142+ },
143+ "telegram_bot" : {
144+ "username" : f"@{ StreamBot .username } " ,
145+ "active_clients" : len (multi_clients )
146+ },
147+ "resources" : {
148+ "total_workload" : total_load ,
149+ "workload_distribution" : workload_distribution
150+ }
138151 },
139- "resources" : {
140- "total_workload" : total_load ,
141- "workload_distribution" : workload_distribution
152+ headers = {"Access-Control-Allow-Origin" : "*" }
153+ )
154+
155+
156+ @routes .options ("/status" )
157+ async def status_options (request : web .Request ):
158+ return web .Response (headers = {
159+ ** CORS_HEADERS ,
160+ "Access-Control-Max-Age" : "86400"
161+ })
142162
143- }
163+
164+ @routes .options (r"/{path:.+}" )
165+ async def media_options (request : web .Request ):
166+ return web .Response (headers = {
167+ ** CORS_HEADERS ,
168+ "Access-Control-Max-Age" : "86400"
144169 })
145170
146171
@@ -152,15 +177,25 @@ async def media_preview(request: web.Request):
152177
153178 rendered_page = await render_page (
154179 message_id , secure_hash , requested_action = 'stream' )
155- return web .Response (text = rendered_page , content_type = 'text/html' )
180+
181+ response = web .Response (
182+ text = rendered_page ,
183+ content_type = 'text/html' ,
184+ headers = {
185+ "Access-Control-Allow-Origin" : "*" ,
186+ "Access-Control-Allow-Headers" : "Range, Content-Type, *" ,
187+ "X-Content-Type-Options" : "nosniff" ,
188+ }
189+ )
190+ response .enable_compression ()
191+ return response
156192
157193 except (InvalidHash , FileNotFound ) as e :
158194 logger .debug (
159195 f"Client error in preview: { type (e ).__name__ } - { e } " ,
160196 exc_info = True )
161197 raise web .HTTPNotFound (text = "Resource not found" ) from e
162198 except Exception as e :
163-
164199 error_id = secrets .token_hex (6 )
165200 logger .error (f"Preview error { error_id } : { e } " , exc_info = True )
166201 raise web .HTTPInternalServerError (
@@ -201,8 +236,13 @@ async def media_delivery(request: web.Request):
201236
202237 mime_type = (
203238 file_info .get ('mime_type' ) or 'application/octet-stream' )
204- filename = (
205- file_info .get ('file_name' ) or f"file_{ secrets .token_hex (4 )} " )
239+
240+ filename = file_info .get ('file_name' )
241+ if not filename :
242+ ext = mime_type .split ('/' )[- 1 ] if '/' in mime_type else 'bin'
243+ ext_map = {'jpeg' : 'jpg' , 'mpeg' : 'mp3' , 'octet-stream' : 'bin' }
244+ ext = ext_map .get (ext , ext )
245+ filename = f"file_{ secrets .token_hex (4 )} .{ ext } "
206246
207247 headers = {
208248 "Content-Type" : mime_type ,
@@ -211,7 +251,12 @@ async def media_delivery(request: web.Request):
211251 f"inline; filename*=UTF-8''{ quote (filename )} " ),
212252 "Accept-Ranges" : "bytes" ,
213253 "Cache-Control" : "public, max-age=31536000" ,
214- "Connection" : "keep-alive"
254+ "Connection" : "keep-alive" ,
255+ "Access-Control-Allow-Origin" : "*" ,
256+ "Access-Control-Allow-Headers" : "Range, Content-Type, *" ,
257+ "Access-Control-Expose-Headers" : (
258+ "Content-Length, Content-Range, Content-Disposition" ),
259+ "X-Content-Type-Options" : "nosniff"
215260 }
216261
217262 if range_header :
@@ -250,6 +295,7 @@ async def stream_generator():
250295 break
251296 finally :
252297 work_loads [client_id ] -= 1
298+
253299 return web .Response (
254300 status = 206 if range_header else 200 ,
255301 body = stream_generator (),
0 commit comments