Make maubot http server serve frontend for production

This commit is contained in:
Tulir Asokan 2018-11-11 00:43:58 +02:00
parent 0264f7b794
commit e0306d29b5
7 changed files with 64 additions and 10 deletions

View file

@ -18,6 +18,7 @@ import asyncio
from aiohttp import web
from aiohttp.abc import AbstractAccessLogger
import pkg_resources
from mautrix.api import PathBuilder, Method
@ -35,21 +36,56 @@ class AccessLogger(AbstractAccessLogger):
class MaubotServer:
log: logging.Logger = logging.getLogger("maubot.server")
def __init__(self, config: Config, management: web.Application,
loop: asyncio.AbstractEventLoop) -> None:
def __init__(self, config: Config, loop: asyncio.AbstractEventLoop) -> None:
self.loop = loop or asyncio.get_event_loop()
self.app = web.Application(loop=self.loop)
self.config = config
path = PathBuilder(config["server.base_path"])
self.add_route(Method.GET, path.version, self.version)
self.app.add_subapp(config["server.base_path"], management)
as_path = PathBuilder(config["server.appservice_base_path"])
self.add_route(Method.PUT, as_path.transactions, self.handle_transaction)
self.setup_management_ui()
self.runner = web.AppRunner(self.app, access_log_class=AccessLogger)
def setup_management_ui(self) -> None:
ui_base = self.config["server.ui_base_path"]
if ui_base == "/":
ui_base = ""
directory = (self.config["server.override_resource_path"]
or pkg_resources.resource_filename("maubot", "management/frontend/build"))
self.app.router.add_static(f"{ui_base}/static", f"{directory}/static")
self.setup_static_root_files(directory, ui_base)
with open(f"{directory}/index.html", "r") as file:
index_html = file.read()
@web.middleware
async def frontend_404_middleware(request, handler):
if hasattr(handler, "__self__") and isinstance(handler.__self__, web.StaticResource):
try:
return await handler(request)
except web.HTTPNotFound:
return web.Response(body=index_html, content_type="text/html")
return await handler(request)
self.app.middlewares.append(frontend_404_middleware)
self.app.router.add_get(f"{ui_base}/", lambda _: web.Response(body=index_html,
content_type="text/html"))
self.app.router.add_get(ui_base, lambda _: web.HTTPFound(f"{ui_base}/"))
def setup_static_root_files(self, directory: str, ui_base: str) -> None:
files = {
"asset-manifest.json": "application/json",
"manifest.json": "application/json",
"favicon.png": "image/png",
}
for file, mime in files.items():
with open(f"{directory}/{file}", "rb") as stream:
data = stream.read()
self.app.router.add_get(f"{ui_base}/{file}", lambda _: web.Response(body=data,
content_type=mime))
def add_route(self, method: Method, path: PathBuilder, handler) -> None:
self.app.router.add_route(method.value, str(path), handler)