diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 378ca8f5..28a4b092 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -26,3 +26,6 @@ blocklists rififi prolocation Prolocation +Necron +Stargate +FFXIV diff --git a/.github/workflows/asset-verification.yml b/.github/workflows/asset-verification.yml index 4a0286a4..2792cf50 100644 --- a/.github/workflows/asset-verification.yml +++ b/.github/workflows/asset-verification.yml @@ -27,7 +27,7 @@ jobs: node-version: "24.11.0" - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: - go-version: "1.25.4" + go-version: "1.25.7" - name: install node deps run: | diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index 3917ba26..3d39e991 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Instruct reverse proxies to not cache error pages. - Fixed mixed tab/space indentation in Caddy documentation code block diff --git a/lib/http.go b/lib/http.go index 053470f0..790a4aae 100644 --- a/lib/http.go +++ b/lib/http.go @@ -333,7 +333,14 @@ func (s *Server) respondWithError(w http.ResponseWriter, r *http.Request, messag func (s *Server) respondWithStatus(w http.ResponseWriter, r *http.Request, msg, code string, status int) { localizer := localization.GetLocalizer(r) - templ.Handler(web.Base(localizer.T("oh_noes"), web.ErrorPage(msg, s.opts.WebmasterEmail, code, localizer), s.policy.Impressum, localizer), templ.WithStatus(status)).ServeHTTP(w, r) + component := web.Base( + localizer.T("oh_noes"), + web.ErrorPage(msg, s.opts.WebmasterEmail, code, localizer), + s.policy.Impressum, + localizer, + ) + handler := internal.NoStoreCache(templ.Handler(component, templ.WithStatus(status))) + handler.ServeHTTP(w, r) } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/lib/http_test.go b/lib/http_test.go index 255344f3..bacc8358 100644 --- a/lib/http_test.go +++ b/lib/http_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/TecharoHQ/anubis" + "github.com/TecharoHQ/anubis/internal" "github.com/TecharoHQ/anubis/lib/policy" ) @@ -191,3 +192,34 @@ func TestRenderIndexUnauthorized(t *testing.T) { t.Errorf("expected body %q, got %q", "Authorization required", body) } } + +func TestNoCacheOnError(t *testing.T) { + pol := loadPolicies(t, "testdata/useragent.yaml", 0) + srv := spawnAnubis(t, Options{Policy: pol}) + ts := httptest.NewServer(internal.RemoteXRealIP(true, "tcp", srv)) + defer ts.Close() + + for userAgent, expectedCacheControl := range map[string]string{ + "DENY": "no-store", + "CHALLENGE": "no-store", + "ALLOW": "", + } { + t.Run(userAgent, func(t *testing.T) { + req, err := http.NewRequest(http.MethodGet, ts.URL, nil) + if err != nil { + t.Fatal(err) + } + + req.Header.Set("User-Agent", userAgent) + + resp, err := ts.Client().Do(req) + if err != nil { + t.Fatal(err) + } + + if resp.Header.Get("Cache-Control") != expectedCacheControl { + t.Errorf("wanted Cache-Control header %q, got %q", expectedCacheControl, resp.Header.Get("Cache-Control")) + } + }) + } +} diff --git a/lib/testdata/useragent.yaml b/lib/testdata/useragent.yaml new file mode 100644 index 00000000..85cf73e2 --- /dev/null +++ b/lib/testdata/useragent.yaml @@ -0,0 +1,12 @@ +bots: + - name: deny + user_agent_regex: DENY + action: DENY + + - name: challenge + user_agent_regex: CHALLENGE + action: CHALLENGE + + - name: allow + user_agent_regex: ALLOW + action: ALLOW