aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/web_ui/root.py
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-08-12 14:33:15 +0200
committerWojtek Kosior <koszko@koszko.org>2022-08-12 14:33:15 +0200
commit2c98d04e4d4a344dc04a481b039a235678f7848e (patch)
tree292b858fa07613c3c455961f17adf33e64db92e8 /src/hydrilla/proxy/web_ui/root.py
parent3d025bfb796d3028282bc806d557b8289a42062b (diff)
downloadhaketilo-hydrilla-2c98d04e4d4a344dc04a481b039a235678f7848e.tar.gz
haketilo-hydrilla-2c98d04e4d4a344dc04a481b039a235678f7848e.zip
make Haketilo proxy web UI in terms of a Flask app
Diffstat (limited to 'src/hydrilla/proxy/web_ui/root.py')
-rw-r--r--src/hydrilla/proxy/web_ui/root.py71
1 files changed, 55 insertions, 16 deletions
diff --git a/src/hydrilla/proxy/web_ui/root.py b/src/hydrilla/proxy/web_ui/root.py
index dbb86c1..194251e 100644
--- a/src/hydrilla/proxy/web_ui/root.py
+++ b/src/hydrilla/proxy/web_ui/root.py
@@ -32,35 +32,74 @@
from __future__ import annotations
import typing as t
+from threading import Lock
+
+import jinja2
+import flask
from ...translations import smart_gettext as _
from .. import state as st
from .. import http_messages
from . import repos
+from . import packages
+
+
+class WebUIApp(flask.Flask):
+ def __init__(self):
+ super().__init__(__name__)
+
+ self.jinja_options = {
+ **self.jinja_options,
+ 'loader': jinja2.PackageLoader(__package__),
+ 'autoescape': jinja2.select_autoescape()
+ }
+ for blueprint in [repos.bp, packages.bp]:
+ self.register_blueprint(blueprint)
-HandlerType = t.Callable[
- [http_messages.RequestInfo, t.Sequence[str], st.HaketiloState],
- http_messages.ProducedResponse
-]
+ _haketilo_state: st.HaketiloState
-request_handlers: t.Mapping[str, HandlerType] = {
- 'repos': repos.respond
-}
+# Flask app is not thread-safe and has to be accompanied by an ugly lock. This
+# can cause slow requests to block other requests, so we might need a better
+# workaround at some later point.
+app = WebUIApp()
+app_lock = Lock()
-def respond(
+
+@app.route('/')
+def respond():
+ return flask.render_template('root.html.jinja')
+
+
+def process_request(
request_info: http_messages.RequestInfo,
state: st.HaketiloState
) -> http_messages.ProducedResponse:
- if request_info.url.path_segments == ():
- raise NotImplementedError()
+ path = '/'.join(('', *request_info.url.path_segments))
+ if (request_info.url.has_trailing_slash):
+ path += '/'
+
+ with app_lock:
+ app._haketilo_state = state
- resource, *rest_of_path = request_info.url.path_segments
+ flask_response = app.test_client().open(
+ path = path,
+ base_url = 'https://hkt.mitm.it',
+ method = request_info.method,
+ query_string = request_info.url.query,
+ headers = [*request_info.headers.items()],
+ data = request_info.body
+ )
- try:
- handler = request_handlers[resource]
- except KeyError:
- raise NotImplementedError()
+ headers_bytes = [
+ (key.encode(), val.encode())
+ for key, val
+ in flask_response.headers
+ ]
- return handler(request_info, rest_of_path, state)
+ return http_messages.ProducedResponse(
+ status_code = flask_response.status_code,
+ headers = headers_bytes,
+ body = flask_response.data
+ )