diff --git a/requirements.txt b/requirements.txt index d7a6bfb..49849ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ markdown jinja2 MarkupSafe bleach +web-mini diff --git a/src/aw/__init__.py b/src/aw/__init__.py index 9208d50..bf4727f 100644 --- a/src/aw/__init__.py +++ b/src/aw/__init__.py @@ -6,14 +6,28 @@ import datetime import os import sys from base64 import b64encode +from functools import lru_cache from typing import Any import flask +import web_mini from werkzeug.middleware.proxy_fix import ProxyFix from . import util +@lru_cache +def min_css(css: str) -> str: + """minify css""" + return web_mini.css.minify_css(css) + + +@lru_cache(maxsize=64) +def min_html(html: str) -> str: + """minify html""" + return web_mini.html.minify_html(html) + + def create_app(name: str) -> flask.Flask: """create ari.lt app""" @@ -65,7 +79,40 @@ def create_app(name: str) -> flask.Flask: c.init_app(app) - app.jinja_env.filters["markdown"] = util.markdown_to_html + app.jinja_env.filters["markdown"] = util.markdown_to_html # type: ignore + + web_mini.compileall() + + @app.after_request + def _(response: flask.Response) -> flask.Response: + """minify resources and add headers""" + + if not app.debug: + response.headers["Content-Security-Policy"] = "upgrade-insecure-requests" + response.headers["Strict-Transport-Security"] = ( + "max-age=63072000; includeSubDomains; preload" + ) + + response.headers["X-Frame-Options"] = "SAMEORIGIN" + response.headers["X-Content-Type-Options"] = "nosniff" + response.headers["X-Permitted-Cross-Domain-Policies"] = "none" + + if response.direct_passthrough: + return response + + if response.content_type == "text/html; charset=utf-8": + minified_data: str = min_html(response.get_data(as_text=True)) + elif response.content_type == "text/css; charset=utf-8": + minified_data: str = min_css(response.get_data(as_text=True)) + else: + return response + + return app.response_class( # type: ignore + response=minified_data, + status=response.status, + headers=dict(response.headers), + mimetype=response.mimetype, + ) @app.context_processor # type: ignore def _() -> Any: diff --git a/src/templates/base.j2 b/src/templates/base.j2 index de0596d..f8cba2b 100644 --- a/src/templates/base.j2 +++ b/src/templates/base.j2 @@ -1,57 +1,57 @@ -
- - - -- TL;DR; your email is stored and can be seen publicly. Please check your mailbox to confirm your email after commenting. + TL;DR; your email is stored and can be seen publicly. Please check your mailbox to confirm your email after commenting.
#{{ comment.id }}: {{ comment.name | escape }} {% if comment.website %} ({{ comment.website | escape }}) {% endif %} <show email> at says...
-#{{ comment.id }}: {{ comment.name | escape }} {% if comment.website %} ({{ comment.website | escape }}) {% endif %} <show email> at says...
+