Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Caddy Module: http.handlers.cache

This is a distributed HTTP cache module for Caddy based on Souin cache.

Warning

Since v1.7.0 Souin (the development repository that cache-handler is based on) implements only one storage. If you need a specific storage you have to take it from the storages repository and add it either in your code, during the build otherwise.
(e.g. with otter using caddy) You have to build your caddy module with the desired storage xcaddy build --with github.com/caddyserver/cache-handler --with github.com/darkweak/storages/otter/caddy and configure otter in your Caddyfile/JSON configuration file.
See the documentation about the storages.

Features

Minimal Configuration

Using the minimal configuration the responses will be cached for 120s

{
cache
}
example.com {
 cache reverse_proxy your-app:8080
}

Global Option Syntax

Here are all the available options for the global options

{
 log {
level debug
}
cache {
allowed_http_verbs GET POST PATCH
api {
basepath /some-basepath
prometheus
souin {
basepath /souin-changed-endpoint-path
}
}
badger {
path the_path_to_a_file.json
}
cache_keys {
.*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
hide
}
}
cache_name Another
cdn {
api_key XXXX
dynamic
 email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
etcd {
configuration {
 # Your etcd configuration here
}
}
key {
disable_body
disable_host
disable_method
headers Content-Type Authorization
}
 log_level debug
mode bypass
nuts {
path /path/to/the/storage
}
olric {
url url_to_your_cluster:3320
path the_path_to_a_file.yaml
configuration {
 # Your olric configuration here
}
}
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}
:4443respond"Hello World!"

Cache directive Syntax

Here are all the available options for the directive options

@match path /path
handle @match {
cache {
cache_name ChangeName
cache_keys {
(host1|host2).*\.css {
disable_body
disable_host
disable_method
disable_query
headers X-Token Authorization
}
}
cdn {
api_key XXXX
dynamic
email darkweak@protonmail.com
hostname domain.com
network your_network
provider fastly
strategy soft
service_id 123456_id
zone_id anywhere_zone
}
key {
disable_body
disable_host
disable_method
disable_query
headers Content-Type Authorization
}
log_level debug
regex {
exclude /test2.*
}
stale 200s
ttl 1000s
default_cache_control no-store
}
}

Provider Syntax

Badger

The badger provider must have either the path or the configuration directive.

badger-path.com {
cache {
badger {
path /tmp/badger/first-match
}
}
}
badger-configuration.com {
cache {
badger {
configuration {
# Required value
ValueDir <string>
# Optional
SyncWrites <bool>
NumVersionsToKeep <int>
ReadOnly <bool>
Compression <int>
InMemory <bool>
MetricsEnabled <bool>
MemTableSize <int>
BaseTableSize <int>
BaseLevelSize <int>
LevelSizeMultiplier <int>
TableSizeMultiplier <int>
MaxLevels <int>
VLogPercentile <float>
ValueThreshold <int>
NumMemtables <int>
BlockSize <int>
BloomFalsePositive <float>
BlockCacheSize <int>
IndexCacheSize <int>
NumLevelZeroTables <int>
NumLevelZeroTablesStall <int>
ValueLogFileSize <int>
ValueLogMaxEntries <int>
NumCompactors <int>
CompactL0OnClose <bool>
LmaxCompaction <bool>
ZSTDCompressionLevel <int>
VerifyValueChecksum <bool>
EncryptionKey <string>
EncryptionKeyRotationDuration <Duration>
BypassLockGuard <bool>
ChecksumVerificationMode <int>
DetectConflicts <bool>
NamespaceOffset <int>
}
}
}
}

Etcd

The etcd provider must have the configuration directive.

etcd-configuration.com {
cache {
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
}
}
}
}

NutsDB

The nutsdb provider must have either the path or the configuration directive.

nuts-path.com {
cache {
nuts {
path /tmp/nuts-path
}
}
}
nuts-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Olric

The olric provider must have either the url directive to work as client mode.

olric-url.com {
cache {
olric {
url olric:3320
}
}
}

The olric provider must have either the path or the configuration directive to work as embedded mode.

olric-path.com {
cache {
olric {
path /path/to/olricd.yml
}
}
}
olric-configuration.com {
cache {
nuts {
configuration {
Dir /tmp/nuts-configuration
EntryIdxMode 1
RWMode 0
SegmentSize 1024
NodeNum 42
SyncEnable true
StartFileLoadingMode 1
}
}
}
}

Redis

The redis provider must have either the URL or the configuration directive.

redis-url.com {
cache {
redis {
url 127.0.0.1:6379
}
}
}

You can also use the configuration. Refer to the Souin docs or rueidis client options to define your config as key value.

What does these directives mean?

KeyDescriptionValue example
allowed_http_verbsThe HTTP verbs allowed to be cachedGET POST PATCH

(default: GET HEAD)
apiThe cache-handler API cache management
api.basepathBasePath for all APIs to avoid conflicts/your-non-conflict-route

(default: /souin-api)
api.prometheusEnable the Prometheus metrics
api.souin.basepathSouin API basepath/another-souin-api-route

(default: /souin)
badgerConfigure the Badger cache storage
badger.pathConfigure Badger with a file/anywhere/badger_configuration.json
badger.configurationConfigure Badger directly in the Caddyfile or your JSON caddy configurationSee the Badger configuration for the options
cache_nameOverride the cache name to use in the Cache-Status response headerAnotherCaddyCache-HandlerSouin
cache_keysDefine the key generation rules for each URI matching the key regexp
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}Regexp that the URI should match to override the key generation.+\.css
cache_keys.{your regexp}.disable_bodyDisable the body part in the key matching the regexp (GraphQL context)true

(default: false)
cache_keys.{your regexp}.disable_hostDisable the host part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_methodDisable the method part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.disable_queryDisable the query string part in the key matching the regexptrue

(default: false)
cache_keys.{your regexp}.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
cache_keys.{your regexp}.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
cdnThe CDN management, if you use any cdn to proxy your requests Souin will handle that
cdn.providerThe provider placed before Souinakamai

fastly

souin
cdn.api_keyThe api key used to access to the providerXXXX
cdn.dynamicEnable the dynamic keys returned by your backend application(default: true)
cdn.emailThe api key used to access to the provider if required, depending the providerXXXX
cdn.hostnameThe hostname if required, depending the providerdomain.com
cdn.networkThe network if required, depending the provideryour_network
cdn.strategyThe strategy to use to purge the cdn cache, soft will keep the content as a stale resourcehard

(default: soft)
cdn.service_idThe service id if required, depending the provider123456_id
cdn.zone_idThe zone id if required, depending the provideranywhere_zone
default_cache_controlSet the default value of Cache-Control response header if not set by upstream (Souin treats empty Cache-Control as public if omitted)no-store
keyOverride the key generation with the ability to disable unecessary parts
key.disable_bodyDisable the body part in the key (GraphQL context)true

(default: false)
key.disable_hostDisable the host part in the keytrue

(default: false)
key.disable_methodDisable the method part in the keytrue

(default: false)
key.disable_queryDisable the query string part in the keytrue

(default: false)
key.disable_schemeDisable the scheme string part in the keytrue

(default: false)
key.hashHash the key before store it in the storage to get smaller keystrue

(default: false)
key.headersAdd headers to the key matching the regexpAuthorization Content-Type X-Additional-Header
key.hidePrevent the key from being exposed in the Cache-Status HTTP response headertrue

(default: false)
key.templateUse 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_bytesSet the maximum size (in bytes) for a response body to be cached (unlimited if omited)1048576 (1MB)
modeBypass the RFC respectOne of bypassbypass_requestbypass_responsestrict (default strict)
nutsConfigure the Nuts cache storage
nuts.pathSet the Nuts file path storage/anywhere/nuts/storage
nuts.configurationConfigure Nuts directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
etcdConfigure the Etcd cache storage
etcd.configurationConfigure Etcd directly in the Caddyfile or your JSON caddy configurationSee the Etcd configuration for the options
olricConfigure the Olric cache storage
olric.pathConfigure Olric with a file/anywhere/olric_configuration.json
olric.configurationConfigure Olric directly in the Caddyfile or your JSON caddy configurationSee the Olric configuration for the options
otterConfigure the Otter cache storage
otter.configurationConfigure Otter directly in the Caddyfile or your JSON caddy configuration
otter.configuration.sizeSet the size of the pool in Otter999999 (default 10000)
redisConfigure the Redis cache storage
redis.urlSet the Redis url storagelocalhost:6379
redis.configurationConfigure Redis directly in the Caddyfile or your JSON caddy configurationSee the Nuts configuration for the options
regex.excludeThe regex used to prevent paths being cached^[A-z]+.*$
staleThe stale duration25m
storersStorers chain to fallback if a previous one is unreachable or don't have the resourceotter nuts badger redis
timeoutThe timeout configuration
timeout.backendThe timeout duration to consider the backend as unreachable10s
timeout.cacheThe timeout duration to consider the cache provider as unreachable10ms
ttlThe TTL duration120s
log_levelThe log levelOne of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive

Other resources

You can find an example for the Caddyfile or the JSON file.
See the Souin configuration for the full configuration, and its associated Caddyfile

Development and Stable Versions

The Souin repository serves as the development version, where new features are introduced and tested. Once these features have been thoroughly stabilized, they are integrated into the cache-handler repository through a dependency update. This ensures that cache-handler remains the stable and reliable version for production use.

About

Distributed HTTP caching module for Caddy

Resources

Stars

391 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages