Skip to content

Commit

Permalink
feat(dependencies): bump Souin v1.6.49 (#83)
Browse files Browse the repository at this point in the history
darkweak authored May 30, 2024
1 parent 3d544e3 commit 1dd8d3b
Showing 7 changed files with 548 additions and 447 deletions.
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@ This is a distributed HTTP cache module for Caddy based on [Souin](https://githu
Using the minimal configuration the responses will be cached for `120s`
```caddy
{
order cache before rewrite
cache
}
@@ -29,7 +28,6 @@ example.com {
Here are all the available options for the global options
```caddy
{
order cache before rewrite
log {
level debug
}
@@ -324,9 +322,24 @@ redis-configuration.com {
cache {
redis {
configuration {
ClientName souin-redis
InitAddress 127.0.0.1:6379
SelectDB 0
Network my-network
Addr 127.0.0.1:6379
Username user
Password password
DB 1
MaxRetries 1
MinRetryBackoff 5s
MaxRetryBackoff 5s
DialTimeout 5s
ReadTimeout 5s
WriteTimeout 5s
PoolFIFO true
PoolSize 99999
PoolTimeout 10s
MinIdleConns 100
MaxIdleConns 100
ConnMaxIdleTime 5s
ConnMaxLifetime 5s
}
}
}
@@ -370,8 +383,12 @@ What does these directives mean?
| `key.disable_host` | Disable the host part in the key | `true`<br/><br/>`(default: false)` |
| `key.disable_method` | Disable the method part in the key | `true`<br/><br/>`(default: false)` |
| `key.disable_query` | Disable the query string part in the key | `true`<br/><br/>`(default: false)` |
| `key.disable_scheme` | Disable the scheme string part in the key | `true`<br/><br/>`(default: false)` |
| `key.hash` | Hash the key before store it in the storage to get smaller keys | `true`<br/><br/>`(default: false)` |
| `key.headers` | Add headers to the key matching the regexp | `Authorization Content-Type X-Additional-Header` |
| `key.hide` | Prevent the key from being exposed in the `Cache-Status` HTTP response header | `true`<br/><br/>`(default: false)` |
| `key.template` | Use caddy templates to create the key (when this option is enabled, disable_* directives are skipped) | `KEY-{http.request.uri.path}-{http.request.uri.query}` |
| `max_cacheable_body_bytes` | Set the maximum size (in bytes) for a response body to be cached (unlimited if omited) | `1048576` (1MB) |
| `mode` | Bypass the RFC respect | One of `bypass` `bypass_request` `bypass_response` `strict` (default `strict`) |
| `nuts` | Configure the Nuts cache storage | |
| `nuts.path` | Set the Nuts file path storage | `/anywhere/nuts/storage` |
@@ -381,11 +398,15 @@ What does these directives mean?
| `olric` | Configure the Olric cache storage | |
| `olric.path` | Configure Olric with a file | `/anywhere/olric_configuration.json` |
| `olric.configuration` | Configure Olric directly in the Caddyfile or your JSON caddy configuration | [See the Olric configuration for the options](https://github.com/buraksezer/olric/blob/master/cmd/olricd/olricd.yaml/) |
| `otter` | Configure the Otter cache storage | |
| `otter.configuration` | Configure Otter directly in the Caddyfile or your JSON caddy configuration | |
| `otter.configuration.size` | Set the size of the pool in Otter | `999999` (default `10000`) |
| `redis` | Configure the Redis cache storage | |
| `redis.url` | Set the Redis url storage | `localhost:6379` |
| `redis.configuration` | Configure Redis directly in the Caddyfile or your JSON caddy configuration | [See the Nuts configuration for the options](https://github.com/nutsdb/nutsdb#default-options) |
| `regex.exclude` | The regex used to prevent paths being cached | `^[A-z]+.*$` |
| `stale` | The stale duration | `25m` |
| `storers` | Storers chain to fallback if a previous one is unreachable or don't have the resource | `otter nuts badger redis` |
| `timeout` | The timeout configuration | |
| `timeout.backend` | The timeout duration to consider the backend as unreachable | `10s` |
| `timeout.cache` | The timeout duration to consider the cache provider as unreachable | `10ms` |
4 changes: 2 additions & 2 deletions app.go
Original file line number Diff line number Diff line change
@@ -52,6 +52,6 @@ func (s SouinApp) CaddyModule() caddy.ModuleInfo {
}

var (
_ caddy.App = (*SouinApp)(nil)
_ caddy.Module = (*SouinApp)(nil)
_ caddy.App = (*SouinApp)(nil)
_ caddy.Module = (*SouinApp)(nil)
)
42 changes: 39 additions & 3 deletions configuration.go
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ type DefaultCache struct {
// The default Cache-Control header value if none set by the upstream server.
DefaultCacheControl string `json:"default_cache_control"`
// The maximum body size (in bytes) to be stored into cache.
MaxBodyBytes uint64 `json:"max_cachable_body_bytes"`
MaxBodyBytes uint64 `json:"max_cacheable_body_bytes"`
// Redis provider configuration.
Distributed bool `json:"distributed"`
// Headers to add to the cache key if they are present.
@@ -40,6 +40,8 @@ type DefaultCache struct {
Etcd configurationtypes.CacheProvider `json:"etcd"`
// NutsDB provider configuration.
Nuts configurationtypes.CacheProvider `json:"nuts"`
// Otter provider configuration.
Otter configurationtypes.CacheProvider `json:"otter"`
// Regex to exclude cache.
Regex configurationtypes.Regex `json:"regex"`
// Storage providers chaining and order.
@@ -102,6 +104,11 @@ func (d *DefaultCache) GetNuts() configurationtypes.CacheProvider {
return d.Nuts
}

// GetOtter returns otter configuration
func (d *DefaultCache) GetOtter() configurationtypes.CacheProvider {
return d.Otter
}

// GetOlric returns olric configuration
func (d *DefaultCache) GetOlric() configurationtypes.CacheProvider {
return d.Olric
@@ -169,6 +176,11 @@ func (c *Configuration) GetUrls() map[string]configurationtypes.URL {
return c.URLs
}

// GetDefaultCache get the default cache
func (c *Configuration) GetPluginName() string {
return "caddy"
}

// GetDefaultCache get the default cache
func (c *Configuration) GetDefaultCache() configurationtypes.DefaultCacheInterface {
return &c.DefaultCache
@@ -373,6 +385,12 @@ func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal boo
ck.DisableMethod = true
case "disable_query":
ck.DisableQuery = true
case "disable_scheme":
ck.DisableScheme = true
case "template":
ck.Template = h.RemainingArgs()[0]
case "hash":
ck.Hash = true
case "hide":
ck.Hide = true
case "headers":
@@ -419,11 +437,11 @@ func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal boo
case "default_cache_control":
args := h.RemainingArgs()
cfg.DefaultCache.DefaultCacheControl = strings.Join(args, " ")
case "max_cachable_body_bytes":
case "max_cacheable_body_bytes":
args := h.RemainingArgs()
maxBodyBytes, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
return h.Errf("unsupported max_cachable_body_bytes: %s", args)
return h.Errf("unsupported max_cacheable_body_bytes: %s", args)
} else {
cfg.DefaultCache.MaxBodyBytes = maxBodyBytes
}
@@ -455,6 +473,12 @@ func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal boo
config_key.DisableMethod = true
case "disable_query":
config_key.DisableQuery = true
case "disable_scheme":
config_key.DisableScheme = true
case "template":
config_key.Template = h.RemainingArgs()[0]
case "hash":
config_key.Hash = true
case "hide":
config_key.Hide = true
case "headers":
@@ -491,6 +515,18 @@ func parseConfiguration(cfg *Configuration, h *caddyfile.Dispenser, isGlobal boo
}
}
cfg.DefaultCache.Nuts = provider
case "otter":
provider := configurationtypes.CacheProvider{}
for nesting := h.Nesting(); h.NextBlock(nesting); {
directive := h.Val()
switch directive {
case "configuration":
provider.Configuration = parseCaddyfileRecursively(h)
default:
return h.Errf("unsupported otter directive: %s", directive)
}
}
cfg.DefaultCache.Otter = provider
case "olric":
cfg.DefaultCache.Distributed = true
provider := configurationtypes.CacheProvider{}
156 changes: 83 additions & 73 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,74 +1,82 @@
module github.com/caddyserver/cache-handler

go 1.21
go 1.21.0

toolchain go1.21.2

require (
github.com/buraksezer/olric v0.5.4
github.com/caddyserver/caddy/v2 v2.7.6
github.com/darkweak/souin v1.6.47
go.uber.org/zap v1.26.0
github.com/caddyserver/caddy/v2 v2.8.1
github.com/darkweak/souin v1.6.49
go.uber.org/zap v1.27.0
)

require (
filippo.io/edwards25519 v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/RoaringBitmap/roaring v1.2.3 // indirect
github.com/alecthomas/chroma/v2 v2.9.1 // indirect
github.com/alecthomas/chroma/v2 v2.13.0 // indirect
github.com/antlabs/stl v0.0.1 // indirect
github.com/antlabs/timer v0.0.11 // indirect
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.5.0 // indirect
github.com/buraksezer/consistent v0.10.0 // indirect
github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/caddyserver/certmagic v0.20.0 // indirect
github.com/caddyserver/certmagic v0.21.2 // indirect
github.com/caddyserver/zerossl v0.1.3 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/darkweak/go-esi v0.0.5 // indirect
github.com/dgraph-io/badger v1.6.2 // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/badger/v3 v3.2103.5 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/dlclark/regexp2 v1.11.0 // indirect
github.com/dolthub/maphash v0.1.0 // indirect
github.com/dolthub/swiss v0.2.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/go-chi/chi/v5 v5.0.10 // indirect
github.com/go-kit/kit v0.10.0 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/gammazero/deque v0.2.1 // indirect
github.com/go-chi/chi/v5 v5.0.12 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-kit/kit v0.13.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.1.2 // indirect
github.com/golang/glog v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/cel-go v0.15.1 // indirect
github.com/google/certificate-transparency-go v1.1.6 // indirect
github.com/google/cel-go v0.20.1 // indirect
github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 // indirect
github.com/google/flatbuffers v23.1.21+incompatible // indirect
github.com/google/go-tpm v0.9.0 // indirect
github.com/google/go-tspi v0.3.0 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/google/pprof v0.0.0-20231212022811-ec68065c825e // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
@@ -82,40 +90,39 @@ require (
github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.0 // indirect
github.com/jackc/pgconn v1.14.3 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/pgx/v4 v4.18.0 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/libdns/libdns v0.2.1 // indirect
github.com/jackc/pgx/v4 v4.18.3 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/libdns/libdns v0.2.2 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mastercactapus/proxyprotocol v0.0.4 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/maypok86/otter v1.1.1 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mholt/acmez v1.2.0 // indirect
github.com/micromdm/scep/v2 v2.1.0 // indirect
github.com/miekg/dns v1.1.55 // indirect
github.com/mholt/acmez/v2 v2.0.1 // indirect
github.com/miekg/dns v1.1.59 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/nutsdb/nutsdb v0.14.3 // indirect
github.com/onsi/ginkgo/v2 v2.12.1 // indirect
github.com/onsi/ginkgo/v2 v2.13.2 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pquerna/cachecontrol v0.2.0 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/quic-go/quic-go v0.40.0 // indirect
github.com/quic-go/quic-go v0.44.0 // indirect
github.com/redis/rueidis v1.0.31 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -124,15 +131,17 @@ require (
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/slackhq/nebula v1.6.1 // indirect
github.com/smallstep/certificates v0.25.0 // indirect
github.com/smallstep/go-attestation v0.4.4-0.20230627102604-cf579e53cbd2 // indirect
github.com/smallstep/nosql v0.6.0 // indirect
github.com/smallstep/truststore v0.12.1 // indirect
github.com/smallstep/certificates v0.26.1 // indirect
github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect
github.com/smallstep/nosql v0.6.1 // indirect
github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81 // indirect
github.com/smallstep/scep v0.0.0-20231024192529-aee96d7ad34d // indirect
github.com/smallstep/truststore v0.13.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/tailscale/tscert v0.0.0-20230806124524-28a91b69a046 // indirect
github.com/tailscale/tscert v0.0.0-20240517230440-bbccfbf48933 // indirect
github.com/tidwall/btree v1.6.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/redcon v1.6.2 // indirect
@@ -142,49 +151,50 @@ require (
github.com/x448/float16 v0.8.4 // indirect
github.com/xujiajun/mmap-go v1.0.1 // indirect
github.com/xujiajun/utils v0.0.0-20220904132955-5f7c5b914235 // indirect
github.com/yuin/goldmark v1.5.6 // indirect
github.com/yuin/goldmark v1.7.1 // indirect
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.etcd.io/bbolt v1.3.9 // indirect
go.etcd.io/etcd/api/v3 v3.5.12 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.12 // indirect
go.etcd.io/etcd/client/v3 v3.5.12 // indirect
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 // indirect
go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect
go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect
go.opentelemetry.io/contrib/propagators/ot v1.17.0 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.step.sm/cli-utils v0.8.0 // indirect
go.step.sm/crypto v0.35.1 // indirect
go.step.sm/cli-utils v0.9.0 // indirect
go.step.sm/crypto v0.45.0 // indirect
go.step.sm/linkedca v0.20.1 // indirect
go.uber.org/mock v0.3.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.16.0 // indirect
google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
go.uber.org/zap/exp v0.2.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/crypto/x509roots/fallback v0.0.0-20240507223354-67b13616a595 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect
590 changes: 236 additions & 354 deletions go.sum

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions httpcache.go
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ func init() {
caddy.RegisterModule(SouinCaddyMiddleware{})
httpcaddyfile.RegisterGlobalOption(moduleName, parseCaddyfileGlobalOption)
httpcaddyfile.RegisterHandlerDirective(moduleName, parseCaddyfileHandlerDirective)
httpcaddyfile.RegisterDirectiveOrder(moduleName, httpcaddyfile.Before, "rewrite")
}

// SouinCaddyMiddleware allows the user to set up an HTTP cache system,
@@ -49,8 +50,10 @@ 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 Badger cache storage.
// Configure the Nuts cache storage.
Nuts configurationtypes.CacheProvider `json:"nuts,omitempty"`
// Configure the Otter cache storage.
Otter configurationtypes.CacheProvider `json:"otter,omitempty"`
// Enable the Etcd distributed cache storage.
Etcd configurationtypes.CacheProvider `json:"etcd,omitempty"`
// Enable the Redis distributed cache storage.
@@ -91,6 +94,7 @@ func (s *SouinCaddyMiddleware) configurationPropertyMapper() error {
defaultCache := DefaultCache{
Badger: s.Badger,
Nuts: s.Nuts,
Otter: s.Otter,
Key: s.Key,
DefaultCacheControl: s.DefaultCacheControl,
CacheName: s.CacheName,
@@ -185,7 +189,7 @@ func (s *SouinCaddyMiddleware) FromApp(app *SouinApp) error {
if dc.Timeout.Cache.Duration == 0 {
s.Configuration.DefaultCache.Timeout.Cache = appDc.Timeout.Cache
}
if !dc.Key.DisableBody && !dc.Key.DisableHost && !dc.Key.DisableMethod && !dc.Key.DisableQuery && !dc.Key.Hide && len(dc.Key.Headers) == 0 {
if !dc.Key.DisableBody && !dc.Key.DisableHost && !dc.Key.DisableMethod && !dc.Key.DisableQuery && !dc.Key.DisableScheme && !dc.Key.Hash && !dc.Key.Hide && len(dc.Key.Headers) == 0 && dc.Key.Template == "" {
s.Configuration.DefaultCache.Key = appDc.Key
}
if dc.DefaultCacheControl == "" {
@@ -215,6 +219,9 @@ func (s *SouinCaddyMiddleware) FromApp(app *SouinApp) error {
if dc.Nuts.Path == "" && dc.Nuts.Configuration == nil {
s.Configuration.DefaultCache.Nuts = appDc.Nuts
}
if dc.Otter.Configuration == nil {
s.Configuration.DefaultCache.Otter = appDc.Otter
}
if dc.Regex.Exclude == "" {
s.Configuration.DefaultCache.Regex.Exclude = appDc.Regex.Exclude
}
161 changes: 153 additions & 8 deletions httpcache_test.go
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ func TestMinimal(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
https_port 9443
cache
@@ -51,7 +50,6 @@ func TestHead(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
https_port 9443
cache
@@ -86,7 +84,6 @@ func TestQueryString(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
https_port 9443
cache {
@@ -117,7 +114,6 @@ func TestMaxAge(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
https_port 9443
cache
@@ -152,7 +148,6 @@ func TestMaxStale(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
https_port 9443
cache {
@@ -263,6 +258,88 @@ func TestAgeHeader(t *testing.T) {
}
}

func TestKeyGeneration(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
{
admin localhost:2999
http_port 9080
https_port 9443
cache {
ttl 1000s
}
}
localhost:9080 {
route /key-template-route {
cache {
key {
template {method}-{host}-{path}-WITH_SUFFIX
}
}
respond "Hello, template route!"
}
route /key-headers-route {
cache {
key {
headers X-Header X-Internal
}
}
respond "Hello, headers route!"
}
route /key-hash-route {
cache {
key {
hash
}
}
respond "Hello, hash route!"
}
}`, "caddyfile")

resp1, _ := tester.AssertGetResponse(`http://localhost:9080/key-template-route`, 200, "Hello, template route!")
if resp1.Header.Get("Age") != "" {
t.Errorf("unexpected Age header %v", resp1.Header.Get("Age"))
}
if !strings.Contains(resp1.Header.Get("Cache-Status"), "key=GET-localhost-/key-template-route-WITH_SUFFIX") {
t.Errorf("unexpected Cache-Status header %v", resp1.Header.Get("Cache-Status"))
}

resp2, _ := tester.AssertGetResponse(`http://localhost:9080/key-template-route`, 200, "Hello, template route!")
if resp2.Header.Get("Age") == "" {
t.Error("Age header should be present")
}
if resp2.Header.Get("Age") != "1" {
t.Error("Age header should be present")
}
if !strings.Contains(resp2.Header.Get("Cache-Status"), "key=GET-localhost-/key-template-route-WITH_SUFFIX") {
t.Errorf("unexpected Cache-Status header %v", resp2.Header.Get("Cache-Status"))
}

rq, _ := http.NewRequest(http.MethodGet, "http://localhost:9080/key-headers-route", nil)
rq.Header = http.Header{
"X-Internal": []string{"my-value"},
}
resp1, _ = tester.AssertResponse(rq, 200, "Hello, headers route!")
if resp1.Header.Get("Age") != "" {
t.Errorf("unexpected Age header %v", resp1.Header.Get("Age"))
}
if !strings.Contains(resp1.Header.Get("Cache-Status"), "key=GET-http-localhost:9080-/key-headers-route--my-value") {
t.Errorf("unexpected Cache-Status header %v", resp1.Header.Get("Cache-Status"))
}

rq.Header = http.Header{
"X-Header": []string{"first"},
"X-Internal": []string{"my-value"},
}
resp1, _ = tester.AssertResponse(rq, 200, "Hello, headers route!")
if resp1.Header.Get("Age") != "" {
t.Errorf("unexpected Age header %v", resp1.Header.Get("Age"))
}
if !strings.Contains(resp1.Header.Get("Cache-Status"), "key=GET-http-localhost:9080-/key-headers-route-first-my-value") {
t.Errorf("unexpected Cache-Status header %v", resp1.Header.Get("Cache-Status"))
}
}

func TestNotHandledRoute(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`
@@ -301,7 +378,7 @@ func TestMaxBodyByte(t *testing.T) {
https_port 9443
cache {
ttl 5s
max_cachable_body_bytes 30
max_cacheable_body_bytes 30
}
}
localhost:9080 {
@@ -446,7 +523,6 @@ func TestMustRevalidate(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
cache {
ttl 5s
@@ -546,7 +622,6 @@ func Test_ETags(t *testing.T) {
tester.InitServer(`
{
admin localhost:2999
order cache before rewrite
http_port 9080
cache {
ttl 50s
@@ -827,3 +902,73 @@ func TestESITags(t *testing.T) {
t.Error("Cache-Status should be already stored")
}
}

func TestCacheableStatusCode(t *testing.T) {
caddyTester := caddytest.NewTester(t)
caddyTester.InitServer(`
{
admin localhost:2999
http_port 9080
https_port 9443
cache {
ttl 10s
}
}
localhost:9080 {
cache
respond /cache-200 "" 200 {
close
}
respond /cache-204 "" 204 {
close
}
respond /cache-301 "" 301 {
close
}
respond /cache-405 "" 405 {
close
}
}`, "caddyfile")

cacheChecker := func(tester *caddytest.Tester, path string, expectedStatusCode int, expectedCached bool) {
resp1, _ := tester.AssertGetResponse("http://localhost:9080"+path, expectedStatusCode, "")
if resp1.Header.Get("Age") != "" {
t.Errorf("unexpected Age header %v", resp1.Header.Get("Age"))
}

cacheStatus := "Souin; fwd=uri-miss; "
if expectedCached {
cacheStatus += "stored; "
} else {
cacheStatus += "detail=UPSTREAM-ERROR-OR-EMPTY-RESPONSE; "
}
cacheStatus += "key=GET-http-localhost:9080-" + path

if resp1.Header.Get("Cache-Status") != cacheStatus {
t.Errorf("unexpected first Cache-Status header %v", resp1.Header.Get("Cache-Status"))
}

resp1, _ = tester.AssertGetResponse("http://localhost:9080"+path, expectedStatusCode, "")

cacheStatus = "Souin; "
if expectedCached {
if resp1.Header.Get("Age") != "1" {
t.Errorf("unexpected Age header %v", resp1.Header.Get("Age"))
}
cacheStatus += "hit; ttl=9; "
} else {
cacheStatus += "fwd=uri-miss; detail=UPSTREAM-ERROR-OR-EMPTY-RESPONSE; "
}
cacheStatus += "key=GET-http-localhost:9080-" + path

if resp1.Header.Get("Cache-Status") != cacheStatus {
t.Errorf("unexpected second Cache-Status header %v", resp1.Header.Get("Cache-Status"))
}
}

cacheChecker(caddyTester, "/cache-200", 200, false)
cacheChecker(caddyTester, "/cache-204", 204, true)
cacheChecker(caddyTester, "/cache-301", 301, true)
cacheChecker(caddyTester, "/cache-405", 405, true)
}

0 comments on commit 1dd8d3b

Please sign in to comment.