gabriel / musehub public
static_cache.py python
71 lines 3.1 KB
Raw
sha256:73f24973678ceefd56628ee17c6d0535d86e33533828af6c63348f50941515ad Merge branch 'fix/smoke-test-tag-label' into dev Human 16 days ago
1 """Static asset Cache-Control middleware.
2
3 Injects ``Cache-Control`` headers on ``/static/`` and ``/releases/`` responses:
4
5 - ``/static/*.css``, ``/static/*.js``, ``/static/*.map`` — far-future 1-year
6 immutable (paired with ``?v=<hash8>`` query strings in ``base.html``).
7 - Other ``/static/`` paths — 1-day TTL (un-versioned assets like favicons).
8 - ``/releases/*.tar.gz`` — 1-hour TTL for sdist tarballs; short enough for
9 republishing, long enough to reduce origin load during install waves.
10 - Any non-2xx response on ``/releases/`` — ``no-store`` so Cloudflare never
11 caches 404s (which would break installs if a tarball is added after first
12 access).
13 """
14
15 from starlette.types import ASGIApp, Message, Receive, Scope, Send
16
17 _FAR_FUTURE = "public, max-age=31536000, immutable"
18 _ONE_DAY = "public, max-age=86400"
19 _ONE_HOUR = "public, max-age=3600"
20 _NO_STORE = "no-store"
21
22 # Extensions that always carry a ?v= query string in base.html.
23 # All other /static/ paths get the shorter 1-day TTL.
24 _VERSIONED_EXTS = frozenset([".css", ".js", ".map"])
25
26 class StaticCacheMiddleware:
27 """Pure ASGI middleware — zero overhead for non-static requests."""
28
29 def __init__(self, app: ASGIApp) -> None:
30 self._app = app
31
32 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
33 if scope["type"] != "http":
34 await self._app(scope, receive, send)
35 return
36
37 path: str = scope.get("path", "")
38
39 if path.startswith("/static/"):
40 ext = path.rsplit(".", 1)[-1].lower() if "." in path else ""
41 cache_value = _FAR_FUTURE if f".{ext}" in _VERSIONED_EXTS else _ONE_DAY
42 cache_bytes = cache_value.encode()
43
44 async def _send_static(message: Message) -> None:
45 if message["type"] == "http.response.start":
46 headers: list[tuple[bytes, bytes]] = list(message.get("headers", []))
47 if not any(k.lower() == b"cache-control" for k, _ in headers):
48 headers.append((b"cache-control", cache_bytes))
49 message = {**message, "headers": headers}
50 await send(message)
51
52 await self._app(scope, receive, _send_static)
53 return
54
55 if path.startswith("/releases/"):
56 async def _send_releases(message: Message) -> None:
57 if message["type"] == "http.response.start":
58 headers = list(message.get("headers", []))
59 if not any(k.lower() == b"cache-control" for k, _ in headers):
60 # Non-2xx (e.g. 404) must not be cached — prevents edge
61 # caches from locking out a tarball that is added later.
62 status: int = message.get("status", 200)
63 cc = _ONE_HOUR if 200 <= status < 300 else _NO_STORE
64 headers.append((b"cache-control", cc.encode()))
65 message = {**message, "headers": headers}
66 await send(message)
67
68 await self._app(scope, receive, _send_releases)
69 return
70
71 await self._app(scope, receive, send)
File History 12 commits
sha256:73f24973678ceefd56628ee17c6d0535d86e33533828af6c63348f50941515ad Merge branch 'fix/smoke-test-tag-label' into dev Human 16 days ago
sha256:d035733f21ccff27735fddebfbbe0ed24565a32a22db8de5885402262671ecd2 chore: bump version to 0.2.0rc15 for musehub#113 fix release Sonnet 4.6 patch 16 days ago
sha256:0032d6cfa33bc3c8367436ad768e7dd0e339b4332153160247da8266cb5fa352 Merge branch 'task/version-tags-phase3-server' into dev Human 18 days ago
sha256:4669620efda9ff41c55bdefd1f7bfe1c239d468428744c84ead9957e5a003a53 merge: rescue snapshot-recovery hardening (c00aa21d) into d… Opus 4.8 minor 31 days ago
sha256:a59da49c4611b970fc4b6ae48678ce4943261c213a07ddbd73ce9201df869b4a fix: remove false-positive proposal_comments index drop fro… Sonnet 4.6 patch 35 days ago
sha256:0a240d6dbff234f07d98a28a4a9a68db702f3f9ff9260196f24219bdb1c0b6f3 feat: render markdown mists as HTML with heading anchor links Sonnet 4.6 patch 35 days ago
sha256:24a7d47486ebc4ebd1832830580e177ec6f877b48dced8c000e198cdec4ce9d6 Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 37 days ago
sha256:b9ff931d147e0114a1f17060f415b89ed551c170a91ff226c70437aa5c85f9ee Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 37 days ago
sha256:d1122d21e73471879b460037b22c0b50fded7c423444a176f248428f75dac39c Merge 'task/fix-issue-pagination-cursor' into 'dev' — propo… Human 37 days ago
sha256:01e18975e73d2b3cd5b6db7929c895bef9aa6e0d4391dc5b2adfc548b41318dd Merge 'feat/adding-debug-logs-to-staging' into 'dev' — prop… Human 37 days ago
sha256:6b1949fc2797ca4c1936a637a4cbfec828ef56cf52398a2e74ca3c4f494e728f fix: use wire_bytes not mpack_bytes_raw in compute_object_b… Sonnet 4.6 patch 49 days ago
sha256:b99f2455dc346966d040133f5203297e6e3ef5803a93728a2c30568d0a0f7583 rename: delta_add → delta_upsert across wire format, models… Sonnet 4.6 patch 51 days ago