diff --git a/pkg/api/souin.go b/pkg/api/souin.go index 661706de6..15c40563e 100644 --- a/pkg/api/souin.go +++ b/pkg/api/souin.go @@ -143,6 +143,7 @@ func (s *SouinAPI) listKeys(search string) []string { var storageToInfiniteTTLMap = map[string]time.Duration{ "BADGER": types.OneYearDuration, "ETCD": types.OneYearDuration, + "GO-REDIS": 0, "NUTS": 0, "OLRIC": types.OneYearDuration, "OTTER": types.OneYearDuration, diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index 52e519233..14f3600fd 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -429,9 +429,9 @@ func (s *SouinBaseHandler) Upstream( } } - _, cacheControl := s.SurrogateKeyStorer.GetSurrogateControl(customWriter.Header()) + headerName, cacheControl := s.SurrogateKeyStorer.GetSurrogateControl(customWriter.Header()) if cacheControl == "" { - // customWriter.Header().Set(headerName, s.DefaultMatchedUrl.DefaultCacheControl) + customWriter.Header().Set(headerName, s.DefaultMatchedUrl.DefaultCacheControl) } err := s.Store(customWriter, rq, requestCc, cachedKey) diff --git a/plugins/beego/souin_test.go b/plugins/beego/souin_test.go index 4b25ed1dd..5ada1ae60 100644 --- a/plugins/beego/souin_test.go +++ b/plugins/beego/souin_test.go @@ -57,7 +57,7 @@ func Test_SouinBeegoPlugin_Middleware(t *testing.T) { req.Header = http.Header{} web.BeeApp.Handlers.ServeHTTP(res, req) - if res.Result().Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-example.com-/handled; detail=DEFAULT" { + if res.Result().Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-example.com-/handled" { t.Error("The response must contain a Cache-Status header with the stored directive.") } diff --git a/plugins/gin/souin_test.go b/plugins/gin/souin_test.go index adf3771d7..4a5cea854 100644 --- a/plugins/gin/souin_test.go +++ b/plugins/gin/souin_test.go @@ -51,7 +51,7 @@ func Test_SouinGinPlugin_Process(t *testing.T) { } r.ServeHTTP(res2, c.Request) - if res2.Result().Header.Get("Cache-Status") != "Souin; hit; ttl=4; key=GET-http-example.com-/handled; detail=DEFAULTh" { + if res2.Result().Header.Get("Cache-Status") != "Souin; hit; ttl=4; key=GET-http-example.com-/handled; detail=DEFAULT" { t.Error("The response must contain a Cache-Status header with the hit and ttl directives.") } if res2.Result().Header.Get("Age") != "1" { diff --git a/plugins/traefik/override/middleware/middleware.go b/plugins/traefik/override/middleware/middleware.go index 2fe9f0551..753089f18 100644 --- a/plugins/traefik/override/middleware/middleware.go +++ b/plugins/traefik/override/middleware/middleware.go @@ -411,7 +411,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n if response != nil && (!modeContext.Strict || rfc.ValidateCacheControl(response, requestCc)) { if validator.ResponseETag != "" && validator.Matched { - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") customWriter.Headers = response.Header if validator.NotModified { customWriter.statusCode = http.StatusNotModified @@ -440,7 +440,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n return err } - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") if !modeContext.Strict || rfc.ValidateMaxAgeCachedResponse(requestCc, response) != nil { customWriter.Headers = response.Header customWriter.statusCode = response.StatusCode @@ -458,7 +458,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n } if nil != response && (!modeContext.Strict || rfc.ValidateCacheControl(response, requestCc)) { addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") responseCc, _ := cacheobject.ParseResponseCacheControl(response.Header.Get("Cache-Control")) if responseCc.StaleWhileRevalidate > 0 { @@ -502,7 +502,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n if customWriter.statusCode == http.StatusNotModified { if !validator.Matched { - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") customWriter.statusCode = response.StatusCode customWriter.Headers = response.Header _, _ = io.Copy(customWriter.Buf, response.Body) diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go index 2fe9f0551..753089f18 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/middleware/middleware.go @@ -411,7 +411,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n if response != nil && (!modeContext.Strict || rfc.ValidateCacheControl(response, requestCc)) { if validator.ResponseETag != "" && validator.Matched { - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") customWriter.Headers = response.Header if validator.NotModified { customWriter.statusCode = http.StatusNotModified @@ -440,7 +440,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n return err } - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") if !modeContext.Strict || rfc.ValidateMaxAgeCachedResponse(requestCc, response) != nil { customWriter.Headers = response.Header customWriter.statusCode = response.StatusCode @@ -458,7 +458,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n } if nil != response && (!modeContext.Strict || rfc.ValidateCacheControl(response, requestCc)) { addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") responseCc, _ := cacheobject.ParseResponseCacheControl(response.Header.Get("Cache-Control")) if responseCc.StaleWhileRevalidate > 0 { @@ -502,7 +502,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n if customWriter.statusCode == http.StatusNotModified { if !validator.Matched { - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, "DEFAULT") customWriter.statusCode = response.StatusCode customWriter.Headers = response.Header _, _ = io.Copy(customWriter.Buf, response.Body) diff --git a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/cache_status.go b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/cache_status.go index 3d5a61b48..f02132fb7 100644 --- a/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/cache_status.go +++ b/plugins/traefik/vendor/github.com/darkweak/souin/pkg/rfc/cache_status.go @@ -80,7 +80,7 @@ func HitStaleCache(h *http.Header) { h.Set("Cache-Status", h.Get("Cache-Status")+"; fwd=stale") } -func manageAge(h *http.Header, ttl time.Duration, cacheName, key string) { +func manageAge(h *http.Header, ttl time.Duration, cacheName, key, storerName string) { utc1 := time.Now().UTC() dh := h.Get("Date") if dh == "" { @@ -119,7 +119,7 @@ func manageAge(h *http.Header, ttl time.Duration, cacheName, key string) { age := strconv.Itoa(oldAge + cage) h.Set("Age", age) ttlValue := strconv.Itoa(int(ttl.Seconds()) - cage) - h.Set("Cache-Status", cacheName+"; hit; ttl="+ttlValue+"; key="+key) + h.Set("Cache-Status", cacheName+"; hit; ttl="+ttlValue+"; key="+key+"; detail="+storerName) } func setMalformedHeader(headers *http.Header, header, cacheName string) { @@ -127,11 +127,11 @@ func setMalformedHeader(headers *http.Header, header, cacheName string) { } // SetCacheStatusHeader set the Cache-Status header -func SetCacheStatusHeader(resp *http.Response) *http.Response { +func SetCacheStatusHeader(resp *http.Response, storerName string) *http.Response { h := resp.Header cacheName := resp.Request.Context().Value(context.CacheName).(string) validateEmptyHeaders(&h, cacheName) - manageAge(&h, 0, cacheName, GetCacheKeyFromCtx(resp.Request.Context())) + manageAge(&h, 0, cacheName, GetCacheKeyFromCtx(resp.Request.Context()), storerName) resp.Header = h return resp diff --git a/plugins/tyk/main.go b/plugins/tyk/main.go index d24beb9a6..acc06f6df 100644 --- a/plugins/tyk/main.go +++ b/plugins/tyk/main.go @@ -190,6 +190,7 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { defer s.bufPool.Put(bufPool) if !requestCc.NoCache { validator := rfc.ParseRequest(rq) + var storerName string var fresh, stale *http.Response finalKey := cachedKey if rq.Context().Value(context.Hashed).(bool) { @@ -199,6 +200,7 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { fresh, stale = currentStorer.GetMultiLevel(finalKey, rq, validator) if fresh != nil || stale != nil { + storerName = currentStorer.Name() fmt.Printf("Found at least one valid response in the %s storage\n", currentStorer.Name()) break } @@ -206,7 +208,7 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { if fresh != nil && (!modeContext.Strict || rfc.ValidateCacheControl(fresh, requestCc)) { response := fresh - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, storerName) if rfc.ValidateMaxAgeCachedResponse(requestCc, response) != nil { for hn, hv := range response.Header { rw.Header().Set(hn, strings.Join(hv, ", ")) @@ -220,7 +222,7 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { if nil != response && rfc.ValidateCacheControl(response, requestCc) { addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, storerName) responseCc, _ := cacheobject.ParseResponseCacheControl(response.Header.Get("Cache-Control")) if responseCc.StaleIfError > 0 { diff --git a/plugins/tyk/override/middleware/middleware.go b/plugins/tyk/override/middleware/middleware.go index 3fc69a742..6c69021f2 100644 --- a/plugins/tyk/override/middleware/middleware.go +++ b/plugins/tyk/override/middleware/middleware.go @@ -272,6 +272,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, baseRq *http.Reques customWriter := NewCustomWriter(rq, rw, bufPool) if !requestCc.NoCache { validator := rfc.ParseRequest(rq) + var storerName string var response *http.Response var fresh, stale *http.Response finalKey := cachedKey @@ -279,6 +280,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, baseRq *http.Reques finalKey = fmt.Sprint(xxhash.Sum64String(finalKey)) } for _, currentStorer := range s.Storers { + storerName = currentStorer.Name() fresh, stale = currentStorer.GetMultiLevel(finalKey, rq, validator) if fresh != nil || stale != nil { @@ -289,7 +291,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, baseRq *http.Reques if rfc.ValidateCacheControl(response, requestCc) { response := fresh - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, storerName) if rfc.ValidateMaxAgeCachedResponse(requestCc, response) != nil { customWriter.Headers = response.Header customWriter.statusCode = response.StatusCode @@ -303,7 +305,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, baseRq *http.Reques if nil != response && rfc.ValidateCacheControl(response, requestCc) { addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) - rfc.SetCacheStatusHeader(response) + rfc.SetCacheStatusHeader(response, storerName) responseCc, _ := cacheobject.ParseResponseCacheControl(response.Header.Get("Cache-Control")) if responseCc.StaleWhileRevalidate > 0 {