diff --git a/configurationtypes/types.go b/configurationtypes/types.go
index 016aae3a5..c6a60b8ed 100644
--- a/configurationtypes/types.go
+++ b/configurationtypes/types.go
@@ -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"`
@@ -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
}
@@ -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
@@ -382,6 +388,7 @@ type DefaultCacheInterface interface {
GetHeaders() []string
GetKey() Key
GetRegex() Regex
+ GetSimpleFS() CacheProvider
GetStale() time.Duration
GetStorers() []string
GetTimeout() Timeout
diff --git a/pkg/api/souin.go b/pkg/api/souin.go
index a14671b2a..d262488db 100644
--- a/pkg/api/souin.go
+++ b/pkg/api/souin.go
@@ -158,6 +158,7 @@ var storageToInfiniteTTLMap = map[string]time.Duration{
"OLRIC": types.OneYearDuration,
"OTTER": types.OneYearDuration,
"REDIS": -1,
+ "SIMPLEFS": 0,
types.DefaultStorageName: types.OneYearDuration,
}
diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go
index f407901c1..1d512ac54 100644
--- a/pkg/middleware/middleware.go
+++ b/pkg/middleware/middleware.go
@@ -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))
diff --git a/pkg/surrogate/providers/common.go b/pkg/surrogate/providers/common.go
index 490047ef9..1830d06e2 100644
--- a/pkg/surrogate/providers/common.go
+++ b/pkg/surrogate/providers/common.go
@@ -37,6 +37,7 @@ var storageToInfiniteTTLMap = map[string]time.Duration{
"OLRIC": types.OneYearDuration,
"OTTER": types.OneYearDuration,
"REDIS": -1,
+ "SIMPLEFS": 0,
types.DefaultStorageName: types.OneYearDuration,
}
diff --git a/plugins/caddy/Caddyfile b/plugins/caddy/Caddyfile
index 8ebabe803..5a657271d 100644
--- a/plugins/caddy/Caddyfile
+++ b/plugins/caddy/Caddyfile
@@ -4,23 +4,13 @@
level debug
}
cache {
- allowed_http_verbs GET POST
- api {
- prometheus
- souin
- }
- cdn {
- dynamic
- strategy hard
- }
- regex {
- exclude /test2.*
- }
- ttl 1000s
- timeout {
- backend 10s
- cache 100ms
+ simplefs {
+ configuration {
+ size 10
+ path storage
+ }
}
+ ttl 10s
default_cache_control public
}
}
@@ -28,341 +18,7 @@
:4443
respond "Hello World!"
-@match path /test1*
-@match2 path /test2*
-@matchdefault path /default
-@souin-api path /souin-api*
-
-cache @match {
- ttl 5s
-}
-
-cache @match2 {
- ttl 50s
-}
-
-cache @matchdefault {
- ttl 5s
-}
-
-route /badger-configuration {
- cache {
- ttl 15s
- badger {
- configuration {
- Dir /tmp/badger-configuration
- ValueDir match2
- ValueLogFileSize 16777216
- MemTableSize 4194304
- ValueThreshold 524288
- }
- }
- }
- respond "Hello badger"
-}
-
-route /etcd {
- cache {
- ttl 5s
- etcd {
- configuration {
- Endpoints etcd1:2379 etcd2:2379 etcd3:2379
- AutoSyncInterval 1s
- DialTimeout 1s
- DialKeepAliveTime 1s
- DialKeepAliveTimeout 1s
- MaxCallSendMsgSize 10000000
- MaxCallRecvMsgSize 10000000
- Username john
- Password doe
- RejectOldCluster false
- PermitWithoutStream false
- }
- }
- }
- respond "Hello etcd"
-}
-
-route /etcd-configuration {
- cache {
- ttl 5s
- etcd {
- configuration {
- Endpoints etcd:2379 etcd:2379
- AutoSyncInterval 1s
- DialTimeout 1s
- DialKeepAliveTime 1s
- DialKeepAliveTimeout 1s
- MaxCallSendMsgSize 10000000
- MaxCallRecvMsgSize 10000000
- RejectOldCluster false
- PermitWithoutStream false
- }
- }
- }
- respond "Hello etcd"
-}
-
-route /nats {
- cache {
- ttl 5s
- nats {
- url nats://127.0.0.1:4222
- }
- }
- respond "Hello nats"
-}
-
-route /nats-configuration {
- cache {
- ttl 5s
- nats {
- configuration {
- Servers nats://127.0.0.1:4222
- }
- }
- }
- respond "Hello nats"
-}
-
-route /nuts-configuration {
- cache {
- ttl 15s
- nuts {
- configuration {
- Dir /tmp/nuts-configuration
- EntryIdxMode 1
- RWMode 0
- SegmentSize 1024
- NodeNum 42
- SyncEnable true
- StartFileLoadingMode 1
- }
- }
- }
- respond "Hello nuts"
-}
-
-route /redis {
- cache {
- ttl 5s
- redis {
- configuration {
- ClientName souin-redis
- InitAddress 127.0.0.1:6379
- SelectDB 0
- }
- }
- }
- respond "Hello redis"
-}
-
-route /redis-configuration {
- cache {
- ttl 5s
- redis {
- configuration {
- ClientName souin-redis
- InitAddress 127.0.0.1:6379
- SelectDB 0
- }
- }
- }
- respond "Hello redis"
-}
-
-route /redis-url {
- cache {
- ttl 5s
- redis {
- url 127.0.0.1:6379
- }
- }
- respond "Hello redis url"
-}
-
-route /vary {
- cache {
- ttl 15s
- }
- header Vary X-Something
- respond "Hello {http.request.header.X-Something}"
-}
-
-route /cache-s-maxage {
- cache
- header Cache-Control "s-maxage=10"
- respond "Hello, s-maxage!"
-}
-
-route /cache-maxage {
- cache
- header Cache-Control "max-age=5"
- respond "Hello, max-age!"
-}
-
-route /cache-maxstale {
- cache {
- ttl 3s
- stale 5s
- }
- header Cache-Control "max-age=5"
- respond "Hello, max-age!"
-}
-
-route /not-modified {
- cache {
- ttl 5s
- }
- reverse_proxy 127.0.0.1:9000
-}
-
-route /no-reverse-proxy {
- cache
- reverse_proxy 127.0.0.1:9000
-}
-
-route /surrogate-keys {
+route /simplefs-configuration {
cache
- header Surrogate-Key "KEY-{http.request.header.X-Surrogate-Key-Suffix}"
- header Vary X-Surrogate-Key-Suffix,Accept-Encoding
- respond "Hello {http.request.header.X-Surrogate-Key-Suffix}"
+ respond "Hello simplefs"
}
-
-route /another-cache-status-name {
- cache {
- cache_name Another
- }
-}
-
-route /backend-timeout {
- cache {
- timeout {
- backend 1s
- cache 1ms
- }
- }
- reverse_proxy 127.0.0.1:8081
-}
-
-route /stream {
- cache
- reverse_proxy 127.0.0.1:81
-}
-
-route /gzip {
- cache
- encode {
- gzip
- minimum_length 5
- }
- header Content-Type text/plain
- respond "Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip. Hello, gzip."
-}
-
-route /custom-key/without-* {
- cache {
- cache_keys {
- body {
- disable_body
- }
- host {
- disable_host
- }
- method {
- disable_method
- }
- everything-with-content-type {
- disable_method
- headers Content-Type
- }
- }
- }
- respond "Hello to the authenticated user."
-}
-
-route /must-revalidate {
- cache {
- ttl 5s
- stale 5s
- }
- header Cache-Control "must-revalidate"
- reverse_proxy 127.0.0.1:81
-}
-
-route /cache-authorization {
- cache {
- cache_keys {
- /.+ {
- headers Authorization
- }
- }
- }
- header Souin-Cache-Control public
- respond "Hello to the authenticated user."
-}
-
-route /bypass {
- cache {
- mode bypass
- }
-
- header Cache-Control "no-store"
- respond "Hello bypass"
-}
-
-route /bypass_request {
- cache {
- mode bypass_request
- }
-
- respond "Hello bypass_request"
-}
-
-route /bypass_response {
- cache {
- mode bypass_response
- }
-
- header Cache-Control "no-cache, no-store"
- respond "Hello bypass_response"
-}
-
-route /strict_request {
- cache {
- mode strict
- }
-
- respond "Hello strict"
-}
-
-route /strict_response {
- cache {
- mode strict
- }
-
- header Cache-Control "no-cache, no-store"
- respond "Hello strict"
-}
-
-cache @souin-api {
-}
-
-# ESI part
-route /esi-include {
- cache
- header Content-Type text/html
- respond "
ESI INCLUDE
"
-}
-
-route /alt-esi-include {
- cache
- header Content-Type text/html
- respond "ALTERNATE ESI INCLUDE
"
-}
-
-route /esi {
- cache
- header Content-Type text/html
- respond ``
-}
\ No newline at end of file
diff --git a/plugins/caddy/configuration.go b/plugins/caddy/configuration.go
index a8b803ec2..0708509a5 100644
--- a/plugins/caddy/configuration.go
+++ b/plugins/caddy/configuration.go
@@ -52,6 +52,8 @@ type DefaultCache struct {
Timeout configurationtypes.Timeout `json:"timeout"`
// Time to live.
TTL configurationtypes.Duration `json:"ttl"`
+ // SimpleFS provider configuration.
+ SimpleFS configurationtypes.CacheProvider `json:"simplefs"`
// Stale time to live.
Stale configurationtypes.Duration `json:"stale"`
// Disable the coalescing system.
@@ -103,7 +105,7 @@ func (d *DefaultCache) GetMode() string {
return d.Mode
}
-// GetNats returns nuts configuration
+// GetNats returns nats configuration
func (d *DefaultCache) GetNats() configurationtypes.CacheProvider {
return d.Nats
}
@@ -133,6 +135,11 @@ func (d *DefaultCache) GetRegex() configurationtypes.Regex {
return d.Regex
}
+// GetSimpleFS returns simplefs configuration
+func (d *DefaultCache) GetSimpleFS() configurationtypes.CacheProvider {
+ return d.SimpleFS
+}
+
// GetStorers returns the chianed storers
func (d *DefaultCache) GetStorers() []string {
return d.Storers
@@ -309,6 +316,25 @@ func parseRedisConfiguration(c map[string]interface{}) map[string]interface{} {
return c
}
+func parseSimpleFSConfiguration(c map[string]interface{}) map[string]interface{} {
+ for k, v := range c {
+ switch k {
+ case "path":
+ c[k] = v
+ case "size":
+ if v == false {
+ c[k] = 0
+ } else if v == true {
+ c[k] = 1
+ } else {
+ c[k], _ = strconv.Atoi(v.(string))
+ }
+ }
+ }
+
+ return c
+}
+
func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal bool) error {
for h.Next() {
for nesting := h.Nesting(); h.NextBlock(nesting); {
@@ -537,7 +563,7 @@ func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal boo
return h.Errf("unsupported nats directive: %s", directive)
}
}
- cfg.DefaultCache.Nuts = provider
+ cfg.DefaultCache.Nats = provider
case "nuts":
provider := configurationtypes.CacheProvider{Found: true}
for nesting := h.Nesting(); h.NextBlock(nesting); {
@@ -617,6 +643,22 @@ func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal boo
return h.Errf("unsupported regex directive: %s", directive)
}
}
+ case "simplefs":
+ provider := configurationtypes.CacheProvider{Found: true}
+ for nesting := h.Nesting(); h.NextBlock(nesting); {
+ directive := h.Val()
+ switch directive {
+ case "path":
+ urlArgs := h.RemainingArgs()
+ provider.Path = urlArgs[0]
+ case "configuration":
+ provider.Configuration = parseCaddyfileRecursively(h)
+ provider.Configuration = parseSimpleFSConfiguration(provider.Configuration.(map[string]interface{}))
+ default:
+ return h.Errf("unsupported simplefs directive: %s", directive)
+ }
+ }
+ cfg.DefaultCache.SimpleFS = provider
case "stale":
args := h.RemainingArgs()
stale, err := time.ParseDuration(args[0])
diff --git a/plugins/caddy/dispatch.go b/plugins/caddy/dispatch.go
index 63574e806..76e5a75ba 100644
--- a/plugins/caddy/dispatch.go
+++ b/plugins/caddy/dispatch.go
@@ -2,6 +2,7 @@ package httpcache
import (
"fmt"
+ "os"
"strings"
"github.com/caddyserver/caddy/v2"
@@ -73,7 +74,7 @@ func (s *SouinCaddyMiddleware) parseStorages(ctx caddy.Context) {
if e != nil {
s.logger.Errorf("Error during Nats init, did you include the Nats storage (--with github.com/darkweak/storages/nats/caddy)? %v", e)
} else {
- s.Configuration.DefaultCache.Nuts.Uuid = fmt.Sprintf("NATS-%s-%s", s.Configuration.DefaultCache.Nats.URL, s.Configuration.DefaultCache.GetStale())
+ s.Configuration.DefaultCache.Nats.Uuid = fmt.Sprintf("NATS-%s-%s", s.Configuration.DefaultCache.Nats.URL, s.Configuration.DefaultCache.GetStale())
}
}
if s.Configuration.DefaultCache.Nuts.Found {
@@ -101,7 +102,7 @@ func (s *SouinCaddyMiddleware) parseStorages(ctx caddy.Context) {
if e != nil {
s.logger.Errorf("Error during Olric init, did you include the Olric storage (--with github.com/darkweak/storages/olric/caddy)? %v", e)
} else {
- s.Configuration.DefaultCache.Nuts.Uuid = fmt.Sprintf("OLRIC-%s-%s", s.Configuration.DefaultCache.Olric.URL, s.Configuration.DefaultCache.GetStale())
+ s.Configuration.DefaultCache.Olric.Uuid = fmt.Sprintf("OLRIC-%s-%s", s.Configuration.DefaultCache.Olric.URL, s.Configuration.DefaultCache.GetStale())
}
}
if s.Configuration.DefaultCache.Otter.Found {
@@ -172,4 +173,35 @@ func (s *SouinCaddyMiddleware) parseStorages(ctx caddy.Context) {
)
}
}
+ if s.Configuration.DefaultCache.SimpleFS.Found {
+ e := dispatchStorage(ctx, "simplefs", s.Configuration.DefaultCache.SimpleFS, s.Configuration.DefaultCache.GetStale())
+ if e != nil {
+ s.logger.Errorf("Error during SimpleFS init, did you include the SimpleFS storage (--with github.com/darkweak/storages/simplefs/caddy)? %v", e)
+ } else {
+ simplefs := s.Configuration.DefaultCache.SimpleFS
+ path := simplefs.Path
+ size := "0"
+ if c := simplefs.Configuration; c != nil {
+ p, ok := c.(map[string]interface{})
+ if ok {
+ if d, ok := p["path"]; path == "" && ok {
+ path = fmt.Sprint(d)
+ }
+ if d, ok := p["size"]; ok {
+ size = fmt.Sprint(d)
+ }
+ }
+ }
+
+ if path == "" {
+ path, _ = os.Getwd()
+ }
+
+ s.Configuration.DefaultCache.SimpleFS.Uuid = fmt.Sprintf(
+ "SIMPLEFS-%s-%s",
+ path,
+ size,
+ )
+ }
+ }
}
diff --git a/plugins/caddy/httpcache.go b/plugins/caddy/httpcache.go
index d72efd6ed..7d4c4f464 100644
--- a/plugins/caddy/httpcache.go
+++ b/plugins/caddy/httpcache.go
@@ -48,6 +48,8 @@ type SouinCaddyMiddleware struct {
Key configurationtypes.Key `json:"key,omitempty"`
// Override the cache key generation matching the pattern.
CacheKeys configurationtypes.CacheKeys `json:"cache_keys,omitempty"`
+ // Configure the Nats cache storage.
+ Nats configurationtypes.CacheProvider `json:"nats,omitempty"`
// Configure the Nuts cache storage.
Nuts configurationtypes.CacheProvider `json:"nuts,omitempty"`
// Configure the Otter cache storage.
@@ -62,6 +64,8 @@ type SouinCaddyMiddleware struct {
Timeout configurationtypes.Timeout `json:"timeout,omitempty"`
// Time to live for a key, using time.duration.
TTL configurationtypes.Duration `json:"ttl,omitempty"`
+ // Configure the SimpleFS cache storage.
+ SimpleFS configurationtypes.CacheProvider `json:"simplefs,omitempty"`
// Time to live for a stale key, using time.duration.
Stale configurationtypes.Duration `json:"stale,omitempty"`
// Storage providers chaining and order.
@@ -91,7 +95,9 @@ func (s *SouinCaddyMiddleware) configurationPropertyMapper() error {
if s.Configuration.GetDefaultCache() == nil {
defaultCache := DefaultCache{
Badger: s.Badger,
+ Nats: s.Nats,
Nuts: s.Nuts,
+ SimpleFS: s.SimpleFS,
Otter: s.Otter,
Key: s.Key,
DefaultCacheControl: s.DefaultCacheControl,
@@ -203,14 +209,16 @@ func (s *SouinCaddyMiddleware) FromApp(app *SouinApp) error {
if dc.CacheName == "" {
s.Configuration.DefaultCache.CacheName = appDc.CacheName
}
- if isProviderEmpty(dc.Badger) && isProviderEmpty(dc.Etcd) && isProviderEmpty(dc.Nats) && isProviderEmpty(dc.Nuts) && isProviderEmpty(dc.Olric) && isProviderEmpty(dc.Otter) && isProviderEmpty(dc.Redis) {
+ if isProviderEmpty(dc.Badger) && isProviderEmpty(dc.Etcd) && isProviderEmpty(dc.Nats) && isProviderEmpty(dc.Nuts) && isProviderEmpty(dc.Olric) && isProviderEmpty(dc.Otter) && isProviderEmpty(dc.Redis) && isProviderEmpty(dc.SimpleFS) {
s.Configuration.DefaultCache.Distributed = appDc.Distributed
s.Configuration.DefaultCache.Olric = appDc.Olric
s.Configuration.DefaultCache.Redis = appDc.Redis
s.Configuration.DefaultCache.Etcd = appDc.Etcd
s.Configuration.DefaultCache.Badger = appDc.Badger
+ s.Configuration.DefaultCache.Nats = appDc.Nats
s.Configuration.DefaultCache.Nuts = appDc.Nuts
s.Configuration.DefaultCache.Otter = appDc.Otter
+ s.Configuration.DefaultCache.SimpleFS = appDc.SimpleFS
}
if dc.Regex.Exclude == "" {
s.Configuration.DefaultCache.Regex.Exclude = appDc.Regex.Exclude
diff --git a/plugins/caddy/httpcache_test.go b/plugins/caddy/httpcache_test.go
index 3911e13e8..70f716a5d 100644
--- a/plugins/caddy/httpcache_test.go
+++ b/plugins/caddy/httpcache_test.go
@@ -4,6 +4,9 @@ import (
"context"
"fmt"
"net/http"
+ "net/url"
+ "os"
+ "path/filepath"
"strings"
"sync"
"testing"
@@ -1186,3 +1189,68 @@ func TestComplexQuery(t *testing.T) {
cacheChecker(caddyTester, "fields[]=id&pagination=true", 9)
cacheChecker(caddyTester, "fields[]=id&pagination=false", 9)
}
+
+func TestSimpleFS(t *testing.T) {
+ tester := caddytest.NewTester(t)
+ tester.InitServer(`
+ {
+ admin localhost:2999
+ http_port 9080
+ cache {
+ ttl 5s
+ stale 5s
+ simplefs {
+ configuration {
+ size 10
+ path storage
+ }
+ }
+ }
+ }
+ localhost:9080 {
+ route /simplefs {
+ cache
+ respond "Hello, simplefs storage!"
+ }
+ }`, "caddyfile")
+
+ time.Sleep(time.Second)
+ resp1, _ := tester.AssertGetResponse(`http://localhost:9080/simplefs`, http.StatusOK, "Hello simplefs storage!")
+
+ if resp1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/simplefs" {
+ 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 _, err := os.Stat(filepath.Join("storage", url.PathEscape("GET-http-localhost:9080-/simplefs"))); os.IsNotExist(err) {
+ t.Errorf("impossible to check the stored file %v", err)
+ }
+
+ resp2, _ := tester.AssertGetResponse(`http://localhost:9080/simplefs`, http.StatusOK, "Hello simplefs storage!")
+
+ if resp1.Header.Get("Cache-Status") != "Souin; fwd=uri-miss; stored; key=GET-http-localhost:9080-/simplefs" {
+ 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 _, err := os.Stat(filepath.Join("storage", url.PathEscape("GET-http-localhost:9080-/simplefs"))); os.IsNotExist(err) {
+ t.Errorf("impossible to check the stored file %v", err)
+ }
+
+ if resp2.Header.Get("Cache-Status") != "Souin; hit; ttl=4; key=GET-http-localhost:9080-/simplefs; detail=SIMPLEFS" {
+ t.Errorf("unexpected resp2 Cache-Status header %v", resp2.Header.Get("Cache-Status"))
+ }
+ if resp2.Header.Get("Age") != "1" {
+ t.Errorf("unexpected resp2 Age header %v", resp2.Header.Get("Age"))
+ }
+ if _, err := os.Stat(filepath.Join("storage", url.PathEscape("GET-http-localhost:9080-/simplefs"))); os.IsNotExist(err) {
+ t.Errorf("impossible to check the stored file %v", err)
+ }
+
+ time.Sleep(5 * time.Second)
+ if _, err := os.Stat(filepath.Join("storage", url.PathEscape("GET-http-localhost:9080-/simplefs"))); err == nil {
+ t.Errorf("the stored file %v should be deleted", err)
+ }
+}
diff --git a/plugins/echo/souin.go b/plugins/echo/souin.go
index f1ec9ad38..77b86e2ab 100644
--- a/plugins/echo/souin.go
+++ b/plugins/echo/souin.go
@@ -34,9 +34,6 @@ var (
Regex: configurationtypes.Regex{
Exclude: "/excluded",
},
- // Nuts: configurationtypes.CacheProvider{
- // Path: "./tmp",
- // },
TTL: configurationtypes.Duration{
Duration: 5 * time.Second,
},
diff --git a/plugins/kratos/configuration.go b/plugins/kratos/configuration.go
index edc20e372..2bb9d30ec 100644
--- a/plugins/kratos/configuration.go
+++ b/plugins/kratos/configuration.go
@@ -178,14 +178,20 @@ func parseDefaultCache(dcConfiguration map[string]config.Value) *configurationty
cdn.APIKey, _ = cdnConfigurationV.String()
case "dynamic":
cdn.Dynamic, _ = cdnConfigurationV.Bool()
+ case "email":
+ cdn.Email, _ = cdnConfigurationV.String()
case "hostname":
cdn.Hostname, _ = cdnConfigurationV.String()
case "network":
cdn.Network, _ = cdnConfigurationV.String()
case "provider":
cdn.Provider, _ = cdnConfigurationV.String()
+ case "service_id":
+ cdn.ServiceID, _ = cdnConfigurationV.String()
case "strategy":
cdn.Strategy, _ = cdnConfigurationV.String()
+ case "zone_id":
+ cdn.ZoneID, _ = cdnConfigurationV.String()
}
}
dc.CDN = cdn
@@ -300,6 +306,21 @@ func parseDefaultCache(dcConfiguration map[string]config.Value) *configurationty
if exclude != "" {
dc.Regex = configurationtypes.Regex{Exclude: exclude}
}
+ case "simplefs":
+ provider := configurationtypes.CacheProvider{}
+ simplefsConfiguration, _ := defaultCacheV.Map()
+ for simplefsConfigurationK, simplefsConfigurationV := range simplefsConfiguration {
+ switch simplefsConfigurationK {
+ case path:
+ provider.Path, _ = simplefsConfigurationV.String()
+ case configurationPK:
+ configMap, e := simplefsConfigurationV.Map()
+ if e == nil {
+ provider.Configuration = parseRecursively(configMap)
+ }
+ }
+ }
+ dc.SimpleFS = provider
case "timeout":
timeout := configurationtypes.Timeout{}
timeoutConfiguration, _ := defaultCacheV.Map()
diff --git a/plugins/souin/agnostic/configuration_parser.go b/plugins/souin/agnostic/configuration_parser.go
index 604518212..33e32db1f 100644
--- a/plugins/souin/agnostic/configuration_parser.go
+++ b/plugins/souin/agnostic/configuration_parser.go
@@ -142,14 +142,20 @@ func parseDefaultCache(dcConfiguration map[string]interface{}) *configurationtyp
cdn.APIKey, _ = cdnConfigurationV.(string)
case "dynamic":
cdn.Dynamic = cdnConfigurationV.(bool)
+ case "email":
+ cdn.Email, _ = cdnConfigurationV.(string)
case "hostname":
cdn.Hostname, _ = cdnConfigurationV.(string)
case "network":
cdn.Network, _ = cdnConfigurationV.(string)
case "provider":
cdn.Provider, _ = cdnConfigurationV.(string)
+ case "service_id":
+ cdn.ServiceID, _ = cdnConfigurationV.(string)
case "strategy":
cdn.Strategy, _ = cdnConfigurationV.(string)
+ case "zone_id":
+ cdn.ZoneID, _ = cdnConfigurationV.(string)
}
}
dc.CDN = cdn
@@ -255,6 +261,17 @@ func parseDefaultCache(dcConfiguration map[string]interface{}) *configurationtyp
}
}
}
+ case "simplefs":
+ provider := configurationtypes.CacheProvider{}
+ for simplefsConfigurationK, simplefsConfigurationV := range defaultCacheV.(map[string]interface{}) {
+ switch simplefsConfigurationK {
+ case path:
+ provider.Path, _ = simplefsConfigurationV.(string)
+ case configurationPK:
+ provider.Configuration = simplefsConfigurationV.(map[string]interface{})
+ }
+ }
+ dc.SimpleFS = provider
case "timeout":
timeout := configurationtypes.Timeout{}
for timeoutK, timeoutV := range defaultCacheV.(map[string]interface{}) {
diff --git a/plugins/traefik/override/configurationtypes/types.go b/plugins/traefik/override/configurationtypes/types.go
index 684b56241..10729fea2 100644
--- a/plugins/traefik/override/configurationtypes/types.go
+++ b/plugins/traefik/override/configurationtypes/types.go
@@ -241,6 +241,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"`
@@ -295,7 +296,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
}
@@ -325,6 +326,11 @@ func (d *DefaultCache) GetRegex() Regex {
return d.Regex
}
+// GetSimpleFS returns simpleFS configuration
+func (d *DefaultCache) GetSimpleFS() CacheProvider {
+ return d.SimpleFS
+}
+
// GetTimeout returns the backend and cache timeouts
func (d *DefaultCache) GetTimeout() Timeout {
return d.Timeout
@@ -376,6 +382,7 @@ type DefaultCacheInterface interface {
GetHeaders() []string
GetKey() Key
GetRegex() Regex
+ GetSimpleFS() CacheProvider
GetStale() time.Duration
GetStorers() []string
GetTimeout() Timeout
diff --git a/tests/mock.go b/tests/mock.go
index d88e6f532..97606b2b2 100644
--- a/tests/mock.go
+++ b/tests/mock.go
@@ -278,7 +278,7 @@ urls:
`
}
-// EtcdConfiguration simulate the configuration for the Nuts storage
+// EtcdConfiguration simulate the configuration for the Etcd storage
func EtcdConfiguration() string {
return `
api:
@@ -321,7 +321,7 @@ urls:
`
}
-// RedisConfiguration simulate the configuration for the Nuts storage
+// RedisConfiguration simulate the configuration for the Redis storage
func RedisConfiguration() string {
return `
api:
@@ -362,6 +362,46 @@ urls:
`
}
+// SimpleFSConfiguration simulate the configuration for the SimpleFS storage
+func SimpleFSConfiguration() string {
+ return `
+api:
+ basepath: /souin-api
+ security:
+ secret: your_secret_key
+ enable: true
+ users:
+ - username: user1
+ password: test
+ souin:
+ enable: true
+default_cache:
+ simplefs:
+ path: "./simplefs"
+ headers:
+ - Authorization
+ port:
+ web: 80
+ tls: 443
+ regex:
+ exclude: 'ARegexHere'
+ ttl: 1000s
+reverse_proxy_url: 'http://domain.com:81'
+ssl_providers:
+ - traefik
+urls:
+ 'domain.com/':
+ ttl: 1000s
+ headers:
+ - Authorization
+ 'mysubdomain.domain.com':
+ ttl: 50s
+ headers:
+ - Authorization
+ - 'Content-Type'
+`
+}
+
func baseEmbeddedOlricConfiguration(path string) string {
return fmt.Sprintf(`
api: