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

feat(chore): surrogate-keys distributed storage #448

Merged
merged 8 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ generate-workflow: ## Generate plugin workflow
bash .github/workflows/workflow_plugins_generator.sh

golangci-lint: ## Run golangci-lint to ensure the code quality
docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint:v1.50.1 golangci-lint run -v --timeout 180s ./...
docker run --rm -v $(PWD):/app -w /app golangci/golangci-lint:v1.55.2 golangci-lint run -v --timeout 180s ./...
for plugin in $(PLUGINS_LIST) ; do \
echo "Starting lint $$plugin \n" && docker run --rm -v $(PWD)/plugins/$$plugin:/app -w /app golangci/golangci-lint:v1.50.1 golangci-lint run -v --skip-dirs=override --timeout 240s ./...; \
done
Expand Down
130 changes: 0 additions & 130 deletions cache/types/souin.go

This file was deleted.

5 changes: 5 additions & 0 deletions configurationtypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,13 @@ type API struct {
Security SecurityAPI `json:"security" yaml:"security"`
}

type SurrogateConfiguration struct {
Storer string `json:"storer" yaml:"storer"`
}

// SurrogateKeys structure define the way surrogate keys are stored
type SurrogateKeys struct {
SurrogateConfiguration
URL string `json:"url" yaml:"url"`
Headers map[string]string `json:"headers" yaml:"headers"`
}
Expand Down
119 changes: 56 additions & 63 deletions docs/e2e/Souin E2E.postman_collection.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pkg/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/darkweak/souin/configurationtypes"
"github.com/darkweak/souin/pkg/api/debug"
"github.com/darkweak/souin/pkg/api/prometheus"
"github.com/darkweak/souin/pkg/storage"
"github.com/darkweak/souin/pkg/storage/types"
"github.com/darkweak/souin/pkg/surrogate/providers"
)

Expand All @@ -18,7 +18,7 @@ type MapHandler struct {
// GenerateHandlerMap generate the MapHandler
func GenerateHandlerMap(
configuration configurationtypes.AbstractConfigurationInterface,
storers []storage.Storer,
storers []types.Storer,
surrogateStorage providers.SurrogateInterface,
) *MapHandler {
hm := make(map[string]http.HandlerFunc)
Expand All @@ -45,7 +45,7 @@ func GenerateHandlerMap(
}

// Initialize contains all apis that should be enabled
func Initialize(c configurationtypes.AbstractConfigurationInterface, storers []storage.Storer, surrogateStorage providers.SurrogateInterface) []EndpointInterface {
func Initialize(c configurationtypes.AbstractConfigurationInterface, storers []types.Storer, surrogateStorage providers.SurrogateInterface) []EndpointInterface {
return []EndpointInterface{initializeSouin(c, storers,
surrogateStorage), debug.InitializeDebug(c), prometheus.InitializePrometheus(c)}
}
6 changes: 3 additions & 3 deletions pkg/api/souin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import (
"strings"

"github.com/darkweak/souin/configurationtypes"
"github.com/darkweak/souin/pkg/storage"
"github.com/darkweak/souin/pkg/storage/types"
"github.com/darkweak/souin/pkg/surrogate/providers"
)

// SouinAPI object contains informations related to the endpoints
type SouinAPI struct {
basePath string
enabled bool
storers []storage.Storer
storers []types.Storer
surrogateStorage providers.SurrogateInterface
allowedMethods []string
}
Expand All @@ -39,7 +39,7 @@ type invalidation struct {

func initializeSouin(
configuration configurationtypes.AbstractConfigurationInterface,
storers []storage.Storer,
storers []types.Storer,
surrogateStorage providers.SurrogateInterface,
) *SouinAPI {
basePath := configuration.GetAPI().Souin.BasePath
Expand Down
49 changes: 0 additions & 49 deletions pkg/coalescing/layerStorage.go

This file was deleted.

49 changes: 0 additions & 49 deletions pkg/coalescing/layerStorage_test.go

This file was deleted.

21 changes: 13 additions & 8 deletions pkg/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/darkweak/souin/pkg/api/prometheus"
"github.com/darkweak/souin/pkg/rfc"
"github.com/darkweak/souin/pkg/storage"
"github.com/darkweak/souin/pkg/storage/types"
"github.com/darkweak/souin/pkg/surrogate"
"github.com/darkweak/souin/pkg/surrogate/providers"
"github.com/pquerna/cachecontrol/cacheobject"
Expand Down Expand Up @@ -104,7 +105,7 @@ func NewHTTPCacheHandler(c configurationtypes.AbstractConfigurationInterface) *S

type SouinBaseHandler struct {
Configuration configurationtypes.AbstractConfigurationInterface
Storers []storage.Storer
Storers []types.Storer
InternalEndpointHandlers *api.MapHandler
ExcludeRegex *regexp.Regexp
RegexpUrls regexp.Regexp
Expand Down Expand Up @@ -160,16 +161,17 @@ func (s *SouinBaseHandler) Store(
return nil
}

if customWriter.Header().Get("Cache-Control") == "" {
headerName, cacheControl := s.SurrogateKeyStorer.GetSurrogateControl(customWriter.Header())
if cacheControl == "" {
// TODO see with @mnot if mandatory to not store the response when no Cache-Control given.
// if s.DefaultMatchedUrl.DefaultCacheControl == "" {
// customWriter.Header().Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=EMPTY-RESPONSE-CACHE-CONTROL", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context())))
// return nil
// }
customWriter.Header().Set("Cache-Control", s.DefaultMatchedUrl.DefaultCacheControl)
customWriter.Header().Set(headerName, s.DefaultMatchedUrl.DefaultCacheControl)
}

responseCc, _ := cacheobject.ParseResponseCacheControl(customWriter.Header().Get("Cache-Control"))
responseCc, _ := cacheobject.ParseResponseCacheControl(customWriter.Header().Get(headerName))
s.Configuration.GetLogger().Sugar().Debugf("Response cache-control %+v", responseCc)
if responseCc == nil {
customWriter.Header().Set("Cache-Status", fmt.Sprintf("%s; fwd=uri-miss; key=%s; detail=INVALID-RESPONSE-CACHE-CONTROL", rq.Context().Value(context.CacheName), rfc.GetCacheKeyFromCtx(rq.Context())))
Expand Down Expand Up @@ -259,7 +261,7 @@ func (s *SouinBaseHandler) Store(
default:
for _, storer := range s.Storers {
wg.Add(1)
go func(currentStorer storage.Storer) {
go func(currentStorer types.Storer) {
defer wg.Done()
if currentStorer.Set(cachedKey, response, currentMatchedURL, ma) == nil {
s.Configuration.GetLogger().Sugar().Debugf("Stored the key %s in the %s provider", cachedKey, currentStorer.Name())
Expand Down Expand Up @@ -345,8 +347,9 @@ func (s *SouinBaseHandler) Upstream(
}
}

if customWriter.Header().Get("Cache-Control") == "" {
customWriter.Header().Set("Cache-Control", s.DefaultMatchedUrl.DefaultCacheControl)
headerName, cacheControl := s.SurrogateKeyStorer.GetSurrogateControl(customWriter.Header())
if cacheControl == "" {
customWriter.Header().Set(headerName, s.DefaultMatchedUrl.DefaultCacheControl)
}

err := s.Store(customWriter, rq, requestCc, cachedKey)
Expand Down Expand Up @@ -526,6 +529,7 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n
}
}

headerName, _ := s.SurrogateKeyStorer.GetSurrogateControl(customWriter.Header())
if response != nil && (!modeContext.Strict || rfc.ValidateCacheControl(response, requestCc)) {
if validator.ResponseETag != "" && validator.Matched {
rfc.SetCacheStatusHeader(response)
Expand Down Expand Up @@ -553,7 +557,8 @@ func (s *SouinBaseHandler) ServeHTTP(rw http.ResponseWriter, rq *http.Request, n

return err
}
if resCc, _ := cacheobject.ParseResponseCacheControl(response.Header.Get("Cache-Control")); resCc.NoCachePresent {

if resCc, _ := cacheobject.ParseResponseCacheControl(response.Header.Get(headerName)); resCc.NoCachePresent {
prometheus.Increment(prometheus.NoCachedResponseCounter)
err := s.Revalidate(validator, next, customWriter, req, requestCc, cachedKey)
_, _ = customWriter.Send()
Expand Down
Loading
Loading