feat(proxy): improve streaming and error handling

Enhanced proxy endpoint by adding streaming support to handle large files efficiently. Introduced error handling for various HTTP errors and Internal Server errors to provide more robust feedback. Updated content disposition to handle attachment downloads properly.
This commit is contained in:
Kumi 2024-08-03 16:33:32 +02:00
parent 052eeb7531
commit c519a056c2
Signed by: kumi
GPG key ID: ECBCC9082395383F

48
app.py
View file

@ -1,22 +1,50 @@
from flask import Flask, render_template, request from flask import Flask, render_template, request, Response, abort
from werkzeug.exceptions import InternalServerError
from urllib.request import urlopen from urllib.request import urlopen
from urllib.error import HTTPError
from urllib.parse import unquote
app = Flask(__name__) app = Flask(__name__)
@app.route('/')
@app.route("/")
def home(): def home():
domain = request.url_root domain = request.url_root
return render_template('index.html', domain=domain) return render_template("index.html", domain=domain)
@app.route('/<path:url>')
@app.route("/<path:url>")
def proxy(url): def proxy(url):
jsdelivr_url = f'https://cdnjs.cloudflare.com/{url}' jsdelivr_url = f"https://cdnjs.cloudflare.com/{url}"
response = urlopen(jsdelivr_url) def generate():
content = response.read() # Subfunction to allow streaming the data instead of
# downloading all of it at once
try:
with urlopen(unquote(url)) as data:
while True:
chunk = data.read(1024 * 1024)
if not chunk:
break
yield chunk
except HTTPError as e:
abort(e.code)
return content try:
with urlopen(unquote(jsdelivr_url)) as data:
content_type = data.headers["content-type"]
except HTTPError as e:
abort(e.code)
except KeyError:
raise InternalServerError()
if __name__ == '__main__': headers = dict()
app.run() filename = url.split("/")[-1]
headers["Content-Disposition"] = f'attachment; filename="{filename}"'
return Response(generate(), content_type=content_type, headers=headers)
if __name__ == "__main__":
app.run()