Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(multiple): october 2024 wave #558

Merged
merged 12 commits into from
Oct 28, 2024
9 changes: 8 additions & 1 deletion configurationtypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ type DefaultCache struct {
Redis CacheProvider `json:"redis" yaml:"redis"`
Port Port `json:"port" yaml:"port"`
Regex Regex `json:"regex" yaml:"regex"`
SimpleFS CacheProvider `json:"simplefs" yaml:"simplefs"`
Stale Duration `json:"stale" yaml:"stale"`
Storers []string `json:"storers" yaml:"storers"`
Timeout Timeout `json:"timeout" yaml:"timeout"`
Expand Down Expand Up @@ -300,7 +301,7 @@ func (d *DefaultCache) GetMode() string {
return d.Mode
}

// GetNats returns nuts configuration
// GetNats returns nats configuration
func (d *DefaultCache) GetNats() CacheProvider {
return d.Nats
}
Expand Down Expand Up @@ -340,6 +341,11 @@ func (d *DefaultCache) GetTTL() time.Duration {
return d.TTL.Duration
}

// GetSimpleFS returns simplefs configuration
func (d *DefaultCache) GetSimpleFS() CacheProvider {
return d.SimpleFS
}

// GetStale returns the stale duration
func (d *DefaultCache) GetStale() time.Duration {
return d.Stale.Duration
Expand Down Expand Up @@ -382,6 +388,7 @@ type DefaultCacheInterface interface {
GetHeaders() []string
GetKey() Key
GetRegex() Regex
GetSimpleFS() CacheProvider
GetStale() time.Duration
GetStorers() []string
GetTimeout() Timeout
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.1
require (
github.com/caddyserver/caddy/v2 v2.8.4
github.com/cespare/xxhash/v2 v2.2.0
github.com/darkweak/storages/core v0.0.8
github.com/darkweak/storages/core v0.0.11
github.com/google/uuid v1.6.0
github.com/pierrec/lz4/v4 v4.1.21
github.com/pquerna/cachecontrol v0.2.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/darkweak/go-esi v0.0.5 h1:b9LHI8Tz46R+i6p8avKPHAIBRQUCZDebNmKm5w/Zrns=
github.com/darkweak/go-esi v0.0.5/go.mod h1:koCJqwum1u6mslyZuq/Phm6hfG1K3ZK5Y7jrUBTH654=
github.com/darkweak/storages/core v0.0.8 h1:9e7rOxHiJwnvADDVCZ7LFRnUnOHGT+UMpNOFlR8BOiw=
github.com/darkweak/storages/core v0.0.8/go.mod h1:ajTpB9IFLRIRY0EEFLjM5vtsrcNTh+TJK9yRxgG5/wY=
github.com/darkweak/storages/core v0.0.11 h1:IwvpAtkhOmxC5pIffJ8opW6erpTnIi5zqPveiAQs8ew=
github.com/darkweak/storages/core v0.0.11/go.mod h1:ajTpB9IFLRIRY0EEFLjM5vtsrcNTh+TJK9yRxgG5/wY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
5 changes: 4 additions & 1 deletion pkg/api/souin.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ var storageToInfiniteTTLMap = map[string]time.Duration{
"OLRIC": types.OneYearDuration,
"OTTER": types.OneYearDuration,
"REDIS": -1,
"SIMPLEFS": 0,
types.DefaultStorageName: types.OneYearDuration,
}

Expand Down Expand Up @@ -305,7 +306,9 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) {
s.purgeMapping()
} else {
submatch := keysRg.FindAllStringSubmatch(r.RequestURI, -1)[0][1]
s.BulkDelete(submatch, true)
for _, current := range s.storers {
current.DeleteMany(submatch)
}
}
} else {
ck, _ := s.surrogateStorage.Purge(r.Header)
Expand Down
56 changes: 49 additions & 7 deletions pkg/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func NewHTTPCacheHandler(c configurationtypes.AbstractConfigurationInterface) *S
storers := []types.Storer{}
if len(storedStorers) != 0 {
dc := c.GetDefaultCache()
for _, s := range []string{dc.GetBadger().Uuid, dc.GetEtcd().Uuid, dc.GetNats().Uuid, dc.GetNuts().Uuid, dc.GetOlric().Uuid, dc.GetOtter().Uuid, dc.GetRedis().Uuid} {
for _, s := range []string{dc.GetBadger().Uuid, dc.GetEtcd().Uuid, dc.GetNats().Uuid, dc.GetNuts().Uuid, dc.GetOlric().Uuid, dc.GetOtter().Uuid, dc.GetRedis().Uuid, dc.GetSimpleFS().Uuid} {
if s != "" {
if st := core.GetRegisteredStorer(s); st != nil {
storers = append(storers, st.(types.Storer))
Expand Down Expand Up @@ -244,7 +244,7 @@ func (s *SouinBaseHandler) Store(
ma = time.Duration(responseCc.SMaxAge) * time.Second
} else if responseCc.MaxAge >= 0 {
ma = time.Duration(responseCc.MaxAge) * time.Second
} else if customWriter.Header().Get("Expires") != "" {
} else if !modeContext.Bypass_response && customWriter.Header().Get("Expires") != "" {
exp, err := time.Parse(time.RFC1123, customWriter.Header().Get("Expires"))
if err != nil {
return nil
Expand Down Expand Up @@ -569,7 +569,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n

req := s.context.SetBaseContext(rq)
cacheName := req.Context().Value(context.CacheName).(string)
if rq.Header.Get("Upgrade") == "websocket" || (s.ExcludeRegex != nil && s.ExcludeRegex.MatchString(rq.RequestURI)) {
if rq.Header.Get("Upgrade") == "websocket" || rq.Header.Get("Accept") == "text/event-stream" || (s.ExcludeRegex != nil && s.ExcludeRegex.MatchString(rq.RequestURI)) {
rw.Header().Set("Cache-Status", cacheName+"; fwd=bypass; detail=EXCLUDED-REQUEST-URI")
return next(rw, req)
}
Expand Down Expand Up @@ -673,13 +673,13 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
return nil
}

if validator.NeedRevalidation {
if !modeContext.Bypass_request && validator.NeedRevalidation {
err := s.Revalidate(validator, next, customWriter, req, requestCc, cachedKey, uri)
_, _ = customWriter.Send()

return err
}
if resCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(response.Header, headerName)); resCc.NoCachePresent {
if resCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(response.Header, headerName)); !modeContext.Bypass_response && resCc.NoCachePresent {
prometheus.Increment(prometheus.NoCachedResponseCounter)
err := s.Revalidate(validator, next, customWriter, req, requestCc, cachedKey, uri)
_, _ = customWriter.Send()
Expand Down Expand Up @@ -726,7 +726,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
return err
}

if responseCc.MustRevalidate || responseCc.NoCachePresent || validator.NeedRevalidation {
if modeContext.Bypass_response || responseCc.MustRevalidate || responseCc.NoCachePresent || validator.NeedRevalidation {
req.Header["If-None-Match"] = append(req.Header["If-None-Match"], validator.ResponseETag)
err := s.Revalidate(validator, next, customWriter, req, requestCc, cachedKey, uri)
statusCode := customWriter.GetStatusCode()
Expand All @@ -737,6 +737,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
response.Header.Set("Cache-Status", response.Header.Get("Cache-Status")+code)
maps.Copy(customWriter.Header(), response.Header)
customWriter.WriteHeader(response.StatusCode)
customWriter.Buf.Reset()
_, _ = io.Copy(customWriter.Buf, response.Body)
_, err := customWriter.Send()

Expand Down Expand Up @@ -774,7 +775,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
return err
}

if rfc.ValidateMaxAgeCachedStaleResponse(requestCc, response, int(addTime.Seconds())) != nil {
if !modeContext.Strict || rfc.ValidateMaxAgeCachedStaleResponse(requestCc, responseCc, response, int(addTime.Seconds())) != nil {
customWriter.WriteHeader(response.StatusCode)
rfc.HitStaleCache(&response.Header)
maps.Copy(customWriter.Header(), response.Header)
Expand All @@ -784,6 +785,47 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
return err
}
}
} else if stale != nil {
response := stale

if !modeContext.Strict {
rfc.SetCacheStatusHeader(response, storerName)
customWriter.WriteHeader(response.StatusCode)
rfc.HitStaleCache(&response.Header)
maps.Copy(customWriter.Header(), response.Header)
_, _ = io.Copy(customWriter.Buf, response.Body)
_, err := customWriter.Send()

return err
}

addTime, _ := time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader))
responseCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(response.Header, "Cache-Control"))

if !modeContext.Strict || rfc.ValidateMaxAgeCachedStaleResponse(requestCc, responseCc, response, int(addTime.Seconds())) != nil {
_, _ = time.ParseDuration(response.Header.Get(rfc.StoredTTLHeader))
rfc.SetCacheStatusHeader(response, storerName)

responseCc, _ := cacheobject.ParseResponseCacheControl(rfc.HeaderAllCommaSepValuesString(response.Header, "Cache-Control"))

if responseCc.StaleIfError > -1 || requestCc.StaleIfError > 0 {
err := s.Revalidate(validator, next, customWriter, req, requestCc, cachedKey, uri)
statusCode := customWriter.GetStatusCode()
if err != nil {
code := fmt.Sprintf("; fwd-status=%d", statusCode)
rfc.HitStaleCache(&response.Header)
response.Header.Set("Cache-Status", response.Header.Get("Cache-Status")+code)
maps.Copy(customWriter.Header(), response.Header)
customWriter.WriteHeader(response.StatusCode)
customWriter.Buf.Reset()
_, _ = io.Copy(customWriter.Buf, response.Body)
_, err := customWriter.Send()

return err
}
}

}
}
}

Expand Down
16 changes: 15 additions & 1 deletion pkg/rfc/age.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,25 @@ func ValidateMaxAgeCachedResponse(co *cacheobject.RequestCacheDirectives, res *h
return validateMaxAgeCachedResponse(res, int(ma), 0)
}

func ValidateMaxAgeCachedStaleResponse(co *cacheobject.RequestCacheDirectives, res *http.Response, addTime int) *http.Response {
func ValidateMaxAgeCachedStaleResponse(co *cacheobject.RequestCacheDirectives, resCo *cacheobject.ResponseCacheDirectives, res *http.Response, addTime int) *http.Response {
if co.MaxStaleSet {
return res
}

if resCo != nil && (resCo.StaleIfError > -1 || co.StaleIfError > 0) {
if resCo.StaleIfError > -1 {
if response := validateMaxAgeCachedResponse(res, int(resCo.StaleIfError), addTime); response != nil {
return response
}
}

if co.StaleIfError > 0 {
if response := validateMaxAgeCachedResponse(res, int(co.StaleIfError), addTime); response != nil {
return response
}
}
}

if co.MaxStale < 0 {
return nil
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/rfc/age_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,20 @@ func Test_ValidateMaxStaleCachedResponse(t *testing.T) {
},
}

if ValidateMaxAgeCachedStaleResponse(&coWithoutMaxStale, &expiredMaxAge, 3) != nil {
if ValidateMaxAgeCachedStaleResponse(&coWithoutMaxStale, nil, &expiredMaxAge, 3) != nil {
t.Errorf("The max-stale validation should return nil instead of the response with the given parameters:\nRequestCacheDirectives: %+v\nResponse: %+v\n", coWithoutMaxStale, expiredMaxAge)
}
if ValidateMaxAgeCachedStaleResponse(&coWithoutMaxStale, &validMaxAge, 14) != nil {
if ValidateMaxAgeCachedStaleResponse(&coWithoutMaxStale, nil, &validMaxAge, 14) != nil {
t.Errorf("The max-stale validation should return the response instead of nil with the given parameters:\nRequestCacheDirectives: %+v\nResponse: %+v\n", coWithoutMaxStale, validMaxAge)
}

if ValidateMaxAgeCachedStaleResponse(&coWithMaxStale, &expiredMaxAge, 0) != nil {
if ValidateMaxAgeCachedStaleResponse(&coWithMaxStale, nil, &expiredMaxAge, 0) != nil {
t.Errorf("The max-stale validation should return nil instead of the response with the given parameters:\nRequestCacheDirectives: %+v\nResponse: %+v\n", coWithMaxStale, expiredMaxAge)
}
if ValidateMaxAgeCachedStaleResponse(&coWithMaxStaleSet, &expiredMaxAge, 0) == nil {
if ValidateMaxAgeCachedStaleResponse(&coWithMaxStaleSet, nil, &expiredMaxAge, 0) == nil {
t.Errorf("The max-stale validation should return the response instead of nil with the given parameters:\nRequestCacheDirectives: %+v\nResponse: %+v\n", coWithMaxStaleSet, expiredMaxAge)
}
if ValidateMaxAgeCachedStaleResponse(&coWithMaxStale, &validMaxAge, 5) == nil {
if ValidateMaxAgeCachedStaleResponse(&coWithMaxStale, nil, &validMaxAge, 5) == nil {
t.Errorf("The max-stale validation should return the response instead of nil with the given parameters:\nRequestCacheDirectives: %+v\nResponse: %+v\n", coWithMaxStale, expiredMaxAge)
}
}
8 changes: 7 additions & 1 deletion pkg/surrogate/providers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ var storageToInfiniteTTLMap = map[string]time.Duration{
"OLRIC": types.OneYearDuration,
"OTTER": types.OneYearDuration,
"REDIS": -1,
"SIMPLEFS": 0,
types.DefaultStorageName: types.OneYearDuration,
}

func (s *baseStorage) ParseHeaders(value string) []string {
return strings.Split(value, s.parent.getHeaderSeparator())
res := strings.Split(value, s.parent.getHeaderSeparator())
for i, v := range res {
res[i] = strings.TrimSpace(v)
}

return res
}

func getCandidateHeader(header http.Header, getCandidates func() []string) (string, string) {
Expand Down
7 changes: 3 additions & 4 deletions plugins/beego/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ toolchain go1.22.4
require (
github.com/beego/beego/v2 v2.1.1
github.com/darkweak/souin v1.7.2
github.com/darkweak/souin/plugins/souin v0.0.0-00010101000000-000000000000
github.com/darkweak/souin/plugins/souin/storages v0.0.0-00010101000000-000000000000
github.com/darkweak/souin/plugins/souin v1.7.2
github.com/darkweak/souin/plugins/souin/storages v1.7.2
)

require (
Expand Down Expand Up @@ -41,7 +41,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/darkweak/go-esi v0.0.5 // indirect
github.com/darkweak/storages/badger v0.0.8 // indirect
github.com/darkweak/storages/core v0.0.8 // indirect
github.com/darkweak/storages/core v0.0.11 // indirect
github.com/darkweak/storages/etcd v0.0.8 // indirect
github.com/darkweak/storages/nats v0.0.8 // indirect
github.com/darkweak/storages/nuts v0.0.8 // indirect
Expand Down Expand Up @@ -186,5 +186,4 @@ require (
replace (
github.com/darkweak/souin v1.7.2 => ../..
github.com/darkweak/souin/plugins/souin => ../souin
github.com/darkweak/souin/plugins/souin/storages => ../souin/storages
)
6 changes: 4 additions & 2 deletions plugins/beego/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,12 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/darkweak/go-esi v0.0.5 h1:b9LHI8Tz46R+i6p8avKPHAIBRQUCZDebNmKm5w/Zrns=
github.com/darkweak/go-esi v0.0.5/go.mod h1:koCJqwum1u6mslyZuq/Phm6hfG1K3ZK5Y7jrUBTH654=
github.com/darkweak/souin/plugins/souin/storages v1.7.2 h1:vA1oFap6sbWO+Ebbq6NGtjmCFuCRJOZeG+XXPhhSIWA=
github.com/darkweak/souin/plugins/souin/storages v1.7.2/go.mod h1:VfkwGN+ubAuluSwbjGHqImbUjxdEA0N9xGJUTCcFBV0=
github.com/darkweak/storages/badger v0.0.8 h1:rKVXrasVA74xgiqGRgW0kH11NUIlWwn9HiFyHUok85k=
github.com/darkweak/storages/badger v0.0.8/go.mod h1:ZmrNmKkFzyu/B3+1nsvVeTvyg2I2mOV5yTpT46mZ06o=
github.com/darkweak/storages/core v0.0.8 h1:9e7rOxHiJwnvADDVCZ7LFRnUnOHGT+UMpNOFlR8BOiw=
github.com/darkweak/storages/core v0.0.8/go.mod h1:ajTpB9IFLRIRY0EEFLjM5vtsrcNTh+TJK9yRxgG5/wY=
github.com/darkweak/storages/core v0.0.11 h1:IwvpAtkhOmxC5pIffJ8opW6erpTnIi5zqPveiAQs8ew=
github.com/darkweak/storages/core v0.0.11/go.mod h1:ajTpB9IFLRIRY0EEFLjM5vtsrcNTh+TJK9yRxgG5/wY=
github.com/darkweak/storages/etcd v0.0.8 h1:Guzv6zgxkQJLjak36KsbtQqkmwMRJoZZI0B7ztZKIik=
github.com/darkweak/storages/etcd v0.0.8/go.mod h1:Yw9xJramKAzIRoC7tizVMYPSwUBHqxY5BPTh8OgyISY=
github.com/darkweak/storages/nats v0.0.8 h1:HRS3i2zzzIq1Qb3yoOUWD6MoRQgGV1NbECF1ex4wZjg=
Expand Down
Loading
Loading