From f488d661d74d860aeb12339cdfc9391516fa3069 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Fri, 15 Mar 2024 21:15:54 -0400 Subject: [PATCH] load static files into memory when not in dev mode --- relay/application.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/relay/application.py b/relay/application.py index 58668a8..3560573 100644 --- a/relay/application.py +++ b/relay/application.py @@ -8,9 +8,12 @@ import traceback import typing from aiohttp import web +from aiohttp.web import StaticResource from aiohttp_swagger import setup_swagger from aputils.signer import Signer from datetime import datetime, timedelta +from mimetypes import guess_type +from pathlib import Path from queue import Empty from threading import Event, Thread @@ -68,7 +71,13 @@ class Application(web.Application): for path, view in VIEWS: self.router.add_view(path, view) - self.add_routes([web.static('/static', get_resource('frontend/static'))]) + if dev: + static = StaticResource('/static', get_resource('frontend/static')) + + else: + static = CachedStaticResource('/static', get_resource('frontend/static')) + + self.router.register_resource(static) setup_swagger( self, @@ -223,6 +232,39 @@ class Application(web.Application): self['cache'].close() +class CachedStaticResource(StaticResource): + def __init__(self, prefix: str, path: Path): + StaticResource.__init__(self, prefix, path) + + self.cache: dict[Path, bytes] = {} + + for filename in path.rglob('*'): + if filename.is_dir(): + continue + + rel_path = str(filename.relative_to(path)) + + with filename.open('rb') as fd: + logging.debug('Loading static resource "%s"', rel_path) + self.cache[rel_path] = fd.read() + + + async def _handle(self, request: web.Request) -> web.StreamResponse: + rel_url = request.match_info['filename'] + + if Path(rel_url).anchor: + raise web.HTTPForbidden() + + try: + return web.Response( + body = self.cache[rel_url], + content_type = guess_type(path)[0] + ) + + except KeyError: + raise web.HTTPNotFound() + + class CacheCleanupThread(Thread): def __init__(self, app: Application): Thread.__init__(self)