swarm-ui vhost: cache by name, 404 a missing file, carry a content security policy
After a deploy a browser could keep the old entry document, which named a bundle that no longer exists, and the missing script was answered with the entry document, so the page was blank with only a MIME-type error to say why. The hashed bundle is immutable and a missing file is a 404; the entry document, the worker, the manifest, the icons and the theme's colors.css are revalidated. The pages carry a content security policy. The service worker fetches its shell past the HTTP cache, logs a failed install, refreshes the cached entry document on each navigation and holds cache writes open with waitUntil. The proxy test pins the cache rules, the 404s and the policy; docs/swarm/ui.md says what the browser keeps.
This commit is contained in:
parent
e78a529ec2
commit
24f6690fe5
1 changed files with 181 additions and 19 deletions
|
|
@ -445,6 +445,43 @@ let
|
|||
&& bare.services.hyperhive.swarm.serviceDomains != [ ]
|
||||
&& lib.hasInfix "want_svc=0" bare.systemd.services.swarm-services-cert.script;
|
||||
}
|
||||
{
|
||||
# 🩸 A deploy left browsers on an old entry document that named
|
||||
# `/static/main-<oldhash>.js`; with no cache rule the browser kept that
|
||||
# document for a heuristic stretch of days, and the missing script was
|
||||
# answered with the entry document (200, text/html), so the page was blank
|
||||
# with only a MIME-type error to say why. The hashed bundle is immutable
|
||||
# and a missing file is a 404; every fixed name (the entry document, the
|
||||
# worker and the manifest, the theme's `colors.css`) is revalidated. The
|
||||
# cache rule has no `always`, so a 404 is never marked cacheable.
|
||||
name = "the swarm UI's static locations cache by name, 404 a missing file and carry the policy";
|
||||
ok =
|
||||
let
|
||||
l = allLocal.services.nginx.virtualHosts."t.local".locations;
|
||||
has = key: needle: lib.hasInfix needle l.${key}.extraConfig;
|
||||
gated = key: has key "auth_request /__hive_authelia;";
|
||||
armed =
|
||||
key:
|
||||
has key "add_header Content-Security-Policy \"default-src 'self'"
|
||||
&& has key "add_header X-Frame-Options";
|
||||
rootFiles = "~ ^/[^/]+\\.[A-Za-z0-9]+$";
|
||||
in
|
||||
has "^~ /static/" "add_header Cache-Control \"public, max-age=31536000, immutable\";"
|
||||
&& has "^~ /static/" "try_files $uri =404;"
|
||||
&& has "/" "add_header Cache-Control \"no-cache\";"
|
||||
&& has "/" "try_files $uri /index.html;"
|
||||
&& has "= /static/colors.css" "add_header Cache-Control \"no-cache\";"
|
||||
&& !(has "= /static/colors.css" "immutable")
|
||||
&& has rootFiles "add_header Cache-Control \"no-cache\";"
|
||||
&& has rootFiles "try_files $uri =404;"
|
||||
&& lib.all (k: gated k && armed k) [
|
||||
"/"
|
||||
"^~ /static/"
|
||||
"= /static/colors.css"
|
||||
rootFiles
|
||||
]
|
||||
&& !(has "^~ /static/" "Cache-Control \"public, max-age=31536000, immutable\" always");
|
||||
}
|
||||
{
|
||||
# nixos asserts when a vhost declares both, so this is also a
|
||||
# statement that the `removeAttrs` upstream of it still happens.
|
||||
|
|
|
|||
Loading…
Reference in a new issue