From 1ad103b6dcd7d07a7015292533375d73af2d7868 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sun, 17 May 2026 12:59:41 +0300 Subject: [PATCH] Use immutable cache for HTML5 assets --- .../api-server/src/api_server/html5_responses.py | 2 +- services/api-server/tests/test_api.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/services/api-server/src/api_server/html5_responses.py b/services/api-server/src/api_server/html5_responses.py index 019929c..e0ebf18 100644 --- a/services/api-server/src/api_server/html5_responses.py +++ b/services/api-server/src/api_server/html5_responses.py @@ -20,7 +20,7 @@ HTML5_CONTENT_SECURITY_POLICY = ( class Html5StaticFiles(StaticFiles): def file_response(self, *args, **kwargs): response = super().file_response(*args, **kwargs) - response.headers.setdefault("Cache-Control", "public, max-age=86400") + response.headers.setdefault("Cache-Control", "public, max-age=31536000, immutable") response.headers.setdefault("X-Content-Type-Options", "nosniff") return response diff --git a/services/api-server/tests/test_api.py b/services/api-server/tests/test_api.py index e3ecf6a..85fedd4 100644 --- a/services/api-server/tests/test_api.py +++ b/services/api-server/tests/test_api.py @@ -396,20 +396,26 @@ def test_html5_server_rendered_project_editor(tmp_path: Path): htmx_asset = client.get("/html5/assets/htmx.min.js") assert htmx_asset.status_code == 200 assert "javascript" in htmx_asset.headers["content-type"] - assert htmx_asset.headers["cache-control"] == "public, max-age=86400" + assert htmx_asset.headers["cache-control"] == "public, max-age=31536000, immutable" assert htmx_asset.headers["x-content-type-options"] == "nosniff" assert "htmx" in htmx_asset.text sse_asset = client.get("/html5/assets/htmx-ext-sse.js") assert sse_asset.status_code == 200 assert "javascript" in sse_asset.headers["content-type"] - assert sse_asset.headers["cache-control"] == "public, max-age=86400" + assert sse_asset.headers["cache-control"] == "public, max-age=31536000, immutable" assert sse_asset.headers["x-content-type-options"] == "nosniff" assert "sse" in sse_asset.text css_asset = client.get("/html5/assets/html5.css") assert css_asset.status_code == 200 assert "text/css" in css_asset.headers["content-type"] - assert css_asset.headers["cache-control"] == "public, max-age=86400" + assert css_asset.headers["cache-control"] == "public, max-age=31536000, immutable" assert css_asset.headers["x-content-type-options"] == "nosniff" + assert css_asset.headers["etag"] + cached_css_asset = client.get("/html5/assets/html5.css", headers={"If-None-Match": css_asset.headers["etag"]}) + assert cached_css_asset.status_code == 304 + assert cached_css_asset.headers["cache-control"] == "public, max-age=31536000, immutable" + assert cached_css_asset.headers["x-content-type-options"] == "nosniff" + assert cached_css_asset.content == b"" assert ".workspace" in css_asset.text