From b1792361afb1fdc3e9d3fedc3712a00008795272 Mon Sep 17 00:00:00 2001 From: darkweak Date: Fri, 25 Oct 2024 21:45:24 +0200 Subject: [PATCH] feat(caddy): allow to configure TLSConfig in Caddyfile --- plugins/caddy/Caddyfile | 360 +++++++++++++++++++++++++++++++- plugins/caddy/configuration.go | 20 ++ plugins/caddy/httpcache_test.go | 68 ------ 3 files changed, 372 insertions(+), 76 deletions(-) diff --git a/plugins/caddy/Caddyfile b/plugins/caddy/Caddyfile index 5a657271d..8ebabe803 100644 --- a/plugins/caddy/Caddyfile +++ b/plugins/caddy/Caddyfile @@ -4,13 +4,23 @@ level debug } cache { - simplefs { - configuration { - size 10 - path storage - } + allowed_http_verbs GET POST + api { + prometheus + souin + } + cdn { + dynamic + strategy hard + } + regex { + exclude /test2.* + } + ttl 1000s + timeout { + backend 10s + cache 100ms } - ttl 10s default_cache_control public } } @@ -18,7 +28,341 @@ :4443 respond "Hello World!" -route /simplefs-configuration { +@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 { cache - respond "Hello simplefs" + 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}" } + +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 0708509a5..df18a107d 100644 --- a/plugins/caddy/configuration.go +++ b/plugins/caddy/configuration.go @@ -310,6 +310,26 @@ func parseRedisConfiguration(c map[string]interface{}) map[string]interface{} { } case "ConnWriteTimeout", "MaxFlushDelay", "MinRetryBackoff", "MaxRetryBackoff", "DialTimeout", "ReadTimeout", "WriteTimeout", "PoolTimeout", "ConnMaxIdleTime", "ConnMaxLifetime": c[k], _ = time.ParseDuration(v.(string)) + case "MaxVersion", "MinVersion": + strV, _ := v.(string) + if strings.HasPrefix(strV, "TLS") { + strV = strings.Trim(strings.TrimPrefix(strV, "TLS"), " ") + } + + switch strV { + case "0x0300", "SSLv3": + c[k] = 0x0300 + case "0x0301", "1.0": + c[k] = 0x0301 + case "0x0302", "1.1": + c[k] = 0x0302 + case "0x0303", "1.2": + c[k] = 0x0303 + case "0x0304", "1.3": + c[k] = 0x0304 + } + case "TLSConfig": + c[k] = parseRedisConfiguration(v.(map[string]interface{})) } } diff --git a/plugins/caddy/httpcache_test.go b/plugins/caddy/httpcache_test.go index 70f716a5d..3911e13e8 100644 --- a/plugins/caddy/httpcache_test.go +++ b/plugins/caddy/httpcache_test.go @@ -4,9 +4,6 @@ import ( "context" "fmt" "net/http" - "net/url" - "os" - "path/filepath" "strings" "sync" "testing" @@ -1189,68 +1186,3 @@ 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) - } -}