diff --git a/pkg/api/souin.go b/pkg/api/souin.go index 2c32eddea..4d415a4d3 100644 --- a/pkg/api/souin.go +++ b/pkg/api/souin.go @@ -152,6 +152,7 @@ func (s *SouinAPI) purgeMapping() { var mapping types.StorageMapper e := gob.NewDecoder(bytes.NewBuffer([]byte(v))).Decode(&mapping) if e != nil { + current.Delete(storage.MappingKeyPrefix + k) continue } diff --git a/plugins/tyk/go.mod b/plugins/tyk/go.mod index 9b528bb86..a86e69441 100644 --- a/plugins/tyk/go.mod +++ b/plugins/tyk/go.mod @@ -6,7 +6,7 @@ toolchain go1.21.0 require ( github.com/TykTechnologies/tyk v1.9.2-0.20230330071232-370295d796b5 - github.com/cespare/xxhash v1.1.0 + github.com/cespare/xxhash/v2 v2.2.0 github.com/darkweak/souin v1.6.47 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pierrec/lz4/v4 v4.1.21 @@ -32,7 +32,7 @@ require ( github.com/buraksezer/consistent v0.10.0 // indirect github.com/buraksezer/olric v0.5.4 // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/clbanning/mxj v1.8.4 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect diff --git a/plugins/tyk/main.go b/plugins/tyk/main.go index 27c78568b..d24beb9a6 100644 --- a/plugins/tyk/main.go +++ b/plugins/tyk/main.go @@ -11,11 +11,10 @@ import ( "time" "github.com/TykTechnologies/tyk/ctx" - "github.com/cespare/xxhash" + "github.com/cespare/xxhash/v2" "github.com/darkweak/souin/context" "github.com/darkweak/souin/pkg/middleware" "github.com/darkweak/souin/pkg/rfc" - "github.com/darkweak/souin/pkg/storage" "github.com/darkweak/souin/pkg/storage/types" "github.com/pquerna/cachecontrol/cacheobject" ) @@ -176,6 +175,7 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { requestCc, coErr := cacheobject.ParseRequestCacheControl(rq.Header.Get("Cache-Control")) + modeContext := rq.Context().Value(context.Mode).(*context.ModeContext) if coErr != nil || requestCc == nil { rw.Header().Set("Cache-Status", cacheName+"; fwd=bypass; detail=CACHE-CONTROL-EXTRACTION-ERROR") @@ -199,12 +199,13 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { fresh, stale = currentStorer.GetMultiLevel(finalKey, rq, validator) if fresh != nil || stale != nil { - s.Configuration.GetLogger().Sugar().Debugf("Found at least one valid response in the %s storage", currentStorer.Name()) + fmt.Printf("Found at least one valid response in the %s storage\n", currentStorer.Name()) break } } - if response != nil && rfc.ValidateCacheControl(response, requestCc) { + if fresh != nil && (!modeContext.Strict || rfc.ValidateCacheControl(fresh, requestCc)) { + response := fresh rfc.SetCacheStatusHeader(response) if rfc.ValidateMaxAgeCachedResponse(requestCc, response) != nil { for hn, hv := range response.Header { @@ -214,13 +215,9 @@ func SouinRequestHandler(rw http.ResponseWriter, baseRq *http.Request) { return } - } else if response == nil && (requestCc.MaxStaleSet || requestCc.MaxStale > -1) { - for _, currentStorer := range s.SouinBaseHandler.Storers { - response = currentStorer.Prefix(storage.StalePrefix+cachedKey, rq, validator) - if response != nil { - break - } - } + } else if !requestCc.OnlyIfCached && (requestCc.MaxStaleSet || requestCc.MaxStale > -1) { + response := stale + if nil != response && rfc.ValidateCacheControl(response, requestCc) { addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) rfc.SetCacheStatusHeader(response) diff --git a/plugins/tyk/override/middleware/middleware.go b/plugins/tyk/override/middleware/middleware.go index ff68a8f6d..3fc69a742 100644 --- a/plugins/tyk/override/middleware/middleware.go +++ b/plugins/tyk/override/middleware/middleware.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/cespare/xxhash/v2" "github.com/darkweak/souin/configurationtypes" "github.com/darkweak/souin/context" "github.com/darkweak/souin/helpers" @@ -272,15 +273,22 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, baseRq *http.Reques if !requestCc.NoCache { validator := rfc.ParseRequest(rq) var response *http.Response + var fresh, stale *http.Response + finalKey := cachedKey + if rq.Context().Value(context.Hashed).(bool) { + finalKey = fmt.Sprint(xxhash.Sum64String(finalKey)) + } for _, currentStorer := range s.Storers { - response = currentStorer.Prefix(cachedKey, rq, validator) - if response != nil { - s.Configuration.GetLogger().Sugar().Debugf("Found response in the %s storage", currentStorer.Name()) + fresh, stale = currentStorer.GetMultiLevel(finalKey, rq, validator) + + if fresh != nil || stale != nil { + s.Configuration.GetLogger().Sugar().Debugf("Found at least one valid response in the %s storage", currentStorer.Name()) break } } - if response != nil && rfc.ValidateCacheControl(response, requestCc) { + if rfc.ValidateCacheControl(response, requestCc) { + response := fresh rfc.SetCacheStatusHeader(response) if rfc.ValidateMaxAgeCachedResponse(requestCc, response) != nil { customWriter.Headers = response.Header @@ -290,13 +298,9 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, baseRq *http.Reques return nil } - } else if response == nil && (requestCc.MaxStaleSet || requestCc.MaxStale > -1) { - for _, currentStorer := range s.Storers { - response = currentStorer.Prefix(storage.StalePrefix+cachedKey, rq, validator) - if response != nil { - break - } - } + } else if requestCc.MaxStaleSet || requestCc.MaxStale > -1 { + response := stale + if nil != response && rfc.ValidateCacheControl(response, requestCc) { addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader)) rfc.SetCacheStatusHeader(response)