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:
parent
b517139b00
commit
455218f7b6
1 changed files with 18 additions and 14 deletions
32
main.py
32
main.py
|
@ -1186,27 +1186,31 @@ def route_explore():
|
||||||
@app.route("/proxy/")
|
@app.route("/proxy/")
|
||||||
def route_proxy():
|
def route_proxy():
|
||||||
url = request.args.get("url")
|
url = request.args.get("url")
|
||||||
if url != None:
|
if url is not None:
|
||||||
if url.startswith("https://cdn.instructables.com/") or url.startswith(
|
if url.startswith("https://cdn.instructables.com/") or url.startswith(
|
||||||
"https://content.instructables.com/"
|
"https://content.instructables.com/"
|
||||||
):
|
):
|
||||||
|
def generate():
|
||||||
|
# Subfunction to allow streaming the data instead of
|
||||||
|
# downloading all of it at once
|
||||||
try:
|
try:
|
||||||
data = urlopen(unquote(url))
|
with urlopen(unquote(url)) as data:
|
||||||
|
while True:
|
||||||
|
chunk = data.read(1024 * 1024)
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
yield chunk
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
abort(e.code)
|
abort(e.code)
|
||||||
|
try:
|
||||||
|
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")
|
return Response(generate(), content_type=content_type)
|
||||||
|
|
||||||
headers = {}
|
|
||||||
|
|
||||||
if content_disposition:
|
|
||||||
headers["Content-Disposition"] = content_disposition
|
|
||||||
|
|
||||||
return Response(
|
|
||||||
data.read(),
|
|
||||||
headers=headers,
|
|
||||||
content_type=data.headers["content-type"],
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
raise BadRequest()
|
raise BadRequest()
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue