From 00c4b70a9122d5ebb167493937e89641993d4707 Mon Sep 17 00:00:00 2001 From: darkweak Date: Sun, 22 Dec 2024 18:11:18 +0100 Subject: [PATCH] fix(multiple): december 2024 wave #584 --- pkg/middleware/middleware.go | 4 +-- plugins/caddy/httpcache_test.go | 59 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index 18302bfaa..c46c9e9bd 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -922,10 +922,10 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n case <-req.Context().Done(): switch req.Context().Err() { case baseCtx.DeadlineExceeded: - customWriter.WriteHeader(http.StatusGatewayTimeout) - s.Configuration.GetLogger().Infof("Internal server error on endpoint %s: %v", req.URL, s.Storers) rw.Header().Set("Cache-Status", cacheName+"; fwd=bypass; detail=DEADLINE-EXCEEDED") + customWriter.Rw.WriteHeader(http.StatusGatewayTimeout) _, _ = customWriter.Rw.Write([]byte("Internal server error")) + s.Configuration.GetLogger().Infof("Internal server error on endpoint %s: %v", req.URL, s.Storers) return baseCtx.DeadlineExceeded case baseCtx.Canceled: return baseCtx.Canceled diff --git a/plugins/caddy/httpcache_test.go b/plugins/caddy/httpcache_test.go index 2b4270997..419f43652 100644 --- a/plugins/caddy/httpcache_test.go +++ b/plugins/caddy/httpcache_test.go @@ -1281,3 +1281,62 @@ func TestAllowedAdditionalStatusCode(t *testing.T) { t.Error("Age header should be present") } } + +type testTimeoutHandler struct { + iterator int +} + +func (t *testTimeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + t.iterator++ + if t.iterator%2 == 0 { + time.Sleep(5 * time.Second) + + return + } + + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("Hello timeout!")) +} + +func TestTimeout(t *testing.T) { + tester := caddytest.NewTester(t) + tester.InitServer(` + { + admin localhost:2999 + http_port 9080 + cache { + ttl 1ns + stale 1ns + timeout { + backend 1s + } + } + } + localhost:9080 { + route /cache-timeout { + cache + reverse_proxy localhost:9086 + } + }`, "caddyfile") + + go func() { + errorHandler := testTimeoutHandler{} + _ = http.ListenAndServe(":9086", &errorHandler) + }() + time.Sleep(time.Second) + resp1, _ := tester.AssertGetResponse(`http://localhost:9080/cache-timeout`, http.StatusOK, "Hello timeout!") + time.Sleep(time.Millisecond) + resp2, _ := tester.AssertGetResponse(`http://localhost:9080/cache-timeout`, http.StatusGatewayTimeout, "Internal server error") + + if resp1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/cache-timeout" { + t.Errorf("unexpected resp1 Cache-Status header %v", resp1.Header.Get("Cache-Status")) + } + + if resp1.Header.Get("Age") != "" { + t.Errorf("unexpected resp1 Age header %v", resp1.Header.Get("Age")) + } + + if resp2.Header.Get("Cache-Status") != "Souin; fwd=bypass; detail=DEADLINE-EXCEEDED" { + t.Errorf("unexpected resp2 Cache-Status header %v", resp2.Header.Get("Cache-Status")) + } +}