feat: stream proxy content dynamically

Refactored the proxy route to stream data dynamically from URLs starting
with specific domains, rather than loading it all at once. This change
introduces a subfunction within the proxy route handler to manage
streaming, which iterates through data chunks and yields them until
completion. The new approach aims to enhance performance and resource
utilization by avoiding the download of the entire content before
sending it to the client. Additionally, error handling has been
tightened, specifically for HTTP errors and missing 'content-type'
headers, improving the robustness and reliability of the proxy feature.
This commit is contained in:
Kumi 2024-03-29 08:17:56 +01:00
parent b517139b00
commit 455218f7b6
Signed by: kumi
GPG key ID: ECBCC9082395383F

32
main.py
View file

@ -1186,27 +1186,31 @@ def route_explore():
@app.route("/proxy/")
def route_proxy():
url = request.args.get("url")
if url != None:
if url is not None:
if url.startswith("https://cdn.instructables.com/") or url.startswith(
"https://content.instructables.com/"
):
def generate():
# 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)
try:
data = urlopen(unquote(url))
with urlopen(unquote(url)) as data:
content_type = data.headers["content-type"]
except HTTPError as e:
abort(e.code)
except KeyError:
raise InternalServerError()
content_disposition = data.headers.get("content-disposition")
headers = {}
if content_disposition:
headers["Content-Disposition"] = content_disposition
return Response(
data.read(),
headers=headers,
content_type=data.headers["content-type"],
)
return Response(generate(), content_type=content_type)
else:
raise BadRequest()
else: