mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 06:52:21 -04:00
Factor flask.make_response() calls out into helper function
This commit is contained in:
parent
bd88d15303
commit
5082d9ae5c
1 changed files with 26 additions and 38 deletions
|
@ -174,15 +174,24 @@ def _mime_for_path(path: str) -> str:
|
||||||
return mime or "application/octet-stream"
|
return mime or "application/octet-stream"
|
||||||
|
|
||||||
|
|
||||||
|
def _text_response(code: HTTPStatus, text: str) -> Response:
|
||||||
|
"""Return an error message.
|
||||||
|
|
||||||
|
Response is returned as text/plain, so no escaping of untrusted
|
||||||
|
input is required."""
|
||||||
|
resp = flask.make_response(text, code)
|
||||||
|
resp.headers["Content-type"] = "text/plain"
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
||||||
directory = request.root
|
directory = request.root
|
||||||
path = request.path
|
path = request.path
|
||||||
try:
|
try:
|
||||||
isdir = os.path.isdir(os.path.join(directory, path))
|
isdir = os.path.isdir(os.path.join(directory, path))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return flask.make_response(
|
return _text_response(
|
||||||
f"Path for '{directory} - {path}' is too long!",
|
HTTPStatus.BAD_REQUEST, f"Path for '{directory} - {path}' is too long!"
|
||||||
HTTPStatus.BAD_REQUEST,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
directory = os.path.realpath(directory)
|
directory = os.path.realpath(directory)
|
||||||
|
@ -191,15 +200,14 @@ def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
||||||
|
|
||||||
# protect against directory transversal: https://security.openstack.org/guidelines/dg_using-file-paths.html
|
# protect against directory transversal: https://security.openstack.org/guidelines/dg_using-file-paths.html
|
||||||
if not fullpath.startswith(directory):
|
if not fullpath.startswith(directory):
|
||||||
return flask.make_response(
|
return _text_response(
|
||||||
f"Path for '{directory} - {path}' is a security leak!",
|
HTTPStatus.FORBIDDEN, f"Path for '{directory} - {path}' is a security leak!"
|
||||||
HTTPStatus.FORBIDDEN,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if isdir:
|
if isdir:
|
||||||
return flask.make_response(
|
return _text_response(
|
||||||
f"Path for '{directory} - {path}' is a directory (not supported)!",
|
|
||||||
HTTPStatus.FORBIDDEN,
|
HTTPStatus.FORBIDDEN,
|
||||||
|
f"Path for '{directory} - {path}' is a directory (not supported)!",
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -219,10 +227,7 @@ def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(f"Not found: {path}")
|
print(f"Not found: {path}")
|
||||||
return flask.make_response(
|
return _text_response(HTTPStatus.NOT_FOUND, f"Invalid path: {path}")
|
||||||
f"Invalid path: {path}",
|
|
||||||
HTTPStatus.NOT_FOUND,
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
if dev_mode:
|
if dev_mode:
|
||||||
|
@ -234,10 +239,7 @@ def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
||||||
# swallow it - user likely surfed away from
|
# swallow it - user likely surfed away from
|
||||||
# review screen before an image had finished
|
# review screen before an image had finished
|
||||||
# downloading
|
# downloading
|
||||||
return flask.make_response(
|
return _text_response(HTTPStatus.INTERNAL_SERVER_ERROR, str(error))
|
||||||
str(error),
|
|
||||||
HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _builtin_data(path: str) -> bytes:
|
def _builtin_data(path: str) -> bytes:
|
||||||
|
@ -270,10 +272,7 @@ def _handle_builtin_file_request(request: BundledFileRequest) -> Response:
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
if dev_mode:
|
if dev_mode:
|
||||||
print(f"404: {data_path}")
|
print(f"404: {data_path}")
|
||||||
resp = flask.make_response(
|
resp = _text_response(HTTPStatus.NOT_FOUND, f"Invalid path: {path}")
|
||||||
f"Invalid path: {path}",
|
|
||||||
HTTPStatus.NOT_FOUND,
|
|
||||||
)
|
|
||||||
# we're including the path verbatim in our response, so we need to either use
|
# we're including the path verbatim in our response, so we need to either use
|
||||||
# plain text, or escape HTML characters to avoid reflecting untrusted input
|
# plain text, or escape HTML characters to avoid reflecting untrusted input
|
||||||
resp.headers["Content-type"] = "text/plain"
|
resp.headers["Content-type"] = "text/plain"
|
||||||
|
@ -288,10 +287,7 @@ def _handle_builtin_file_request(request: BundledFileRequest) -> Response:
|
||||||
# swallow it - user likely surfed away from
|
# swallow it - user likely surfed away from
|
||||||
# review screen before an image had finished
|
# review screen before an image had finished
|
||||||
# downloading
|
# downloading
|
||||||
return flask.make_response(
|
return _text_response(HTTPStatus.INTERNAL_SERVER_ERROR, str(error))
|
||||||
str(error),
|
|
||||||
HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/<path:pathin>", methods=["GET", "POST"])
|
@app.route("/<path:pathin>", methods=["GET", "POST"])
|
||||||
|
@ -310,10 +306,7 @@ def handle_request(pathin: str) -> Response:
|
||||||
|
|
||||||
if isinstance(req, NotFound):
|
if isinstance(req, NotFound):
|
||||||
print(req.message)
|
print(req.message)
|
||||||
return flask.make_response(
|
return _text_response(HTTPStatus.NOT_FOUND, f"Invalid path: {pathin}")
|
||||||
f"Invalid path: {pathin}",
|
|
||||||
HTTPStatus.NOT_FOUND,
|
|
||||||
)
|
|
||||||
elif callable(req):
|
elif callable(req):
|
||||||
return _handle_dynamic_request(req)
|
return _handle_dynamic_request(req)
|
||||||
elif isinstance(req, BundledFileRequest):
|
elif isinstance(req, BundledFileRequest):
|
||||||
|
@ -321,10 +314,7 @@ def handle_request(pathin: str) -> Response:
|
||||||
elif isinstance(req, LocalFileRequest):
|
elif isinstance(req, LocalFileRequest):
|
||||||
return _handle_local_file_request(req)
|
return _handle_local_file_request(req)
|
||||||
else:
|
else:
|
||||||
return flask.make_response(
|
return _text_response(HTTPStatus.FORBIDDEN, f"unexpected request: {pathin}")
|
||||||
f"unexpected request: {pathin}",
|
|
||||||
HTTPStatus.FORBIDDEN,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def is_sveltekit_page(path: str) -> bool:
|
def is_sveltekit_page(path: str) -> bool:
|
||||||
|
@ -665,12 +655,10 @@ def _extract_collection_post_request(path: str) -> DynamicRequest | NotFound:
|
||||||
response = flask.make_response(data)
|
response = flask.make_response(data)
|
||||||
response.headers["Content-Type"] = "application/binary"
|
response.headers["Content-Type"] = "application/binary"
|
||||||
else:
|
else:
|
||||||
response = flask.make_response("", HTTPStatus.NO_CONTENT)
|
response = _text_response(HTTPStatus.NO_CONTENT, "")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
response = flask.make_response(
|
response = _text_response(HTTPStatus.INTERNAL_SERVER_ERROR, str(exc))
|
||||||
str(exc), HTTPStatus.INTERNAL_SERVER_ERROR
|
|
||||||
)
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
return wrapped
|
return wrapped
|
||||||
|
@ -718,7 +706,7 @@ def _handle_dynamic_request(req: DynamicRequest) -> Response:
|
||||||
try:
|
try:
|
||||||
return req()
|
return req()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return flask.make_response(str(e), HTTPStatus.INTERNAL_SERVER_ERROR)
|
return _text_response(HTTPStatus.INTERNAL_SERVER_ERROR, str(e))
|
||||||
|
|
||||||
|
|
||||||
def legacy_page_data() -> Response:
|
def legacy_page_data() -> Response:
|
||||||
|
@ -726,7 +714,7 @@ def legacy_page_data() -> Response:
|
||||||
if html := aqt.mw.mediaServer.get_page_html(id):
|
if html := aqt.mw.mediaServer.get_page_html(id):
|
||||||
return Response(html, mimetype="text/html")
|
return Response(html, mimetype="text/html")
|
||||||
else:
|
else:
|
||||||
return flask.make_response("page not found", HTTPStatus.NOT_FOUND)
|
return _text_response(HTTPStatus.NOT_FOUND, "page not found")
|
||||||
|
|
||||||
|
|
||||||
def _extract_page_context() -> PageContext:
|
def _extract_page_context() -> PageContext:
|
||||||
|
|
Loading…
Reference in a new issue