fix: send Cache-Control so a stale Nix mtime can't pin visitors to old JS
This commit is contained in:
parent
a24c143fd0
commit
a3378def50
1 changed files with 12 additions and 2 deletions
14
bridge.py
14
bridge.py
|
|
@ -96,8 +96,17 @@ async def relay(request: web.Request) -> web.WebSocketResponse:
|
||||||
# The client loads no inline script, no inline style and no foreign origin, so a
|
# The client loads no inline script, no inline style and no foreign origin, so a
|
||||||
# strict policy costs nothing. form-action stays 'self' rather than 'none' so the
|
# strict policy costs nothing. form-action stays 'self' rather than 'none' so the
|
||||||
# compose dialog's method="dialog" form is untouched.
|
# compose dialog's method="dialog" form is untouched.
|
||||||
|
#
|
||||||
|
# Nix normalizes every built file's mtime to the same fixed epoch for
|
||||||
|
# reproducibility, so Last-Modified is identical across every deploy — with no
|
||||||
|
# explicit Cache-Control, a browser's heuristic freshness calculation (based on
|
||||||
|
# that ~56-year-old timestamp) can treat a page as fresh indefinitely and never
|
||||||
|
# revalidate again, silently pinning a visitor to whatever JS they first
|
||||||
|
# loaded across every future deploy. no-cache forces a conditional GET each
|
||||||
|
# time rather than disabling caching outright — the ETag aiohttp already sends
|
||||||
|
# still turns an unchanged file into a bodyless 304.
|
||||||
@web.middleware
|
@web.middleware
|
||||||
async def csp(request: web.Request, handler):
|
async def headers(request: web.Request, handler):
|
||||||
response = await handler(request)
|
response = await handler(request)
|
||||||
response.headers.setdefault("Content-Security-Policy", "; ".join([
|
response.headers.setdefault("Content-Security-Policy", "; ".join([
|
||||||
"default-src 'self'",
|
"default-src 'self'",
|
||||||
|
|
@ -107,6 +116,7 @@ async def csp(request: web.Request, handler):
|
||||||
"object-src 'none'",
|
"object-src 'none'",
|
||||||
"frame-ancestors 'none'",
|
"frame-ancestors 'none'",
|
||||||
]))
|
]))
|
||||||
|
response.headers.setdefault("Cache-Control", "no-cache")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -128,7 +138,7 @@ def main() -> int:
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
|
||||||
app = web.Application(middlewares=[csp])
|
app = web.Application(middlewares=[headers])
|
||||||
app["web_dir"], app["relay_ports"] = args.dir, set(args.allow_ports)
|
app["web_dir"], app["relay_ports"] = args.dir, set(args.allow_ports)
|
||||||
app["allow_origins"] = set(args.allow_origins)
|
app["allow_origins"] = set(args.allow_origins)
|
||||||
app.router.add_get("/", index)
|
app.router.add_get("/", index)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue