diff options
author | Wojtek Kosior <koszko@koszko.org> | 2022-08-12 14:33:15 +0200 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2022-08-12 14:33:15 +0200 |
commit | 2c98d04e4d4a344dc04a481b039a235678f7848e (patch) | |
tree | 292b858fa07613c3c455961f17adf33e64db92e8 /src/hydrilla/proxy/web_ui/root.py | |
parent | 3d025bfb796d3028282bc806d557b8289a42062b (diff) | |
download | haketilo-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.py | 71 |
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 + ) |