{"id":13548580,"url":"https://github.com/darkweak/souin","last_synced_at":"2025-05-14T12:10:44.022Z","repository":{"id":37082171,"uuid":"218724447","full_name":"darkweak/souin","owner":"darkweak","description":"An HTTP cache system, RFC compliant, compatible with @tyktechnologies, @traefik, @caddyserver, @go-chi, @bnkamalesh, @beego, @devfeel, @labstack, @gofiber, @go-goyave, @go-kratos, @gin-gonic, @roadrunner-server, @zalando, @zeromicro, @nginx and @apache","archived":false,"fork":false,"pushed_at":"2025-03-31T17:20:36.000Z","size":52656,"stargazers_count":782,"open_issues_count":13,"forks_count":61,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-11T19:54:58.193Z","etag":null,"topics":["cache","caddy","caddy-module","caddy-plugin","caddy-server","caddyserver","echo-framework","gin-gonic","gin-middleware","http-cache","labstack-echo","middleware","skipper","souin-instance","traefik","traefik-plugin","traefik-v2","tyk","tyk-gateway","varnish"],"latest_commit_sha":null,"homepage":"https://docs.souin.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darkweak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-10-31T09:00:52.000Z","updated_at":"2025-04-11T13:43:07.000Z","dependencies_parsed_at":"2023-02-19T20:45:45.901Z","dependency_job_id":"8149b176-484b-4271-a001-a895f6c0021c","html_url":"https://github.com/darkweak/souin","commit_stats":{"total_commits":202,"total_committers":27,"mean_commits":7.481481481481482,"dds":"0.45049504950495045","last_synced_commit":"f9115e93f623da56590bfa12dfa7457c98f76080"},"previous_names":[],"tags_count":852,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkweak%2Fsouin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkweak%2Fsouin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkweak%2Fsouin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkweak%2Fsouin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darkweak","download_url":"https://codeload.github.com/darkweak/souin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140760,"owners_count":22021219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","caddy","caddy-module","caddy-plugin","caddy-server","caddyserver","echo-framework","gin-gonic","gin-middleware","http-cache","labstack-echo","middleware","skipper","souin-instance","traefik","traefik-plugin","traefik-v2","tyk","tyk-gateway","varnish"],"created_at":"2024-08-01T12:01:12.085Z","updated_at":"2025-05-14T12:10:43.961Z","avatar_url":"https://github.com/darkweak.png","language":"Go","readme":"![Souin logo](https://github.com/darkweak/souin/blob/master/docs/img/logo.svg)\n\n# Souin Table of Contents\n1. [Souin reverse-proxy cache description](#project-description)\n2. [Configuration](#configuration)  \n  2.1. [Required configuration](#required-configuration)  \n    2.1.1. [Souin as plugin](#souin-as-plugin)  \n    2.1.2. [Souin out-of-the-box](#souin-out-of-the-box)  \n  2.2. [Optional configuration](#optional-configuration)\n3. [Storages](#storages)  \n4. [APIs](#apis)  \n  4.1. [Prometheus API](#prometheus-api)  \n  4.2. [Souin API](#souin-api)  \n  4.3. [Security API](#security-api)\n5. [Diagrams](#diagrams)  \n  5.1. [Sequence diagram](#sequence-diagram)\n6. [Cache systems](#cache-systems)\n7. [GraphQL](#graphql)  \n8. [Plugins](#plugins)  \n  8.1. [Beego filter](#beego-filter)  \n  8.2. [Caddy module](#caddy-module)  \n  8.3. [Chi middleware](#chi-middleware)  \n  8.4. [Dotweb middleware](#dotweb-middleware)  \n  8.5. [Echo middleware](#echo-middleware)  \n  8.6. [Fiber middleware](#fiber-middleware)  \n  8.7. [Gin middleware](#gin-middleware)  \n  8.8. [Goa middleware](#goa-middleware)  \n  8.9. [Go-zero middleware](#go-zero-middleware)  \n  8.10. [Goyave middleware](#goyave-middleware)  \n  8.11. [Hertz middleware](#hertz-middleware)  \n  8.12. [Kratos filter](#kratos-filter)  \n  8.13. [Roadrunner middleware](#roadrunner-middleware)  \n  8.14. [Skipper filter](#skipper-filter)  \n  8.15. [Træfik plugin](#træfik-plugin)  \n  8.16. [Tyk plugin](#tyk-plugin)  \n  8.17. [Webgo middleware](#webgo-middleware)  \n9. [Credits](#credits)\n\n# Souin HTTP cache\n\n## Project description\nSouin is a new HTTP cache system suitable for every reverse-proxy. It can be either placed on top of your current reverse-proxy whether it's Apache, Nginx or as plugin in your favorite reverse-proxy like Træfik, Caddy or Tyk.  \nSince it's written in go, it can be deployed on any server and thanks to the docker integration, it will be easy to install on top of a Swarm, or a kubernetes instance.  \nIt's RFC compatible, supporting Vary, request coalescing, stale cache-control and other specifications related to the [RFC-7234](https://tools.ietf.org/html/rfc7234).  \nIt supports the newly written RFCs (currently in draft) [http-cache-groups](https://datatracker.ietf.org/doc/draft-nottingham-http-cache-groups/) and [http-invalidation](https://datatracker.ietf.org/doc/draft-nottingham-http-invalidation/).  \nIt also supports the [Cache-Status HTTP response header](https://www.rfc-editor.org/rfc/rfc9211), the YKey group such as Varnish, the [Targeted HTTP Cache Control RFC](https://www.rfc-editor.org/rfc/rfc9213), .  \nIt supports the ESI tags, thanks to the [go-esi package](https://github.com/darkweak/go-esi).\n\n\u003e [!WARNING]\n\u003e Since `v1.7.0` Souin implements only one storage. If you need a specific storage you have to take it from [the storages repository](https://github.com/darkweak/storages) and add it either in your code, during the build otherwise.  \n(e.g. with otter using caddy) You have to build your caddy module with the desired storage `xcaddy build --with github.com/darkweak/souin/plugins/caddy --with github.com/darkweak/storages/otter/caddy` and configure otter in your Caddyfile/JSON configuration file.  \nSee the [storages section](#storages) or the [documentation website about the storages](https://docs.souin.io/docs/storages).\n\n## Configuration\nThe configuration file is store at `/anywhere/configuration.yml`. You can supply your own as long as you use one of the minimal configurations below.\n\n### Required configuration\n#### Souin as plugin\n```yaml\ndefault_cache: # Required\n  ttl: 10s # Default TTL\n```\n\n#### Souin out-of-the-box\n```yaml\ndefault_cache: # Required\n  ttl: 10s # Default TTL\nreverse_proxy_url: 'http://traefik' # If it's in the same network you can use http://your-service, otherwise just use https://yourdomain.com\n```\n\n|  Key                |  Description                                                |  Value example                                                                                                            |\n|:--------------------|:------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------|\n| `default_cache.ttl` | Duration to cache request (in seconds)                      | 10                                                                                                                        |\n\nBesides, it's highly recommended to set `default_cache.default_cache_control` (see it below) to avoid undesired caching for responses without `Cache-Control` header.\n\n### Optional configuration\n```yaml\n# /anywhere/configuration.yml\napi:\n  basepath: /souin-api # Default route basepath for every additional APIs to avoid conflicts with existing routes\n  prometheus: # Prometheus exposed metrics\n    basepath: /anything-for-prometheus-metrics # Change the prometheus endpoint basepath\n  souin: # Souin listing keys and cache management\n    basepath: /anything-for-souin # Change the souin endpoint basepath\ncache_keys:\n  '.*\\.css':\n    disable_body: true # Prevent the body from being used in the cache key\n    disable_host: true # Prevent the host from being used in the cache key\n    disable_method: true # Prevent the method from being used in the cache key\n    disable_query: true # Prevent the query string from being used in the cache key\n    disable_scheme: true # request scheme the query string from being used in the cache key\n    disable_vary: true # Prevent the varied headers string from being used in the cache key\n    hash: true # Hash the cache key instead of a plaintext one\n    hide: true # Prevent the cache key to be in the response Cache-Status header\n    headers: # Add headers to the key\n      - Authorization # Add the header value in the key\n      - Content-Type # Add the header value in the key\n    template: \"{http.request.method}-{http.request.host}-{http.request.path}\" # Use caddy placeholders to create the key (when this option is enabled, disable_* directives are skipped)\ncdn: # If Souin is set after a CDN fill these informations\n  api_key: XXXX # Your provider API key if mandatory\n  provider: fastly # The provider placed before Souin (e.g. fastly, cloudflare, akamai, varnish)\n  strategy: soft # The strategy to purge the CDN cache based on tags (e.g. soft, hard)\n  dynamic: true # If true, you'll be able to add custom keys than the ones defined under the surrogate_keys key\ndefault_cache:\n  allowed_http_verbs: # Allowed HTTP verbs to cache (default GET, HEAD).\n    - GET\n    - POST\n    - HEAD\n  allowed_additional_status_codes: # Allowed additional HTTP status code to cache.\n    - 202\n    - 400\n  cache_name: Souin # Override the cache name to use in the Cache-Status header\n  distributed: true # Use Olric or Etcd distributed storage\n  key:\n    disable_body: true # Prevent the body from being used in the cache key\n    disable_host: true # Prevent the host from being used in the cache key\n    disable_method: true # Prevent the method from being used in the cache key\n    disable_query: true # Prevent the query string from being used in the cache key\n    disable_scheme: true # Prevent the request scheme string from being used in the cache key\n    disable_vary: true # Prevent the varied headers string from being used in the cache key\n    hash: true # Hash the cache key instead of a plaintext one\n    hide: true # Prevent the cache key to be in the response Cache-Status header\n    headers: # Add headers to the key\n      - Authorization # Add the header value in the key\n      - Content-Type # Add the header value in the key\n    template: \"{http.request.method}-{http.request.host}-{http.request.path}\" # Use caddy placeholders to create the key (when this option is enabled, disable_* directives are skipped)\n  etcd: # If distributed is set to true, you'll have to define either the etcd or olric section\n    configuration: # Configure directly the Etcd client\n      endpoints: # Define multiple endpoints\n        - etcd-1:2379 # First node\n        - etcd-2:2379 # Second node\n        - etcd-3:2379 # Third node\n  mode: bypass # Override the RFC respect.\n  olric: # If distributed is set to true, you'll have to define either the etcd or olric section\n    url: 'olric:3320' # Olric server\n  regex:\n    exclude: 'ARegexHere' # Regex to exclude from cache\n  stale: 1000s # Stale duration\n  timeout: # Timeout configuration\n    backend: 10s # Backend timeout before returning an HTTP unavailable response\n    cache: 20ms # Cache provider (badger, etcd, nutsdb, olric, depending the configuration you set) timeout before returning a miss\n  ttl: 1000s # Default TTL\n  default_cache_control: no-store # Set default value for Cache-Control response header if not set by upstream\nlog_level: INFO # Logs verbosity [ DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL ], case do not matter\nssl_providers: # The {providers}.json to use\n  - traefik\nurls:\n  'https:\\/\\/domain.com\\/first-.+': # First regex route configuration\n    ttl: 1000s # Override default TTL\n  'https:\\/\\/domain.com\\/second-route': # Second regex route configuration\n    ttl: 10s # Override default TTL\n  'https?:\\/\\/mysubdomain\\.domain\\.com': # Third regex route configuration\n    ttl: 50s # Override default TTL'\n    default_cache_control: public, max-age=86400 # Override default default Cache-Control\nykeys:\n  The_First_Test:\n    headers:\n      Content-Type: '.+'\n  The_Second_Test:\n    url: 'the/second/.+'\n  The_Third_Test:\n  The_Fourth_Test:\nsurrogate_keys:\n  The_First_Test:\n    headers:\n      Content-Type: '.+'\n  The_Second_Test:\n    url: 'the/second/.+'\n  The_Third_Test:\n  The_Fourth_Test:\n```\n\n| Key                                               | Description                                                                                                                                 | Value example                                                                                                                                                                                                                 |\n|:--------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `api`                                             | The cache-handler API cache management                                                                                                      |                                                                                                                                                                                                                               |\n| `api.basepath`                                    | BasePath for all APIs to avoid conflicts                                                                                                    | `/your-non-conflicting-route`\u003cbr/\u003e\u003cbr/\u003e`(default: /souin-api)`                                                                                                                                                                |\n| `api.{api}.enable`                                | (DEPRECATED) Enable the API with related routes                                                                                             | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: true if you define the api name, false then)`                                                                                                                                                      |\n| `api.{api}.security`                              | (DEPRECATED) Enable the JWT Authentication token verification                                                                               | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `api.security.secret`                             | (DEPRECATED) JWT secret key                                                                                                                 | `Any_charCanW0rk123`                                                                                                                                                                                                          |\n| `api.security.users`                              | (DEPRECATED) Array of authorized users with username x password combo                                                                       | `- username: admin`\u003cbr/\u003e\u003cbr/\u003e`  password: admin`                                                                                                                                                                              |\n| `api.souin.security`                              | Enable JWT validation to access the resource                                                                                                | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys`                                      | Define the key generation rules for each URI matching the key regexp                                                                        |                                                                                                                                                                                                                               |\n| `cache_keys.{your regexp}`                        | Regexp that the URI should match to override the key generation                                                                             | `.+\\.css`                                                                                                                                                                                                                     |\n| `cache_keys.{your regexp}.disable_body`           | Disable the body part in the key matching the regexp (GraphQL context)                                                                      | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.disable_host`           | Disable the host part in the key matching the regexp                                                                                        | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.disable_method`         | Disable the method part in the key matching the regexp                                                                                      | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.disable_query`          | Disable the query string part in the key matching the regexp                                                                                | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.disable_scheme`         | Disable the request scheme string part in the key matching the regexp                                                                       | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.disable_vary`           | Disable the vary string part in the key matching the regexp                                                                                 | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.hash`                   | Hash the key matching the regexp                                                                                                            | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cache_keys.{your regexp}.headers`                | Add headers to the key matching the regexp                                                                                                  | `- Authorization`\u003cbr/\u003e\u003cbr/\u003e`- Content-Type`\u003cbr/\u003e\u003cbr/\u003e`- X-Additional-Header`                                                                                                                                                  |\n| `cache_keys.{your regexp}.hide`                   | Prevent the key from being exposed in the `Cache-Status` HTTP response header                                                               | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `cdn`                                             | The CDN management, if you use any cdn to proxy your requests Souin will handle that                                                        |                                                                                                                                                                                                                               |\n| `cdn.provider`                                    | The provider placed before Souin                                                                                                            | `akamai`\u003cbr/\u003e\u003cbr/\u003e`fastly`\u003cbr/\u003e\u003cbr/\u003e`souin`                                                                                                                                                                                   |\n| `cdn.api_key`                                     | The api key used to access to the provider                                                                                                  | `XXXX`                                                                                                                                                                                                                        |\n| `cdn.dynamic`                                     | Enable the dynamic keys returned by your backend application                                                                                | `false`\u003cbr/\u003e\u003cbr/\u003e`(default: true)`                                                                                                                                                                                            |\n| `cdn.email`                                       | The api key used to access to the provider if required, depending the provider                                                              | `XXXX`                                                                                                                                                                                                                        |\n| `cdn.hostname`                                    | The hostname if required, depending the provider                                                                                            | `domain.com`                                                                                                                                                                                                                  |\n| `cdn.network`                                     | The network if required, depending the provider                                                                                             | `your_network`                                                                                                                                                                                                                |\n| `cdn.strategy`                                    | The strategy to use to purge the cdn cache, soft will keep the content as a stale resource                                                  | `hard`\u003cbr/\u003e\u003cbr/\u003e`(default: soft)`                                                                                                                                                                                             |\n| `cdn.service_id`                                  | The service id if required, depending the provider                                                                                          | `123456_id`                                                                                                                                                                                                                   |\n| `cdn.zone_id`                                     | The zone id if required, depending the provider                                                                                             | `anywhere_zone`                                                                                                                                                                                                               |\n| `default_cache.allowed_http_verbs`                | The HTTP verbs to support cache                                                                                                             | `- GET`\u003cbr/\u003e\u003cbr/\u003e`- POST`\u003cbr/\u003e\u003cbr/\u003e`(default: GET, HEAD)`                                                                                                                                                                     |\n| `default_cache.allowed_additional_status_codes`   | The additional HTTP status code to support cache                                                                                            | `- 200`\u003cbr/\u003e\u003cbr/\u003e`- 404`                                                                                                                                                                     |\n| `default_cache.badger`                            | Configure the Badger cache storage                                                                                                          |                                                                                                                                                                                                                               |\n| `default_cache.badger.path`                       | Configure Badger with a file                                                                                                                | `/anywhere/badger_configuration.json`                                                                                                                                                                                         |\n| `default_cache.badger.configuration`              | Configure Badger directly in the Caddyfile or your JSON caddy configuration                                                                 | [See the Badger configuration for the options](https://dgraph.io/docs/badger/get-started/)                                                                                                                                    |\n| `default_cache.default_cache_control`             | Set the default value of `Cache-Control` response header if not set by upstream (Souin treats empty `Cache-Control` as `public` if omitted) | `no-store`                                                                                                                                                                                                                    |\n| `default_cache.etcd`                              | Configure the Etcd cache storage                                                                                                            |                                                                                                                                                                                                                               |\n| `default_cache.etcd.configuration`                | Configure Etcd directly in the Caddyfile or your JSON caddy configuration                                                                   | [See the Etcd configuration for the options](https://pkg.go.dev/go.etcd.io/etcd/clientv3#Config)                                                                                                                              |\n| `default_cache.etcd.url`                          | Set the Etcd cluster endpoint                                                                                                               | `http://etcd1:2379,http://etcd2:2379`                                                                                                                                                                                         |\n| `default_cache.key`                               | Override the key generation with the ability to disable unecessary parts                                                                    |                                                                                                                                                                                                                               |\n| `default_cache.key.disable_body`                  | Disable the body part in the key (GraphQL context)                                                                                          | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.disable_host`                  | Disable the host part in the key                                                                                                            | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.disable_method`                | Disable the method part in the key                                                                                                          | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.disable_query`                 | Disable the query string part in the key                                                                                                    | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.disable_scheme`                | Disable the request scheme string part in the key                                                                                           | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.disable_vary`                  | Disable the request vary string part in the key                                                                                             | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.hash`                          | Hash the key name in the storage                                                                                                            | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.headers`                       | Add headers to the key matching the regexp                                                                                                  | `- Authorization`\u003cbr/\u003e\u003cbr/\u003e`- Content-Type`\u003cbr/\u003e\u003cbr/\u003e`- X-Additional-Header`                                                                                                                                                  |\n| `default_cache.key.hide`                          | Prevent the key from being exposed in the `Cache-Status` HTTP response header                                                               | `true`\u003cbr/\u003e\u003cbr/\u003e`(default: false)`                                                                                                                                                                                            |\n| `default_cache.key.template`                      | Use caddy placeholders to create the key (when this option is enabled, disable_* directives are skipped)                                    | [Placeholders documentation](https://caddyserver.com/docs/caddyfile/concepts#placeholders)                                                                                                                                    |\n| `default_cache.max_cacheable_body_bytes`          | Set the maximum size (in bytes) for a response body to be cached (unlimited if omited)                                                      | `1048576` (1MB)                                                                                                                                                                                                               |\n| `default_cache.mode`                              | RFC respect tweaking                                                                                                                        | One of `bypass` `bypass_request` `bypass_response` `strict` (default `strict`)                                                                                                                                                |\n| `default_cache.nats`                              | Configure the Nats cache storage                                                                                                            |                                                                                                                                                                                                                               |\n| `default_cache.nats.url`                          | Set the Nats cluster endpoint                                                                                                               | `nats://127.0.0.1:4222,nats://127.0.0.1:4223`                                                                                                                                                                                 |\n| `default_cache.nats.configuration`                | Configure Nats directly in the Caddyfile or your JSON caddy configuration                                                                   | [See the Nats configuration for the options](https://github.com/nats-io/nats.go/blob/main/nats.go#L267)                                                                                                                       |\n| `default_cache.nuts`                              | Configure the Nuts cache storage                                                                                                            |                                                                                                                                                                                                                               |\n| `default_cache.nuts.path`                         | Set the Nuts file path storage                                                                                                              | `/anywhere/nuts/storage`                                                                                                                                                                                                      |\n| `default_cache.nuts.configuration`                | Configure Nuts directly in the Caddyfile or your JSON caddy configuration                                                                   | [See the Nuts configuration for the options](https://github.com/nutsdb/nutsdb#default-options)                                                                                                                                |\n| `default_cache.olric`                             | Configure the Olric cache storage                                                                                                           |                                                                                                                                                                                                                               |\n| `default_cache.olric.path`                        | Configure Olric with a file                                                                                                                 | `/anywhere/olric_configuration.json`                                                                                                                                                                                          |\n| `default_cache.olric.configuration`               | Configure Olric directly in the Caddyfile or your JSON caddy configuration                                                                  | [See the Olric configuration for the options](https://github.com/buraksezer/olric/blob/master/cmd/olricd/olricd.yaml/)                                                                                                        |\n| `default_cache.otter`                             | Configure the Otter cache storage                                                                                                           |                                                                                                                                                                                                                               |\n| `default_cache.otter.configuration`               | Configure Otter directly in the Caddyfile or your JSON caddy configuration                                                                  |                                                                                                                                                                                                                               |\n| `default_cache.otter.configuration.size`          | Set the size of the pool in Otter                                                                                                           | `999999` (default `10000`)                                                                                                                                                                                                    |\n| `default_cache.port.{web,tls}`                    | The device's local HTTP/TLS port that Souin should be listening on                                                                          | Respectively `80` and `443`                                                                                                                                                                                                   |\n| `default_cache.redis`                             | Configure the Redis cache storage                                                                                                           |                                                                                                                                                                                                                               |\n| `default_cache.redis.url`                         | Set the Redis cluster endpoint                                                                                                              | `nats://127.0.0.1:4222,nats://127.0.0.1:4223`                                                                                                                                                                                 |\n| `default_cache.redis.configuration`               | Configure Redis directly in the Caddyfile or your JSON caddy configuration                                                                  | [See the Go-redis configuration for the options](https://github.com/redis/go-redis/blob/master/options.go#L31) or [See the Rueidis configuration for the options](https://github.com/redis/rueidis/blob/master/rueidis.go#56) |\n| `default_cache.regex.exclude`                     | The regex used to prevent paths being cached                                                                                                | `^[A-z]+.*$`                                                                                                                                                                                                                  |\n| `default_cache.stale`                             | The stale duration                                                                                                                          | `25m`                                                                                                                                                                                                                         |\n| `default_cache.timeout`                           | The timeout configuration                                                                                                                   |                                                                                                                                                                                                                               |\n| `default_cache.timeout.backend`                   | The timeout duration to consider the backend as unreachable                                                                                 | `10s`                                                                                                                                                                                                                         |\n| `default_cache.timeout.cache`                     | The timeout duration to consider the cache provider as unreachable                                                                          | `10ms`                                                                                                                                                                                                                        |\n| `default_cache.ttl`                               | The TTL duration                                                                                                                            | `120s`                                                                                                                                                                                                                        |\n| `log_level`                                       | The log level                                                                                                                               | `One of DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL it's case insensitive`                                                                                                                                                 |\n| `reverse_proxy_url`                               | The reverse-proxy's instance URL (Apache, Nginx, Træfik...)                                                                                 | - `http://yourservice` (Container way)\u003cbr/\u003e`http://localhost:81` (Local way)\u003cbr/\u003e`http://yourdomain.com:81` (Network way)                                                                                                     |\n| `ssl_providers`                                   | List of your providers handling certificates                                                                                                | `- traefik`\u003cbr/\u003e\u003cbr/\u003e`- nginx`\u003cbr/\u003e\u003cbr/\u003e`- apache`                                                                                                                                                                            |\n| `urls.{your url or regex}`                        | List of your custom configuration depending each URL or regex                                                                               | 'https:\\/\\/yourdomain.com'                                                                                                                                                                                                    |\n| `urls.{your url or regex}.ttl`                    | Override the default TTL if defined                                                                                                         | `90s`\u003cbr/\u003e\u003cbr/\u003e`10m`                                                                                                                                                                                                          |\n| `urls.{your url or regex}.default_cache_control`  | Override the default default `Cache-Control` if defined                                                                                     | `public, max-age=86400`                                                                                                                                                                                                       |\n| `surrogate_keys.{key name}.headers`               | Headers that should match to be part of the surrogate key group                                                                             | `Authorization: ey.+`\u003cbr/\u003e\u003cbr/\u003e`Content-Type: json`                                                                                                                                                                           |\n| `surrogate_keys.{key name}.headers.{header name}` | Header name that should be present a match the regex to be part of the surrogate key group                                                  | `Content-Type: json`                                                                                                                                                                                                          |\n| `surrogate_keys.{key name}.url`                   | Url that should match to be part of the surrogate key group                                                                                 | `.+`                                                                                                                                                                                                                          |\n| `ykeys.{key name}.headers`                        | (DEPRECATED) Headers that should match to be part of the ykey group                                                                         | `Authorization: ey.+`\u003cbr/\u003e\u003cbr/\u003e`Content-Type: json`                                                                                                                                                                           |\n| `ykeys.{key name}.headers.{header name}`          | (DEPRECATED) Header name that should be present a match the regex to be part of the ykey group                                              | `Content-Type: json`                                                                                                                                                                                                          |\n| `ykeys.{key name}.url`                            | (DEPRECATED) Url that should match to be part of the ykey group                                                                             | `.+`                                                                                                                                                                                                                          |\n\n## APIs\nAll endpoints are accessible through the `api.basepath` configuration line or by default through `/souin-api` to avoid named route conflicts. Be sure to define an unused route to not break your existing application.\n\n### Prometheus API\nPrometheus API expose some metrics about the cache.  \nThe base path for the prometheus API is `/metrics`.\n**Not supported inside Træfik because the deny the unsafe library usage inside plugins**\n\n| Method  | Endpoint | Description                             |\n|:--------|:---------|:----------------------------------------|\n| `GET`   | `/`      | Expose the different keys listed below. |\n\n| Key                                | Definition                                          |\n|:-----------------------------------|:----------------------------------------------------|\n| `souin_request_upstream_counter`   | Count the incoming requests that go to the upstream |\n| `souin_no_cached_response_counter` | Count the uncacheable responses                     |\n| `souin_cached_response_counter`    | Count the cacheable responses                       |\n| `souin_avg_response_time`          | Average response time                               |\n\n### Souin API\nSouin API allow users to manage the cache.  \nThe base path for the souin API is `/souin`.  \nThe Souin API supports the invalidation by surrogate keys such as Fastly which will replace the Varnish system. You can read the doc [about this system](https://github.com/darkweak/souin/blob/master/pkg/surrogate/README.md).\nThis system is able to invalidate by tags your cloud provider cache. Actually it supports Akamai and Fastly but in a near future some other providers would be implemented like Cloudflare or Varnish.\n\n| Method  | Endpoint          | Headers                                                    | Description                                                                                                                                                                         |\n|:--------|:------------------|:-----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `GET`   | `/`               | -                                                          | List stored keys cache                                                                                                                                                              |\n| `GET`   | `/surrogate_keys` | -                                                          | List stored keys cache                                                                                                                                                              |\n| `PURGE` | `/{id or regexp}` | -                                                          | Purge selected item(s) depending. The parameter can be either a specific key or a regexp; use `$` to end a specific key; without `$`, `id` is considered a regex |\n| `PURGE` | `/?ykey={key}`    | -                                                          | Purge selected item(s) corresponding to the target ykey such as Varnish (deprecated)                                                                                                |\n| `PURGE` | `/`               | `Surrogate-Key: Surrogate-Key-First, Surrogate-Key-Second` | Purge selected item(s) belong to the target key in the header `Surrogate-Key` (see [Surrogate-Key system](https://github.com/darkweak/souin/blob/master/cache/surrogate/README.md)) |\n| `PURGE` | `/flush`          | -                                                          | Purge all providers and surrogate storages                                                                                                                                          |\n\n### Security API\n**DEPRECATED**  \nSecurity API allows users to protect other APIs with JWT authentication.  \nThe base path for the security API is `/authentication`.\n\n| Method | Endpoint   | Body                                       | Headers                                                                         | Description                                                                                                            |\n|:-------|:-----------|:-------------------------------------------|:--------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------|\n| `POST` | `/login`   | `{\"username\":\"admin\", \"password\":\"admin\"}` | `['Content-Type' =\u003e 'json']`                                                    | Try to login, it returns a response which contains the cookie name `souin-authorization-token` with the JWT if succeed |\n| `POST` | `/refresh` | `-`                                        | `['Content-Type' =\u003e 'json', 'Cookie' =\u003e 'souin-authorization-token=the-token']` | Refreshes the token, replaces the old with a new one                                                                   |\n\n## Diagrams\n\n### Sequence diagram\nSee the sequence diagram for the minimal version below\n![Sequence diagram](https://github.com/darkweak/souin/blob/master/docs/plantUML/sequenceDiagram.svg?sanitize=true)\n\n## Cache systems\nSupported providers\n - [Badger](https://github.com/dgraph-io/badger)\n - [NutsDB](https://github.com/nutsdb/nutsdb)\n - [Etcd](https://github.com/etcd-io/etcd)\n - [Olric](https://github.com/buraksezer/olric)\n\nThe cache system sits on top of three providers at the moment. It provides two in-memory storage solutions (badger and nuts), and two distributed storages Olric and Etcd because setting, getting, updating and deleting keys in these providers is as easy as it gets.  \n**The Badger provider (default one)**: you can tune its configuration using the badger configuration inside your Souin configuration. In order to do that, you have to declare the `badger` block. See the following json example.\n```json\n\"badger\": {\n  \"configuration\": {\n    \"ValueDir\": \"default\",\n    \"ValueLogFileSize\": 16777216,\n    \"MemTableSize\": 4194304,\n    \"ValueThreshold\": 524288,\n    \"BypassLockGuard\": true\n  }\n}\n```\n\n**The Nuts provider**: you can tune its configuration using the nuts configuration inside your Souin configuration. In order to do that, you have to declare the `nuts` block. See the following json example.\n```json\n\"nuts\": {\n  \"configuration\": {\n    \"Dir\": \"default\",\n    \"EntryIdxMode\": 1,\n    \"RWMode\": 0,\n    \"SegmentSize\": 1024,\n    \"NodeNum\": 42,\n    \"SyncEnable\": true,\n    \"StartFileLoadingMode\": 1\n  }\n}\n```\n\n**The Otter provider**: you can tune its configuration using the otter configuration inside your Souin configuration. In order to do that, you have to declare the `otter` block. See the following json example.\n```json\n\"otter\": {\n  \"configuration\": {\n    \"size\": 9999999\n  }\n}\n```\n\n**The Olric provider**: you can tune its configuration using the olric configuration inside your Souin configuration and declare Souin has to use the distributed provider. In order to do that, you have to declare the `olric` block and the `distributed` directive. See the following json example.\n```json\n\"distributed\": true,\n\"olric\": {\n  \"configuration\": {\n    # Olric configuration here...\n  }\n}\n```\nIn order to do that, the Olric provider need to be either on the same network as the Souin instance when using docker-compose or over the internet, then it will use by default in-memory to avoid network latency as much as possible. \n\n**The Etcd provider**: you can tune its configuration using the etcd configuration inside your Souin configuration and declare Souin has to use the distributed provider. In order to do that, you have to declare the `etcd` block and the `distributed` directive. See the following json example.\n```json\n\"distributed\": true,\n\"etcd\": {\n  \"configuration\": {\n    # Etcd configuration here...\n  }\n}\n```\nIn order to do that, the Etcd provider need to be either on the same network as the Souin instance when using docker-compose or over the internet, then it will use by default in-memory to avoid network latency as much as possible. \nSouin will return at first the response from the choosen provider when it gives a non-empty response, or fallback to the reverse proxy otherwise.\nSince v1.4.2, Souin supports [Olric](https://github.com/buraksezer/olric) and since v1.6.10 it supports [Etcd](https://github.com/etcd-io/etcd) to handle distributed cache.\n\n## GraphQL\nThis feature is currently in beta.  \nSouin can partially cache your GraphQL requests. It automatically handles the data retrieval and omit the caching for the mutations.  \nHowever, it will invalidate whole cache keys with a body when you send a mutation request due to the inability to read and understand automatically which cached endpoint should be deleted.  \nYou can enable the GraphQL support with the `default_cache.allowed_http_verbs` key to define the list of supported HTTP verbs like `GET`, `POST`, `DELETE`.\n```yaml\ndefault_cache:\n  allowed_http_verbs:\n    - GET\n    - POST\n    - HEAD\n```\n\n### Cache invalidation\nThe cache invalidation is built for CRUD requests, if you're doing a GET HTTP request, it will serve the cached response when it exists, otherwise the reverse-proxy response will be served.  \nIf you're doing a POST, PUT, PATCH or DELETE HTTP request, the related cache GET request, and the list endpoint will be dropped.  \nIt also supports invalidation via [Souin API](#souin-api) to invalidate the cache programmatically.\n\n\n## Plugins\n\n### Beego filter\nTo use Souin as beego filter, you can refer to the [Beego filter integration folder](https://github.com/darkweak/souin/tree/master/plugins/beego) to discover how to configure it.  \nYou just have to define a new beego router and tell to the instance to use the `Handle` method like below:\n```go\nimport (\n\t\"net/http\"\n\n\thttpcache \"github.com/darkweak/souin/plugins/beego\"\n)\n\nfunc main(){\n\n    // ...\n\tweb.InsertFilterChain(\"/*\", httpcache.NewHTTPCacheFilter())\n    // ...\n\n}\n```\n\n### Caddy module\nTo use Souin as caddy module, you can refer to the [Caddy module integration folder](https://github.com/darkweak/souin/tree/master/plugins/caddy) to discover how to configure it.  \nThe related Caddyfile can be found [here](https://github.com/darkweak/souin/tree/master/plugins/caddy/Caddyfile).  \nThen you just have to run the following command:\n```bash\nxcaddy build --with github.com/darkweak/souin/plugins/caddy\n```\n\nThere is the fully configuration below\n```caddy\n{\n    log {\n        level debug\n    }\n    cache {\n        allowed_http_verbs GET POST PATCH\n        allowed_additional_status_codes 202\n        api {\n            basepath /some-basepath\n            prometheus {\n                security\n            }\n            souin {\n                security\n            }\n        }\n        badger {\n            path the_path_to_a_file.json\n        }\n        cache_name Souin\n        cache_keys {\n            .*\\.something {\n                disable_body\n                disable_host\n                disable_method\n                disable_query\n                disable_scheme\n                disable_vary\n                headers X-Token Authorization\n                hide\n                hash\n            }\n        }\n        cdn {\n            api_key XXXX\n            dynamic\n            email darkweak@protonmail.com\n            hostname domain.com\n            network your_network\n            provider fastly\n            strategy soft\n            service_id 123456_id\n            zone_id anywhere_zone\n        }\n        key {\n            disable_body\n            disable_host\n            disable_method\n            disable_query\n            disable_scheme\n            disable_vary\n            hash\n            hide\n            headers Content-Type Authorization\n        }\n        log_level debug\n        etcd {\n            configuration {\n                # Your Etcd configuration here\n            }\n        }\n        olric {\n            url url_to_your_cluster:3320\n            path the_path_to_a_file.yaml\n            configuration {\n                # Your Olric configuration here\n            }\n        }\n        regex {\n            exclude /test2.*\n        }\n        stale 200s\n        timeout {\n          backend 20s\n          cache 5ms\n        }\n        ttl 1000s\n        default_cache_control no-store\n    }\n}\n\n:4443\nrespond \"Hello World!\"\n\n@match path /test1*\n@match2 path /test2*\n@matchdefault path /default\n@souin-api path /souin-api*\n\ncache @match {\n    ttl 5s\n    badger {\n        path /tmp/badger/first-match\n        configuration {\n            # Required value\n            ValueDir \u003cstring\u003e\n\n            # Optional\n            SyncWrites \u003cbool\u003e\n            NumVersionsToKeep \u003cint\u003e\n            ReadOnly \u003cbool\u003e\n            Compression \u003cint\u003e\n            InMemory \u003cbool\u003e\n            MetricsEnabled \u003cbool\u003e\n            MemTableSize \u003cint\u003e\n            BaseTableSize \u003cint\u003e\n            BaseLevelSize \u003cint\u003e\n            LevelSizeMultiplier \u003cint\u003e\n            TableSizeMultiplier \u003cint\u003e\n            MaxLevels \u003cint\u003e\n            VLogPercentile \u003cfloat\u003e\n            ValueThreshold \u003cint\u003e\n            NumMemtables \u003cint\u003e\n            BlockSize \u003cint\u003e\n            BloomFalsePositive \u003cfloat\u003e\n            BlockCacheSize \u003cint\u003e\n            IndexCacheSize \u003cint\u003e\n            NumLevelZeroTables \u003cint\u003e\n            NumLevelZeroTablesStall \u003cint\u003e\n            ValueLogFileSize \u003cint\u003e\n            ValueLogMaxEntries \u003cint\u003e\n            NumCompactors \u003cint\u003e\n            CompactL0OnClose \u003cbool\u003e\n            LmaxCompaction \u003cbool\u003e\n            ZSTDCompressionLevel \u003cint\u003e\n            VerifyValueChecksum \u003cbool\u003e\n            EncryptionKey \u003cstring\u003e\n            EncryptionKey \u003cDuration\u003e\n            BypassLockGuard \u003cbool\u003e\n            ChecksumVerificationMode \u003cint\u003e\n            DetectConflicts \u003cbool\u003e\n            NamespaceOffset \u003cint\u003e\n        }\n    }\n}\n\ncache @match2 {\n    ttl 50s\n    badger {\n        path /tmp/badger/second-match\n        configuration {\n            ValueDir match2\n            ValueLogFileSize 16777216\n            MemTableSize 4194304\n            ValueThreshold 524288\n            BypassLockGuard true\n        }\n    }\n    default_cache_control \"public, max-age=86400\"\n}\n\ncache @matchdefault {\n    ttl 5s\n    badger {\n        path /tmp/badger/default-match\n        configuration {\n            ValueDir default\n            ValueLogFileSize 16777216\n            MemTableSize 4194304\n            ValueThreshold 524288\n            BypassLockGuard true\n        }\n    }\n}\n\nroute /no-method-and-domain.css {\n    cache {\n        cache_keys {\n            .*\\.css {\n                disable_host\n                disable_method\n            }\n        }\n    }\n    respond \"Hello without storing method and domain cache key\"\n}\n\ncache @souin-api {}\n```\n\n### Chi middleware\nTo use Souin as chi middleware, you can refer to the [Chi middleware integration folder](https://github.com/darkweak/souin/tree/master/plugins/chi) to discover how to configure it.  \nYou just have to define a new chi router and tell to the instance to use the `Handle` method like below:\n```go\nimport (\n\t\"net/http\"\n\n\tcache \"github.com/darkweak/souin/plugins/chi\"\n\t\"github.com/go-chi/chi/v5\"\n)\n\nfunc main(){\n\n    // ...\n\trouter := chi.NewRouter()\n\thttpcache := cache.NewHTTPCache(cache.DevDefaultConfiguration)\n\trouter.Use(httpcache.Handle)\n\trouter.Get(\"/*\", defaultHandler)\n    // ...\n\n}\n```\n\n### Dotweb middleware\nTo use Souin as dotweb middleware, you can refer to the [Dotweb plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/dotweb) to discover how to configure it.  \nYou just have to define a new dotweb router and tell to the instance to use the process method like below:\n```go\nimport (\n\tcache \"github.com/darkweak/souin/plugins/dotweb\"\n\t\"github.com/go-dotweb/dotweb/v5\"\n)\n\nfunc main(){\n\n    // ...\n\thttpcache := cache.NewHTTPCache(cache.DevDefaultConfiguration)\n\tapp.HttpServer.GET(\"/:p\", func(ctx dotweb.Context) error {\n\t\treturn ctx.WriteString(\"Hello, World 👋!\")\n\t}).Use(httpcache)\n    // ...\n\n}\n```\n\n### Echo middleware\nTo use Souin as echo middleware, you can refer to the [Echo plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/echo) to discover how to configure it.  \nYou just have to define a new echo router and tell to the instance to use the process method like below:\n```go\nimport (\n\t\"net/http\"\n\n\tsouin_echo \"github.com/darkweak/souin/plugins/echo\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc main(){\n\n    // ...\n\te := echo.New()\n\ts := souin_echo.New(souin_echo.DefaultConfiguration)\n\te.Use(s.Process)\n    // ...\n\n}\n```\n\n### Fiber middleware\nTo use Souin as fiber middleware, you can refer to the [Fiber plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/fiber) to discover how to configure it.  \nYou just have to define a new fiber router and tell to the instance to use the process method like below:\n```go\nimport (\n\tcache \"github.com/darkweak/souin/plugins/fiber\"\n\t\"github.com/gofiber/fiber/v2\"\n)\n\nfunc main(){\n\n    // ...\n\thttpcache := cache.NewHTTPCache(cache.DevDefaultConfiguration)\n\tapp.Use(httpcache.Handle)\n    // ...\n\n}\n```\n\n### Gin middleware\nTo use Souin as gin middleware, you can refer to the [Gin plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/gin) to discover how to configure it.  \nYou just have to define a new gin router and tell to the instance to use the process method like below:\n```go\nimport (\n\t\"net/http\"\n\n\tsouin_gin \"github.com/darkweak/souin/plugins/gin\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc main(){\n\n    // ...\n\tr := gin.New()\n\ts := souin_gin.New(souin_gin.DefaultConfiguration)\n\tr.Use(s.Process())\n    // ...\n\n}\n```\n\n### Go-zero middleware\nTo use Souin as go-zero middleware, you can refer to the [Go-zero plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/go-zero) to discover how to configure it.  \nYou just have to give a Condfiguration object to the `NewHTTPCache` method to get a new HTTP cache instance and use the Handle method as a GlobalMiddleware:\n```go\nimport (\n\t\"net/http\"\n\n\tcache \"github.com/darkweak/souin/plugins/go-zero\"\n)\n\nfunc main(){\n\n    // ...\n\thttpcache := cache.NewHTTPCache(cache.DevDefaultConfiguration)\n\tserver.Use(httpcache.Handle)\n    // ...\n\n}\n```\n\n### Goa middleware\nTo use Souin as goa middleware, you can refer to the [Goa plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/goa) to discover how to configure it.  \nYou just have to start Goa, define a new goa router and tell to the router instance to use the Handle method as GlobalMiddleware like below:\n```go\nimport (\n\t\"net/http\"\n\n\thttpcache \"github.com/darkweak/souin/plugins/goa\"\n\tgoahttp \"goa.design/goa/v3/http\"\n)\n\nfunc main(){\n\n    // ...\n\tg := goahttp.NewMuxer()\n\tg.Use(httpcache.NewHTTPCache(httpcache.DevDefaultConfiguration))\n    // ...\n\n}\n```\n\n### Goyave middleware\nTo use Souin as goyave middleware, you can refer to the [Goyave plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/goyave) to discover how to configure it.  \nYou just have to start Goyave, define a new goyave router and tell to the router instance to use the Handle method as GlobalMiddleware like below:\n```go\nimport (\n\t\"net/http\"\n\n\tcache \"github.com/darkweak/souin/plugins/goyave\"\n\t\"goyave.dev/goyave/v4\"\n)\n\nfunc main() {\n\t// ...\n\tgoyave.Start(func(r *goyave.Router) {\n\t\tr.GlobalMiddleware(cache.NewHTTPCache(cache.DevDefaultConfiguration).Handle)\n\t\t// ...\n\t})\n}\n```\n\n### Hertz middleware\nTo use Souin as hertz middleware, you can refer to the [Hertz middleware integration folder](https://github.com/darkweak/souin/tree/master/plugins/hertz) to discover how to configure it.  \nYou just have to use the `NewHTTPCache` method like below:\n```go\nimport (\n\t\"context\"\n\t\"net/http\"\n\n\t// ...\n\thttpcache \"github.com/darkweak/souin/plugins/hertz\"\n)\n\nfunc main() {\n\t// ...\n\th.Use(httpcache.NewHTTPCache(httpcache.DevDefaultConfiguration))\n\t// ...\n}\n```\n\n### Kratos filter\nTo use Souin as Kratos filter, you can refer to the [Kratos plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/kratos) to discover how to configure it.  \nYou just have to start the Kratos HTTP server with the Souin filter like below:\n```go\nimport (\n\thttpcache \"github.com/darkweak/souin/plugins/kratos\"\n\tkratos_http \"github.com/go-kratos/kratos/v2/transport/http\"\n)\n\nfunc main() {\n\tkratos_http.NewServer(\n\t\tkratos_http.Filter(\n\t\t\thttpcache.NewHTTPCacheFilter(httpcache.DevDefaultConfiguration),\n\t\t),\n\t)\n}\n```\n\nYou can also use the configuration file to configuration the HTTP cache. Refer to the code block below:\n```\nserver: #...\ndata: #...\n# HTTP cache part\nhttpcache:\n  api:\n    souin: {}\n  default_cache:\n    regex:\n      exclude: /excluded\n    ttl: 5s\n  log_level: debug\n```\nAfter that you have to edit your server instanciation to use the HTTP cache configuration parser\n```go\nimport (\n\thttpcache \"github.com/darkweak/souin/plugins/kratos\"\n\tkratos_http \"github.com/go-kratos/kratos/v2/transport/http\"\n)\n\nfunc main() {\n  c := config.New(\n\t\tconfig.WithSource(file.NewSource(\"examples/configuration.yml\")),\n\t\tconfig.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {\n\t\t\treturn yaml.Unmarshal(kv.Value, v)\n\t\t}),\n\t)\n\tif err := c.Load(); err != nil {\n\t\tpanic(err)\n\t}\n\n\tserver := kratos_http.NewServer(\n\t\tkratos_http.Filter(\n\t\t\thttpcache.NewHTTPCacheFilter(httpcache.ParseConfiguration(c)),\n\t\t),\n\t)\n  // ...\n}\n```\n\n### Roadrunner middleware\nTo use Souin as Roadrunner middleware, you can refer to the [Roadrunner plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/roadrunner) to discover how to configure it.  \nYsou have to build your `rr` binary with the souin dependency.\n```toml\n[velox]\nbuild_args = ['-trimpath', '-ldflags', '-s -X github.com/roadrunner-server/roadrunner/v2/internal/meta.version=${VERSION} -X github.com/roadrunner-server/roadrunner/v2/internal/meta.buildTime=${TIME}']\n\n[roadrunner]\nref = \"master\"\n\n[github]\n    [github.token]\n    token = \"GH_TOKEN\"\n\n    [github.plugins]\n    logger = { ref = \"master\", owner = \"roadrunner-server\", repository = \"logger\" }\n    cache = { ref = \"master\", owner = \"darkweak\", repository = \"souin\", folder = \"/plugins/roadrunner\" }\n\t# others ...\n\n[log]\nlevel = \"debug\"\nmode = \"development\"\n```\n\nAfter that, you'll be able to set each Souin configuration key under the `http.cache` key.\n```yaml\n# .rr.yaml\nhttp:\n  # Other http sub keys\n  cache:\n    api:\n      basepath: /httpcache_api\n      prometheus:\n        basepath: /anything-for-prometheus-metrics\n      souin: {}\n    default_cache:\n      allowed_http_verbs:\n        - GET\n        - POST\n        - HEAD\n      allowed_additional_status_codes:\n        - 202\n        - 400\n      cdn:\n        api_key: XXXX\n        dynamic: true\n        hostname: XXXX\n        network: XXXX\n        provider: fastly\n        strategy: soft\n      regex:\n        exclude: '/excluded'\n      timeout:\n        backend: 5s\n        cache: 1ms\n      ttl: 5s\n      stale: 10s\n    log_level: debug\n    ykeys:\n      The_First_Test:\n        headers:\n          Content-Type: '.+'\n      The_Second_Test:\n        url: 'the/second/.+'\n    surrogate_keys:\n      The_First_Test:\n        headers:\n          Content-Type: '.+'\n      The_Second_Test:\n        url: 'the/second/.+'\n  middleware:\n    - cache\n    # Other middlewares\n```\n\n\n### Skipper filter\nTo use Souin as skipper filter, you can refer to the [Skipper plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/skipper) to discover how to configure it.  \nYou just have to add to your Skipper instance the Souin filter like below:\n```go\npackage main\n\nimport (\n\tsouin_skipper \"github.com/darkweak/souin/plugins/skipper\"\n\t\"github.com/zalando/skipper\"\n\t\"github.com/zalando/skipper/filters\"\n)\n\nfunc main() {\n\tskipper.Run(skipper.Options{\n\t\tAddress:       \":9090\",\n\t\tRoutesFile:    \"example.yaml\",\n\t\tCustomFilters: []filters.Spec{souin_skipper.NewSouinFilter()}},\n\t)\n}\n```\n\nAfter that you will be able to declare the httpcache filter in your eskip file.\n```\nhello: Path(\"/hello\") \n  -\u003e httpcache(`{\"api\":{\"basepath\":\"/souin-api\",\"security\":{\"secret\":\"your_secret_key\",\"enable\":true,\"users\":[{\"username\":\"user1\",\"password\":\"test\"}]},\"souin\":{\"security\":true,\"enable\":true}},\"default_cache\":{\"regex\":{\"exclude\":\"ARegexHere\"},\"ttl\":\"10s\",\"stale\":\"10s\"},\"log_level\":\"INFO\"}`)\n  -\u003e \"https://www.example.org\"\n```\n\n### Træfik plugin\nTo use Souin as Træfik plugin, you can refer to the [pilot documentation](https://pilot.traefik.io/plugins/6123af58d00e6cd1260b290e/souin) and the [Træfik plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/traefik) to discover how to configure it.  \nYou have to declare the `experimental` block in your traefik static configuration file. Keep in mind Træfik run their own interpreter and they often break any dependances (such as the yaml.v3 support).\n```yaml\n# anywhere/traefik.yml\nexperimental:\n  plugins:\n    souin:\n      moduleName: github.com/darkweak/souin\n      version: v1.7.6\n```\nAfter that you can declare either the whole configuration at once in the middleware block or by service. See the examples below.\n```yaml\n# anywhere/dynamic-configuration\nhttp:\n  routers:\n    whoami:\n      middlewares:\n        - http-cache\n      service: whoami\n      rule: Host(`domain.com`)\n  middlewares:\n    http-cache:\n      plugin:\n        souin:\n          api:\n            prometheus: {}\n            souin: {}\n          default_cache:\n            regex:\n              exclude: '/test_exclude.*'\n            ttl: 5s\n            allowed_http_verbs:\n              - GET\n              - HEAD\n              - POST\n            allowed_additional_status_codes:\n              - 202\n              - 400\n            default_cache_control: no-store\n          log_level: debug\n          urls:\n            'domain.com/testing':\n              ttl: 5s\n            'mysubdomain.domain.com':\n              ttl: 50s\n              default_cache_control: public, max-age=86400\n          ykeys:\n            The_First_Test:\n              headers:\n                Content-Type: '.+'\n            The_Second_Test:\n              url: 'the/second/.+'\n            The_Third_Test:\n            The_Fourth_Test:\n          surrogate_keys:\n            The_First_Test:\n              headers:\n                Content-Type: '.+'\n            The_Second_Test:\n              url: 'the/second/.+'\n            The_Third_Test:\n            The_Fourth_Test:\n```\n\n```yaml\n# anywhere/docker-compose.yml\nservices:\n#...\n  whoami:\n    image: traefik/whoami\n    labels:\n      # other labels...\n      - traefik.http.routers.whoami.middlewares=http-cache\n      - traefik.http.middlewares.http-cache.plugin.souin.api.souin\n      - traefik.http.middlewares.http-cache.plugin.souin.default_cache.ttl=10s\n      - traefik.http.middlewares.http-cache.plugin.souin.default_cache.allowed_http_verbs=GET,HEAD,POST\n      - traefik.http.middlewares.http-cache.plugin.souin.log_level=debug\n```\n\n### Tyk plugin\nTo use Souin as a Tyk plugin, you can refer to the [Tyk plugin integration folder](https://github.com/darkweak/souin/tree/master/plugins/tyk) to discover how to configure it.  \nYou have to define the use of Souin as `post` and `response` custom middleware. You can compile your own Souin integration using the `Makefile` and the `docker-compose` inside the [tyk integration directory](https://github.com/darkweak/souin/tree/master/plugins/tyk) and place your generated `souin-plugin.so` file inside your `middleware` directory.\n```json\n{\n  \"name\":\"httpbin.org\",\n  \"api_id\":\"3\",\n  \"org_id\":\"3\",\n  \"use_keyless\": true,\n  \"version_data\": {\n    \"not_versioned\": true,\n    \"versions\": {\n      \"Default\": {\n        \"name\": \"Default\",\n        \"use_extended_paths\": true\n      }\n    }\n  },\n  \"custom_middleware\": {\n    \"pre\": [],\n    \"post\": [\n      {\n        \"name\": \"SouinRequestHandler\",\n        \"path\": \"/opt/tyk-gateway/middleware/souin-plugin.so\"\n      }\n    ],\n    \"post_key_auth\": [],\n    \"auth_check\": {\n      \"name\": \"\",\n      \"path\": \"\",\n      \"require_session\": false\n    },\n    \"response\": [\n      {\n        \"name\": \"SouinResponseHandler\",\n        \"path\": \"/opt/tyk-gateway/middleware/souin-plugin.so\"\n      }\n    ],\n    \"driver\": \"goplugin\",\n    \"id_extractor\": {\n      \"extract_from\": \"\",\n      \"extract_with\": \"\",\n      \"extractor_config\": {}\n    }\n  },\n  \"proxy\":{\n    \"listen_path\":\"/httpbin/\",\n    \"target_url\":\"http://httpbin.org/\",\n    \"strip_listen_path\":true\n  },\n  \"active\":true,\n  \"config_data\": {\n    \"httpcache\": {\n      \"api\": {\n        \"souin\": {\n          \"enable\": true\n        }\n      },\n      \"cdn\": {\n        \"api_key\": \"XXXX\",\n        \"provider\": \"fastly\",\n        \"strategy\": \"soft\"\n      },\n      \"default_cache\": {\n        \"ttl\": \"5s\"\n      }\n    }\n  }\n}\n```\n\n### Webgo middleware\nTo use Souin as webgo middleware, you can refer to the [Webgo middleware integration folder](https://github.com/darkweak/souin/tree/master/plugins/webgo) to discover how to configure it.  \nYou just have to define a new webgo router and tell to the instance to use the process method like below:\n```go\nimport (\n\t\"net/http\"\n\n\t\"github.com/bnkamalesh/webgo/v6\"\n\tcache \"github.com/darkweak/souin/plugins/webgo\"\n)\n\nfunc main(){\n\n    // ...\n\thttpcache := cache.NewHTTPCache(cache.DevDefaultConfiguration)\n\trouter.Use(httpcache.Middleware)\n    // ...\n\n}\n```\n\n## Credits\n\nThanks to these users for contributing or helping this project in any way  \n* [Oxodao](https://github.com/oxodao)\n* [Deuchnord](https://github.com/deuchnord)\n* [Vincent Jordan](https://github.com/vejipe)\n* [Mohammed Al Sahaf](https://github.com/mohammed90)\n* [Hussam Almarzooq](https://github.com/hussam-almarzoq)\n* [Sata51](https://github.com/sata51)\n* [Pierre Diancourt](https://github.com/pierrediancourt)\n* [Burak Sezer](https://github.com/buraksezer)\n* [Luc Michalski](https://github.com/lucmichalski)\n* [Jenaye](https://github.com/jenaye)\n* [Brennan Kinney](https://github.com/polarathene)\n* [Agneev](https://github.com/agneevX)\n* [Eidenschink](https://github.com/eidenschink/)\n* [Massimiliano Cannarozzo](https://github.com/maxcanna/)\n* [Kevin Pollet](https://github.com/kevinpollet)\n* [Choelzl](https://github.com/choelzl)\n* [Menci](https://github.com/menci)\n* [Duy Nguyen](https://github.com/duy-nguyen-devops)\n* [Kiss Karoly](https://github.com/kresike)\n* [Matthias von Bargen](https://github.com/mattvb91)\n* [Fred Liang](https://github.com/fredliang44)\n* [Kiril Vladimirov](https://github.com/vladimiroff)\n* [Viktor Szépe](https://github.com/szepeviktor)\n* [Omar Ramadan](https://github.com/kkroo)\n* [Jonasengelmann](https://github.com/jonasengelmann)\n* [JacquesDurand](https://github.com/jacquesdurand)\n* [Frederic Houle](https://github.com/frederichoule)\n* [Valery Piashchynski](https://github.com/rustatian)\n* [Ivan Derda](https://github.com/HobMartin)\n* [p0358](https://github.com/p0358)\n* [Alberto Tablado](https://github.com/aluki)\n* [Yong Zhang](https://github.com/yongzhang)\n","funding_links":[],"categories":["Go","Uncategorized","⚙️ Middlewares"],"sub_categories":["Uncategorized","🌱 Third Party"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkweak%2Fsouin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarkweak%2Fsouin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkweak%2Fsouin/lists"}