diff options
| author | Paul Buetow <paul@buetow.org> | 2026-07-26 09:39:15 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-07-26 09:39:15 +0300 |
| commit | aaa786fcea8de25be1bd2eff8bc35afd1bc7482a (patch) | |
| tree | 23eecd8caa5f69425e4e6a4624dde36f49f100dc /frontends | |
| parent | 424a3cf07654a9a323cf8591c2ebf9ee177a3fdd (diff) | |
frontends: stop relayd clobbering cache headers for every f3s service
The three cache-control response rules were unscoped, so relayd rewrote every
response passing through the https relay -- not just the fallback pages the
comment described. Everything the k3s cluster serves was forced to
"no-cache, no-store, must-revalidate", overriding whatever the backend set.
cgit, for example, marks its CSS and logo "expires 30d", but browsers
re-fetched them on every page view.
relayd cannot filter a response by the backend table that produced it, and a
"header set" cannot be combined with a header match in the same rule. So match
the Server header -- the local httpd is the only backend answering
"OpenBSD httpd" -- and carry that across with a sticky tag.
Verified on blowfish before rollout with an isolated relayd instance: a
response from httpd:8080 gets the tagged headers, one from the cluster's nginx
does not. Fallback behaviour retested after deploy: c-git.f3s.buetow.org
served from httpd:8080 still returns the "Server turned off" page on any path,
with all three headers intact. cgit.css now passes through max-age=2592000.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'frontends')
| -rw-r--r-- | frontends/etc/relayd.conf.tpl | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/frontends/etc/relayd.conf.tpl b/frontends/etc/relayd.conf.tpl index b8d7a24..02b4887 100644 --- a/frontends/etc/relayd.conf.tpl +++ b/frontends/etc/relayd.conf.tpl @@ -122,10 +122,25 @@ http protocol "https" { match request header "Host" value "<%= $prefix.$host -%>" forward to <f3s_static_proxy> <% } } -%> - # Add cache-control headers to f3s fallback pages (served from localhost when cluster is down) - match response header set "Cache-Control" value "no-cache, no-store, must-revalidate" - match response header set "Pragma" value "no-cache" - match response header set "Expires" value "0" + # Keep the f3s fallback pages (served from localhost httpd when the cluster + # is down) out of browser caches, so nobody keeps seeing "cluster is down" + # after the cluster recovers. + # + # These rules used to be unscoped, so they rewrote EVERY response through + # this relay -- including everything the k3s cluster serves. That silently + # defeated upstream cache headers cluster-wide: cgit sets "expires 30d" on + # its CSS and logo, but browsers re-fetched them on every page view. + # + # relayd cannot filter a response by the backend table that produced it, so + # scope on the Server header instead: the local httpd is the only backend + # that answers "OpenBSD httpd" (the cluster answers nginx, the Pis + # bozohttpd). A "header set" cannot be combined with a header match in one + # rule, hence the tag: it is sticky for the connection, and a later + # response rule picks it up with "tagged". + match response header "Server" value "OpenBSD httpd" tag "HTTPD_FALLBACK" + match response tagged "HTTPD_FALLBACK" header set "Cache-Control" value "no-cache, no-store, must-revalidate" + match response tagged "HTTPD_FALLBACK" header set "Pragma" value "no-cache" + match response tagged "HTTPD_FALLBACK" header set "Expires" value "0" } relay "https4" { |
