{"status_code":200,"result":{"structure":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"ModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.\n","module_namespace":"http.matchers"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nRawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"namespaces":{"":[{"name":"exec","docs":"exec is top level module that runs shell commands.","package":"github.com/abiosoft/caddy-exec","repo":"https://github.com/abiosoft/caddy-exec"},{"name":"reconnect","docs":"reconnect is a module that provides an additional \"reconnect\" network type\nthat can be used to reconnect to a [network address] if the initial\nconnection fails. Caddy will bind to the address as soon as it is available.\nUntil that point, the listener will block in the Accept() loop. This is\nuseful if you want to configure Caddy to bind on an address that is\npotentially not available at startup time.\n\nYou can configure the following networks:\n- reconnect+tcp\n- reconnect+tcp4\n- reconnect+tcp6\n- reconnect+udp\n- reconnect+udp4\n- reconnect+udp6\n\nThese are equivalent to the standard networks, except that they will block\nuntil the address is available.\n\nFor example, to start Caddy as an http server on 192.168.1.2:443, even if\nthat address is not available at startup time, you can add the following\nlistener to the [apps.http.servers.{srv}.listen] list:\n\n\t\"listen\": [\"reconnect+tcp/192.168.1.2:443\"]\n\nNote: This module has only been tested with Linux. Other operating systems\nmight not work as intended.\n\n[apps.http.servers.{srv}.listen]: https://caddyserver.com/docs/json/apps/http/servers/listen/\n[network address]: https://caddyserver.com/docs/conventions#network-addresses","package":"github.com/anapaya/caddy-reconnect","repo":"https://github.com/anapaya/caddy-reconnect"},{"name":"supervisor","package":"github.com/baldinof/caddy-supervisor","repo":"https://github.com/baldinof/caddy-supervisor"},{"name":"events","docs":"events implements a global eventing system within Caddy.\nModules can emit and subscribe to events, providing\nhooks into deep parts of the code base that aren't\notherwise accessible. Events provide information about\nwhat and when things are happening, and this facility\nallows handlers to take action when events occur,\nadd information to the event's metadata, and even\ncontrol program flow in some cases.\n\nEvents are propagated in a DOM-like fashion. An event\nemitted from module `a.b.c` (the \"origin\") will first\ninvoke handlers listening to `a.b.c`, then `a.b`,\nthen `a`, then those listening regardless of origin.\nIf a handler returns the special error Aborted, then\npropagation immediately stops and the event is marked\nas aborted. Emitters may optionally choose to adjust\nprogram flow based on an abort.\n\nModules can subscribe to events by origin and/or name.\nA handler is invoked only if it is subscribed to the\nevent by name and origin. Subscriptions should be\nregistered during the provisioning phase, before apps\nare started.\n\nEvent handlers are fired synchronously as part of the\nregular flow of the program. This allows event handlers\nto control the flow of the program if the origin permits\nit and also allows handlers to convey new information\nback into the origin module before it continues.\nIn essence, event handlers are similar to HTTP\nmiddleware handlers.\n\nEvent bindings/subscribers are unordered; i.e.\nevent handlers are invoked in an arbitrary order.\nEvent handlers should not rely on the logic of other\nhandlers to succeed.\n\nThe entirety of this app module is EXPERIMENTAL and\nsubject to change. Pay attention to release notes.","package":"github.com/caddyserver/caddy/v2/modules/caddyevents","repo":"https://github.com/caddyserver/caddy"},{"name":"http","docs":"http is a robust, production-ready HTTP server.\n\nHTTPS is enabled by default if host matchers with qualifying names are used\nin any of routes; certificates are automatically provisioned and renewed.\nAdditionally, automatic HTTPS will also enable HTTPS for servers that listen\nonly on the HTTPS port but which do not have any TLS connection policies\ndefined by adding a good, default TLS connection policy.\n\nIn HTTP routes, additional placeholders are available (replace any `*`):\n\nPlaceholder | Description\n------------|---------------\n`{http.request.body}` | The request body (⚠️ inefficient; use only for debugging)\n`{http.request.cookie.*}` | HTTP request cookie\n`{http.request.duration}` | Time up to now spent handling the request (after decoding headers from client)\n`{http.request.duration_ms}` | Same as 'duration', but in milliseconds.\n`{http.request.uuid}` | The request unique identifier\n`{http.request.header.*}` | Specific request header field\n`{http.request.host}` | The host part of the request's Host header\n`{http.request.host.labels.*}` | Request host labels (0-based from right); e.g. for foo.example.com: 0=com, 1=example, 2=foo\n`{http.request.hostport}` | The host and port from the request's Host header\n`{http.request.method}` | The request method\n`{http.request.orig_method}` | The request's original method\n`{http.request.orig_uri}` | The request's original URI\n`{http.request.orig_uri.path}` | The request's original path\n`{http.request.orig_uri.path.*}` | Parts of the original path, split by `/` (0-based from left)\n`{http.request.orig_uri.path.dir}` | The request's original directory\n`{http.request.orig_uri.path.file}` | The request's original filename\n`{http.request.orig_uri.query}` | The request's original query string (without `?`)\n`{http.request.port}` | The port part of the request's Host header\n`{http.request.proto}` | The protocol of the request\n`{http.request.local.host}` | The host (IP) part of the local address the connection arrived on\n`{http.request.local.port}` | The port part of the local address the connection arrived on\n`{http.request.local}` | The local address the connection arrived on\n`{http.request.remote.host}` | The host (IP) part of the remote client's address\n`{http.request.remote.port}` | The port part of the remote client's address\n`{http.request.remote}` | The address of the remote client\n`{http.request.scheme}` | The request scheme, typically `http` or `https`\n`{http.request.tls.version}` | The TLS version name\n`{http.request.tls.cipher_suite}` | The TLS cipher suite\n`{http.request.tls.resumed}` | The TLS connection resumed a previous connection\n`{http.request.tls.proto}` | The negotiated next protocol\n`{http.request.tls.proto_mutual}` | The negotiated next protocol was advertised by the server\n`{http.request.tls.server_name}` | The server name requested by the client, if any\n`{http.request.tls.client.fingerprint}` | The SHA256 checksum of the client certificate\n`{http.request.tls.client.public_key}` | The public key of the client certificate.\n`{http.request.tls.client.public_key_sha256}` | The SHA256 checksum of the client's public key.\n`{http.request.tls.client.certificate_pem}` | The PEM-encoded value of the certificate.\n`{http.request.tls.client.certificate_der_base64}` | The base64-encoded value of the certificate.\n`{http.request.tls.client.issuer}` | The issuer DN of the client certificate\n`{http.request.tls.client.serial}` | The serial number of the client certificate\n`{http.request.tls.client.subject}` | The subject DN of the client certificate\n`{http.request.tls.client.san.dns_names.*}` | SAN DNS names(index optional)\n`{http.request.tls.client.san.emails.*}` | SAN email addresses (index optional)\n`{http.request.tls.client.san.ips.*}` | SAN IP addresses (index optional)\n`{http.request.tls.client.san.uris.*}` | SAN URIs (index optional)\n`{http.request.uri}` | The full request URI\n`{http.request.uri.path}` | The path component of the request URI\n`{http.request.uri.path.*}` | Parts of the path, split by `/` (0-based from left)\n`{http.request.uri.path.dir}` | The directory, excluding leaf filename\n`{http.request.uri.path.file}` | The filename of the path, excluding directory\n`{http.request.uri.query}` | The query string (without `?`)\n`{http.request.uri.query.*}` | Individual query string value\n`{http.response.header.*}` | Specific response header field\n`{http.vars.*}` | Custom variables in the HTTP handler chain\n`{http.shutting_down}` | True if the HTTP app is shutting down\n`{http.time_until_shutdown}` | Time until HTTP server shutdown, if scheduled","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"pki","docs":"pki provides Public Key Infrastructure facilities for Caddy.\n\nThis app can define certificate authorities (CAs) which are capable\nof signing certificates. Other modules can be configured to use\nthe CAs defined by this app for issuing certificates or getting\nkey information needed for establishing trust.","package":"github.com/caddyserver/caddy/v2/modules/caddypki","repo":"https://github.com/caddyserver/caddy"},{"name":"tls","docs":"tls provides TLS facilities including certificate\nloading and management, client auth, and more.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"frankenphp","package":"github.com/dunglas/frankenphp/caddy","repo":"https://github.com/dunglas/frankenphp"},{"name":"security","docs":"security implements security manager.","package":"github.com/greenpau/caddy-security","repo":"https://github.com/greenpau/caddy-security"},{"name":"crowdsec","docs":"crowdsec is a Caddy App that functions as a CrowdSec bouncer. It acts\nas a CrowdSec API client as well as a local cache for CrowdSec decisions,\nwhich can be used by the HTTP handler and Layer4 matcher to decide if\na request or connection is allowed or not.","package":"github.com/hslatman/caddy-crowdsec-bouncer/crowdsec","repo":"https://github.com/hslatman/caddy-crowdsec-bouncer"},{"name":"ssh","docs":"ssh is the app providing ssh services","package":"github.com/kadeessh/kadeessh/internal","repo":"https://github.com/kadeessh/kadeessh"},{"name":"dns01proxy","docs":"A proxy server for ACME DNS-01 challenges. Designed to work with acme.sh's\n`acmeproxy`, lego's `httpreq`, and Caddy's `acmeproxy` DNS providers.\n\nThis is a Caddy application module.","package":"github.com/liujed/caddy-dns01proxy","repo":"https://github.com/liujed/caddy-dns01proxy"},{"name":"cname_sync","docs":"cname_sync reconciles DNS CNAME records for HTTP routes in a given zone.","package":"github.com/luishfonseca/caddy-cname-sync","repo":"https://github.com/luishfonseca/caddy-cname-sync"},{"name":"dynamic_dns","docs":"dynamic_dns is a Caddy app that keeps your DNS records updated with the public\nIP address of your instance. It updates A and AAAA records.","package":"github.com/mholt/caddy-dynamicdns","repo":"https://github.com/mholt/caddy-dynamicdns"},{"name":"layer4","docs":"layer4 is a Caddy app that operates closest to layer 4 of the OSI model.","package":"github.com/mholt/caddy-l4/layer4","repo":"https://github.com/mholt/caddy-l4"},{"name":"pocketbase","docs":"pocketbase is a Caddy module that provides an embedded PocketBase server.\n\nThe module provides admin API endpoints under `/pocketbase/`:\n\n- `POST /pocketbase/superuser` - Create a new superuser\n- `PUT /pocketbase/superuser` - Upsert a superuser\n- `PATCH /pocketbase/superuser` - Update superuser password\n- `DELETE /pocketbase/superuser` - Delete a superuser\n- `POST /pocketbase/superuser/{email}/otp` - Generate OTP for superuser\n\nAll the above endpoints require a JSON payload, except for the OTP endpoint. The\nJSON payload for the superuser endpoints is as follows:\n\n\t{\n\t\t\"email_address\": \"...\",\n\t\t\"password\": \"...\"\n\t}\n\nThe `DELETE` endpoint does not expect the `password` field.\n\nAlthough PocketBase prints a URL in the logs to create the first superuser, the host\npart of the URL is not correct. You can either replace the host part with the host defined in\nyour Caddy configuration, or use the admin API endpoint to create the first superuser.\n\nThe app can be configured in the Caddyfile through the `pocketbase` block in the global options section. Syntax:\n\n\tpocketbase {\n\t    data_dir \u003cpath\u003e\n\t    listen   \u003caddr\u003e\n\t    origins  \u003corigin...\u003e\n\t}\n\nIf the block is omitted, the default values are used.","package":"github.com/mohammed90/caddy-pocketbase","repo":"https://github.com/mohammed90/caddy-pocketbase"},{"name":"ssh","docs":"ssh is the app providing ssh services","package":"github.com/mohammed90/caddy-ssh/internal","repo":"https://github.com/mohammed90/caddy-ssh"},{"name":"profefe","docs":"The `profefe` app collects profiling data during the life-time of the process\nand uploads them to the profefe server.","package":"github.com/mohammed90/caddy_profiling/profefe","repo":"https://github.com/mohammed90/caddy_profiling"},{"name":"profiling","docs":"The `profiling` app hosts the collection of push-based profiling agents with common profiling parameters acorss the Caddy instance.","package":"github.com/mohammed90/caddy_profiling/profiling","repo":"https://github.com/mohammed90/caddy_profiling"},{"name":"pyroscope","docs":"The `pyroscope` app collects profiling data during the life-time of the process\nand uploads them to the Pyroscope server.","package":"github.com/mohammed90/caddy_profiling/pyroscope","repo":"https://github.com/mohammed90/caddy_profiling"},{"name":"scion","docs":"scion implements a caddy module. Currently, it is used to initialize the\nlogger for the global network. In the future, additional configuration can be\nparsed with this component.","package":"github.com/scionproto-contrib/caddy-scion","repo":"https://github.com/scionproto-contrib/caddy-scion"},{"name":"rift","docs":"rift is the rift Caddy app that runs a QUIC listener for tunnel clients.","package":"github.com/venkatkrishna07/caddy-rift","repo":"https://github.com/venkatkrishna07/caddy-rift"},{"name":"geoip2","docs":"geoip2 is global caddy app with http.handlers.geoip2\nit update geoip2 data automatically by the params","package":"github.com/zhangjiayin/caddy-geoip2","repo":"https://github.com/zhangjiayin/caddy-geoip2"}],"caddy.config_loaders":[{"name":"http","docs":"http can load Caddy configs over HTTP(S).\n\nIf the response is not a JSON config, a config adapter must be specified\neither in the loader config (`adapter`), or in the Content-Type HTTP header\nreturned in the HTTP response from the server. The Content-Type header is\nread just like the admin API's `/load` endpoint. If you don't have control\nover the HTTP server (but can still trust its response), you can override\nthe Content-Type header by setting the `adapter` property in this config.","package":"github.com/caddyserver/caddy/v2/caddyconfig","repo":"https://github.com/caddyserver/caddy"},{"name":"storage","docs":"storage is a dynamic configuration loader that reads the configuration from a Caddy storage. If\nthe storage is not configured, the default storage is used, which may be the file-system if none is configured\nIf the `key` is not configured, the default key is `config/caddy.json`.","package":"github.com/mohammed90/caddy-storage-loader","repo":"https://github.com/mohammed90/caddy-storage-loader"}],"caddy.listeners":[{"name":"http_redirect","docs":"http_redirect provides HTTP-\u003eHTTPS redirects for\nconnections that come on the TLS port as an HTTP request,\nby detecting using the first few bytes that it's not a TLS\nhandshake, but instead an HTTP request.\n\nThis is especially useful when using a non-standard HTTPS port.\nA user may simply type the address in their browser without the\nhttps:// scheme, which would cause the browser to attempt the\nconnection over HTTP, but this would cause a \"Client sent an\nHTTP request to an HTTPS server\" error response.\n\nThis listener wrapper must be placed BEFORE the \"tls\" listener\nwrapper, for it to work properly.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"tls","docs":"tls is a no-op listener wrapper that marks\nwhere the TLS listener should be in a chain of listener wrappers.\nIt should only be used if another listener wrapper must be placed\nin front of the TLS handshake.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"proxy_protocol","docs":"proxy_protocol provides PROXY protocol support to Caddy by implementing\nthe caddy.ListenerWrapper interface. If a connection is received via Unix\nsocket, it's trusted. Otherwise, it's checked against the Allow/Deny lists,\nthen it's handled by the FallbackPolicy.\n\nIt must be loaded before the `tls` listener because the PROXY protocol\nencapsulates the TLS data.\n\nCredit goes to https://github.com/mastercactapus/caddy2-proxyprotocol for having\ninitially implemented this as a plugin.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/proxyprotocol","repo":"https://github.com/caddyserver/caddy"},{"name":"trojan","docs":"trojan implements an TLS wrapper that it accept connections\nfrom clients and check the connection with pre-defined password\nand aead cipher defined by go-shadowsocks2, and return a normal page if\nfailed.","package":"github.com/imgk/caddy-trojan/listener","repo":"https://github.com/imgk/caddy-trojan"},{"name":"proxy_protocol","package":"github.com/mastercactapus/caddy2-proxyprotocol","repo":"https://github.com/mastercactapus/caddy2-proxyprotocol"},{"name":"ngrok","docs":"ngrok is a `listener_wrapper` whose address is an ngrok-ingress address","package":"github.com/mohammed90/caddy-ngrok-listener","repo":"https://github.com/mohammed90/caddy-ngrok-listener"},{"name":"throttle","docs":"The `throttle` listener limits the bandwidth of the connection to the\ngiven values and can inject chaos engineering features like latency and jitter.","package":"github.com/mohammed90/caddy-throttle-listener","repo":"https://github.com/mohammed90/caddy-throttle-listener"}],"caddy.logging.encoders":[{"name":"append","docs":"append can be used to add fields to all log entries\nthat pass through it. It is a wrapper around another\nencoder, which it uses to actually encode the log entries.\nIt is most useful for adding information about the Caddy\ninstance that is producing the log entries, possibly via\nan environment variable.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"console","docs":"console encodes log entries that are mostly human-readable.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"filter","docs":"filter can filter (manipulate) fields on\nlog entries before they are actually encoded by\nan underlying encoder.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"json","docs":"json encodes entries as JSON.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"logfmt","docs":"logfmt encodes log entries as logfmt:\nhttps://www.brandur.org/logfmt\n\nNote that logfmt does not encode nested structures\nproperly, so it is not a good fit for most logs.\n\n⚠️ DEPRECATED. Do not use. It will eventually be removed\nfrom the standard Caddy modules. For more information,\nsee https://github.com/caddyserver/caddy/issues/3575.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"single_field","docs":"single_field writes a log entry that consists entirely\nof a single string field in the log entry. This is useful\nfor custom, self-encoded log entries that consist of a\nsingle field in the structured log entry.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"formatted","docs":"formatted allows the user to provide custom template for log prints. The\nencoder builds atop the json encoder, thus it follows its message structure. The placeholders\nare namespaced by the name of the app logging the message.","package":"github.com/caddyserver/format-encoder","repo":"https://github.com/caddyserver/format-encoder"},{"name":"transform","docs":"transform allows the user to provide custom template for log prints. The\nencoder builds atop the json encoder, thus it follows its message structure. The placeholders\nare namespaced by the name of the app logging the message.","package":"github.com/caddyserver/transform-encoder","repo":"https://github.com/caddyserver/transform-encoder"},{"name":"formatted","package":"github.com/caddyserver/transform-encoder","repo":"https://github.com/caddyserver/transform-encoder"},{"name":"elastic","package":"github.com/firecow/caddy-elastic-encoder","repo":"https://github.com/firecow/caddy-elastic-encoder"}],"caddy.logging.writers":[{"name":"discard","docs":"discard discards all writes.","package":"github.com/caddyserver/caddy/v2","repo":"https://github.com/caddyserver/caddy"},{"name":"stderr","docs":"stderr writes logs to standard error.","package":"github.com/caddyserver/caddy/v2","repo":"https://github.com/caddyserver/caddy"},{"name":"stdout","docs":"stdout writes logs to standard out.","package":"github.com/caddyserver/caddy/v2","repo":"https://github.com/caddyserver/caddy"},{"name":"file","docs":"file can write logs to files. By default, log files\nare rotated (\"rolled\") when they get large, and old log\nfiles get deleted, to ensure that the process does not\nexhaust disk space.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"net","docs":"net implements a log writer that outputs to a network socket. If\nthe socket goes down, it will dump logs to stderr while it attempts to\nreconnect.","package":"github.com/caddyserver/caddy/v2/modules/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"influx_log","package":"github.com/neodyme-labs/influx_log","repo":"https://github.com/neodyme-labs/influx_log"},{"name":"influxlog","docs":"influxlog is a influxdb client to write time series data","package":"github.com/sillygod/cdp-cache/extends/influxlog","repo":"https://github.com/sillygod/cdp-cache"},{"name":"graphite","docs":"graphite is a Caddy logger used to send server activity to a Graphite\ndatabase.\n\nTemplating is available as follow :\n\n\t.Level\n\t.Date\n\t.Logger\n\t.Msg\n\t.Request\n\t\t.RemoteIP\n\t\t.RemotePort\n\t\t.ClientIP\n\t\t.Proto\n\t\t.Method\n\t\t.Host\n\t\t.URI\n\t\t.Headers\n\t.BytesRead\n\t.UserID\n\t.Duration\n\t.Size\n\t.Status\n\t.RespHeaders map[string][]string\n\n\t.DirName\n\t.FileName","package":"github.com/ybizeul/caddy-logger-graphite","repo":"https://github.com/ybizeul/caddy-logger-graphite"}],"caddy.storage":[{"name":"enzonix_kv","docs":"enzonix_kv implements a Caddy storage backend using the kv-database HTTP API.","package":"github.com/Enzonix-LLC/kv-caddy","repo":"https://github.com/Enzonix-LLC/kv-caddy"},{"name":"nats","package":"github.com/HeavyHorst/certmagic-nats","repo":"https://github.com/HeavyHorst/certmagic-nats"},{"name":"file_system","docs":"file_system is a certmagic.Storage wrapper for certmagic.FileStorage.","package":"github.com/caddyserver/caddy/v2/modules/filestorage","repo":"https://github.com/caddyserver/caddy"},{"name":"redis","docs":"redis contain Redis client, and plugin option","package":"github.com/gamalan/caddy-tlsredis","repo":"https://github.com/gamalan/caddy-tlsredis"},{"name":"vault","docs":"A highly available storage module that integrates with HashiCorp Vault.","package":"github.com/gerolf-vent/caddy-vault-storage","repo":"https://github.com/gerolf-vent/caddy-vault-storage"},{"name":"gcs","docs":"gcs implements a caddy storage backend for Google Cloud Storage.","package":"github.com/grafana/certmagic-gcs","repo":"https://github.com/grafana/certmagic-gcs"},{"name":"cloudflare_kv","docs":"cloudflare_kv implements a Caddy storage backend for Cloudflare KV","package":"github.com/mentimeter/caddy-storage-cf-kv","repo":"https://github.com/mentimeter/caddy-storage-cf-kv"},{"name":"encrypted","docs":"encrypted is the impelementation of certmagic.Storage interface for Caddy with encryption/decryption layer\nusing [SOPS](https://github.com/getsops/sops). The module accepts any Caddy storage module as the backend.","package":"github.com/mohammed90/caddy-encrypted-storage","repo":"https://github.com/mohammed90/caddy-encrypted-storage"},{"name":"redis","docs":"redis implements a Caddy storage backend for Redis\nIt supports Single (Standalone), Cluster, or Sentinel (Failover) Redis server configurations.","package":"github.com/pberkel/caddy-storage-redis","repo":"https://github.com/pberkel/caddy-storage-redis"},{"name":"consul","docs":"consul allows to store certificates and other TLS resources\nin a shared cluster environment using Consul's key/value-store.\nIt uses distributed locks to ensure consistency.","package":"github.com/pteich/caddy-tlsconsul","repo":"https://github.com/pteich/caddy-tlsconsul"},{"name":"consul","docs":"consul holds all parameters for the Consul connection","package":"github.com/pteich/caddy-tlsconsul","repo":"https://github.com/pteich/caddy-tlsconsul"},{"name":"dynamodb","docs":"dynamodb implements certmagic.Storage to facilitate\nstorage of certificates in DynamoDB for a clustered environment.\nAlso implements certmagic.Locker to facilitate locking\nand unlocking of cert data during storage","package":"github.com/sil-org/certmagic-storage-dynamodb/v3","repo":"https://github.com/sil-org/certmagic-storage-dynamodb"},{"name":"dynamodb","docs":"dynamodb implements certmagic.Storage to facilitate\nstorage of certificates in DynamoDB for a clustered environment.\nAlso implements certmagic.Locker to facilitate locking\nand unlocking of cert data during storage","package":"github.com/silinternational/certmagic-storage-dynamodb/v2","repo":"https://github.com/silinternational/certmagic-storage-dynamodb"},{"name":"dynamodb","docs":"dynamodb implements certmagic.Storage to facilitate\nstorage of certificates in DynamoDB for a clustered environment.\nAlso implements certmagic.Locker to facilitate locking\nand unlocking of cert data during storage","package":"github.com/silinternational/certmagic-storage-dynamodb/v3","repo":"https://github.com/silinternational/certmagic-storage-dynamodb"},{"name":"consul","docs":"consul implements the certmagic storage's interface\nThis holds the consul client and kv store","package":"github.com/sillygod/cdp-cache/extends/storage","repo":"https://github.com/sillygod/cdp-cache"},{"name":"s3","package":"github.com/ss098/certmagic-s3","repo":"https://github.com/ss098/certmagic-s3"},{"name":"redis","package":"github.com/techio-dev/caddy-redis","repo":"https://github.com/techio-dev/caddy-redis"},{"name":"env_redis","package":"github.com/techio-dev/caddy-redis/storage","repo":"https://github.com/techio-dev/caddy-redis"},{"name":"s3","package":"github.com/techknowlogick/certmagic-s3","repo":"https://github.com/techknowlogick/certmagic-s3"},{"name":"postgres","package":"github.com/yroc92/postgres-storage","repo":"https://github.com/yroc92/postgres-storage"},{"name":"mysql","package":"github.com/zhangjiayin/caddy-mysql-storage","repo":"https://github.com/zhangjiayin/caddy-mysql-storage"}],"http.handlers":[{"name":"x_clacks_overhead","package":"git.madhouse-project.org/algernon/caddy-x-clacks-overhead","repo":"https://git.madhouse-project.org/algernon/caddy-x-clacks-overhead.git"},{"name":"sentry","docs":"sentry — це middleware для Caddy, що обгортає Sentry HTTP handler","package":"github.com/APKO/sentry-caddy","repo":"https://github.com/APKO/sentry-caddy"},{"name":"sqlite_router","package":"github.com/AnswerDotAI/caddy-sqlite-router","repo":"https://github.com/AnswerDotAI/caddy-sqlite-router"},{"name":"myplugin","package":"github.com/Boomchainlab/vite-react-template/caddy-plugin","repo":"https://github.com/Boomchainlab/vite-react-template"},{"name":"waf","package":"github.com/BraveRoy/caddy-waf","repo":"https://github.com/BraveRoy/caddy-waf"},{"name":"authelia","docs":"authelia implements a plugin for securing routes with authentication","package":"github.com/HeavenVolkoff/caddy-authelia/plugin","repo":"https://github.com/HeavenVolkoff/caddy-authelia"},{"name":"listencaddy","docs":"listencaddy is a Caddy http.handlers module that listens for requests to specific URIs/paths and reports IPs that hit these URIs to AbuseIPDB.","package":"github.com/Odyssey346/ListenCaddy","repo":"https://github.com/Odyssey346/ListenCaddy"},{"name":"pixbooster","package":"github.com/PixyBlue/caddy-pixbooster","repo":"https://github.com/PixyBlue/caddy-pixbooster"},{"name":"rate_limit","docs":"rate_limit implements a handler for rate-limiting.\n\nIf a client exceeds the rate limit, an HTTP error with status `\u003creject_status\u003e` will\nbe returned. This error can be handled using the conventional error handlers.\nSee [handle_errors](https://caddyserver.com/docs/caddyfile/directives/handle_errors)\nfor how to set up error handlers.","package":"github.com/RussellLuo/caddy-ext/ratelimit","repo":"https://github.com/RussellLuo/caddy-ext"},{"name":"request_body_var","docs":"request_body_var implements an HTTP handler that replaces {http.request.body.*}\nwith the value of the given field from request body, if any.","package":"github.com/RussellLuo/caddy-ext/requestbodyvar","repo":"https://github.com/RussellLuo/caddy-ext"},{"name":"olaf","docs":"olaf implements a handler that embeds Olaf's declarative configuration, which\nwill be expanded later by a config adapter named `olaf`.","package":"github.com/RussellLuo/olaf/caddymodule","repo":"https://github.com/RussellLuo/olaf"},{"name":"save","package":"github.com/Scarsz/caddy-save","repo":"https://github.com/Scarsz/caddy-save"},{"name":"jailbait","package":"github.com/Tasudo/caddy-jailbait/v2","repo":"https://github.com/Tasudo/caddy-jailbait"},{"name":"waf_chaitin","docs":"waf_chaitin implements an HTTP handler for WAF.","package":"github.com/W0n9/caddy_waf_t1k","repo":"https://github.com/W0n9/caddy_waf_t1k"},{"name":"wafris","docs":"Wafris, a free, open source WAF (web application firewall)","package":"github.com/Wafris/wafris-caddy","repo":"https://github.com/Wafris/wafris-caddy"},{"name":"webhook","docs":"webhook is the module configuration.","package":"github.com/WingLim/caddy-webhook","repo":"https://github.com/WingLim/caddy-webhook"},{"name":"exec","docs":"exec implements an HTTP handler that runs shell command.","package":"github.com/abiosoft/caddy-exec","repo":"https://github.com/abiosoft/caddy-exec"},{"name":"hmac","docs":"hmac implements an HTTP handler that\nvalidates request body with hmac.","package":"github.com/abiosoft/caddy-hmac","repo":"https://github.com/abiosoft/caddy-hmac"},{"name":"inspect","docs":"inspect implements an HTTP handler that writes the\ninspects the current request.","package":"github.com/abiosoft/caddy-inspect","repo":"https://github.com/abiosoft/caddy-inspect"},{"name":"json_parse","docs":"json_parse implements an HTTP handler that parses\njson body as placeholders.","package":"github.com/abiosoft/caddy-json-parse","repo":"https://github.com/abiosoft/caddy-json-parse"},{"name":"sablier","package":"github.com/acouvreur/sablier/plugins/caddy","repo":"https://github.com/acouvreur/sablier"},{"name":"cgi","package":"github.com/aksdb/caddy-cgi/v2","repo":"https://github.com/aksdb/caddy-cgi"},{"name":"dnsfetcher","package":"github.com/anthemaker/caddy-dns-fetcher","repo":"https://github.com/anthemaker/caddy-dns-fetcher"},{"name":"ipgate_trigger","docs":"ipgate_trigger is an HTTP handler that watches upstream responses and whitelists\nthe client IP when a response matches the configured path and status code.\nThis enables IP-based access gating after a successful authentication flow.\n\nWhen placed on an authentication endpoint, it intercepts the response and\nif the path and status code match, the client's IP is added to a shared\nin-memory whitelist for the configured TTL. Other site blocks can then use\nthe ipgate matcher to allow or deny requests based on whitelist membership.\n\nThe module is auth-provider agnostic. Configure match_path and match_status\nto match any provider's successful authentication response.\n\nCaddyfile syntax:\n\n\tipgate_trigger {\n\t    match_path   \u003cpath\u003e\n\t    match_status \u003ccode\u003e\n\t    ttl          \u003cduration\u003e\n\t    sweep_interval \u003cduration\u003e\n\t}","package":"github.com/anujc4/caddy-dynamic-ip-whitelist","repo":"https://github.com/anujc4/caddy-dynamic-ip-whitelist"},{"name":"geoblock","docs":"geoblock implements geolocation-based request blocking for Caddy.\n\nIt looks up the client's IP address in MaxMind databases and blocks\nor allows requests based on geographic and network criteria.\n\nWhen a request is blocked, an HTTP error with status 403 (or configured status)\nis returned. This error can be handled using Caddy's error handling routes.\n\nThe handler sets various placeholders with geo information that can be used\nby downstream handlers:\n  - {geoblock.country_code}\n  - {geoblock.country_name}\n  - {geoblock.city_name}\n  - {geoblock.continent_code}\n  - {geoblock.subdivision_code}\n  - {geoblock.asn}\n  - {geoblock.asn_org}\n  - {geoblock.latitude}\n  - {geoblock.longitude}\n  - {geoblock.time_zone}\n  - {geoblock.postal_code}\n  - {geoblock.blocked}\n  - {geoblock.blocked_reason}","package":"github.com/anujc4/caddy-geoblock","repo":"https://github.com/anujc4/caddy-geoblock"},{"name":"redir_dns","docs":"redir_dns is a RedirDns for manipulating redirecting based on DNS TXT record.","package":"github.com/argami/redir-dns","repo":"https://github.com/argami/redir-dns"},{"name":"ldap_basic_auth","package":"github.com/bluewalk/caddy-ldap-basic-auth","repo":"https://github.com/bluewalk/caddy-ldap-basic-auth"},{"name":"oauth2_token_introspection","docs":"oauth2_token_introspection is a Caddy http.handlers Module for authorizing requests via OAuth2 Token Introspection","package":"github.com/bploetz/caddy-oauth2-token-introspection","repo":"https://github.com/bploetz/caddy-oauth2-token-introspection"},{"name":"cache","docs":"cache allows the user to set up an HTTP cache system,\nRFC-7234 compliant and supports the tag based cache purge,\ndistributed and not-distributed storage, key generation tweaking.","package":"github.com/caddyserver/cache-handler","repo":"https://github.com/caddyserver/cache-handler"},{"name":"cache","docs":"cache allows the user to set up an HTTP cache system,\nRFC-7234 compliant and supports the tag based cache purge,\ndistributed and not-distributed storage, key generation tweaking.","package":"github.com/caddyserver/cache-handler","repo":"https://github.com/caddyserver/cache-handler"},{"name":"invoke","docs":"invoke implements a handler that compiles and executes a\nnamed route that was defined on the server.\n\nEXPERIMENTAL: Subject to change or removal.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"error","docs":"error implements a simple handler that returns an error.\nThis handler returns an error value, but does not write a response.\nThis is useful when you want the server to act as if an error\noccurred; for example, to invoke your custom error handling logic.\n\nSince this handler does not write a response, the error information\nis for use by the server to know how to handle the error.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"static_response","docs":"static_response implements a simple responder for static responses.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"subroute","docs":"subroute implements a handler that compiles and executes routes.\nThis is useful for a batch of routes that all inherit the same\nmatchers, or for multiple routes that should be treated as a\nsingle route.\n\nYou can also use subroutes to handle errors from its handlers.\nFirst the primary routes will be executed, and if they return an\nerror, the errors routes will be executed; in that case, an error\nis only returned to the entry point at the server if there is an\nadditional error returned from the errors routes.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"vars","docs":"vars is an HTTP middleware which sets variables to\nhave values that can be used in the HTTP request handler\nchain. The primary way to access variables is with placeholders,\nwhich have the form: `{http.vars.variable_name}`, or with\nthe `vars` and `vars_regexp` request matchers.\n\nThe key is the variable name, and the value is the value of the\nvariable. Both the name and value may use or contain placeholders.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"authentication","docs":"authentication is a middleware which provides user authentication.\nRejects requests with HTTP 401 if the request is not authenticated.\n\nAfter a successful authentication, the placeholder\n`{http.auth.user.id}` will be set to the username, and also\n`{http.auth.user.*}` placeholders may be set for any authentication\nmodules that provide user metadata.\n\nIts API is still experimental and may be subject to change.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth","repo":"https://github.com/caddyserver/caddy"},{"name":"encode","docs":"encode is a middleware which can encode responses.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/encode","repo":"https://github.com/caddyserver/caddy"},{"name":"file_server","docs":"file_server implements a handler that serves static files.\n\nThe path of the file to serve is constructed by joining the site root\nand the sanitized request path. Any and all files within the root and\nlinks with targets outside the site root may therefore be accessed.\nFor example, with a site root of `/www`, requests to `/foo/bar.txt`\nwill serve the file at `/www/foo/bar.txt`.\n\nThe request path is sanitized using the Go standard library's\npath.Clean() function (https://pkg.go.dev/path#Clean) before being\njoined to the root. Request paths must be valid and well-formed.\n\nFor requests that access directories instead of regular files,\nCaddy will attempt to serve an index file if present. For example,\na request to `/dir/` will attempt to serve `/dir/index.html` if\nit exists. The index file names to try are configurable. If a\nrequested directory does not have an index file, Caddy writes a\n404 response. Alternatively, file browsing can be enabled with\nthe \"browse\" parameter which shows a list of files when directories\nare requested if no index file is present. If \"browse\" is enabled,\nCaddy may serve a JSON array of the directory listing when the `Accept`\nheader mentions `application/json` with the following structure:\n\n\t[{\n\t\t\"name\": \"\",\n\t\t\"size\": 0,\n\t\t\"url\": \"\",\n\t\t\"mod_time\": \"\",\n\t\t\"mode\": 0,\n\t\t\"is_dir\": false,\n\t\t\"is_symlink\": false\n\t}]\n\nwith the `url` being relative to the request path and `mod_time` in the RFC 3339 format\nwith sub-second precision. For any other value for the `Accept` header, the\nrespective browse template is executed with `Content-Type: text/html`.\n\nBy default, this handler will canonicalize URIs so that requests to\ndirectories end with a slash, but requests to regular files do not.\nThis is enforced with HTTP redirects automatically and can be disabled.\nCanonicalization redirects are not issued, however, if a URI rewrite\nmodified the last component of the path (the filename).\n\nThis handler sets the Etag and Last-Modified headers for static files.\nIt does not perform MIME sniffing to determine Content-Type based on\ncontents, but does use the extension (if known); see the Go docs for\ndetails: https://pkg.go.dev/mime#TypeByExtension\n\nThe file server properly handles requests with If-Match,\nIf-Unmodified-Since, If-Modified-Since, If-None-Match, Range, and\nIf-Range headers. It includes the file's modification time in the\nLast-Modified header of the response.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver","repo":"https://github.com/caddyserver/caddy"},{"name":"headers","docs":"headers is a middleware which modifies request and response headers.\n\nChanges to headers are applied immediately, except for the response\nheaders when Deferred is true or when Required is set. In those cases,\nthe changes are applied when the headers are written to the response.\nNote that deferred changes do not take effect if an error occurs later\nin the middleware chain.\n\nProperties in this module accept placeholders.\n\nResponse header operations can be conditioned upon response status code\nand/or other header values.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/headers","repo":"https://github.com/caddyserver/caddy"},{"name":"intercept","docs":"intercept is a middleware that intercepts then replaces or modifies the original response.\nIt can, for instance, be used to implement X-Sendfile/X-Accel-Redirect-like features\nwhen using modules like FrankenPHP or Caddy Snake.\n\nEXPERIMENTAL: Subject to change or removal.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/intercept","repo":"https://github.com/caddyserver/caddy"},{"name":"log_append","docs":"log_append implements a middleware that takes a key and value, where\nthe key is the name of a log field and the value is a placeholder,\nor variable key, or constant value to use for that field.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/logging","repo":"https://github.com/caddyserver/caddy"},{"name":"map","docs":"map implements a middleware that maps inputs to outputs. Specifically, it\ncompares a source value against the map inputs, and for one that matches, it\napplies the output values to each destination. Destinations become placeholder\nnames.\n\nMapped placeholders are not evaluated until they are used, so even for very\nlarge mappings, this handler is quite efficient.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/map","repo":"https://github.com/caddyserver/caddy"},{"name":"push","docs":"push is a middleware for HTTP/2 server push. Note that\nHTTP/2 server push has been deprecated by some clients and\nits use is discouraged unless you can accurately predict\nwhich resources actually need to be pushed to the client;\nit can be difficult to know what the client already has\ncached. Pushing unnecessary resources results in worse\nperformance. Consider using HTTP 103 Early Hints instead.\n\nThis handler supports pushing from Link headers; in other\nwords, if the eventual response has Link headers, this\nhandler will push the resources indicated by those headers,\neven without specifying any resources in its config.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/push","repo":"https://github.com/caddyserver/caddy"},{"name":"request_body","docs":"request_body is a middleware for manipulating the request body.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/requestbody","repo":"https://github.com/caddyserver/caddy"},{"name":"copy_response","docs":"copy_response is a special HTTP handler which may\nonly be used within reverse_proxy's handle_response routes,\nto copy the proxy response. EXPERIMENTAL, subject to change.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy","repo":"https://github.com/caddyserver/caddy"},{"name":"copy_response_headers","docs":"copy_response_headers is a special HTTP handler which may\nonly be used within reverse_proxy's handle_response routes,\nto copy headers from the proxy response. EXPERIMENTAL;\nsubject to change.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy","repo":"https://github.com/caddyserver/caddy"},{"name":"reverse_proxy","docs":"reverse_proxy implements a highly configurable and production-ready reverse proxy.\n\nUpon proxying, this module sets the following placeholders (which can be used\nboth within and after this handler; for example, in response headers):\n\nPlaceholder | Description\n------------|-------------\n`{http.reverse_proxy.upstream.address}` | The full address to the upstream as given in the config\n`{http.reverse_proxy.upstream.hostport}` | The host:port of the upstream\n`{http.reverse_proxy.upstream.host}` | The host of the upstream\n`{http.reverse_proxy.upstream.port}` | The port of the upstream\n`{http.reverse_proxy.upstream.requests}` | The approximate current number of requests to the upstream\n`{http.reverse_proxy.upstream.max_requests}` | The maximum approximate number of requests allowed to the upstream\n`{http.reverse_proxy.upstream.fails}` | The number of recent failed requests to the upstream\n`{http.reverse_proxy.upstream.latency}` | How long it took the proxy upstream to write the response header.\n`{http.reverse_proxy.upstream.latency_ms}` | Same as 'latency', but in milliseconds.\n`{http.reverse_proxy.upstream.duration}` | Time spent proxying to the upstream, including writing response body to client.\n`{http.reverse_proxy.upstream.duration_ms}` | Same as 'upstream.duration', but in milliseconds.\n`{http.reverse_proxy.duration}` | Total time spent proxying, including selecting an upstream, retries, and writing response.\n`{http.reverse_proxy.duration_ms}` | Same as 'duration', but in milliseconds.\n`{http.reverse_proxy.retries}` | The number of retries actually performed to communicate with an upstream.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy","repo":"https://github.com/caddyserver/caddy"},{"name":"rewrite","docs":"rewrite is a middleware which can rewrite/mutate HTTP requests.\n\nThe Method and URI properties are \"setters\" (the request URI\nwill be overwritten with the given values). Other properties are\n\"modifiers\" (they modify existing values in a differentiable\nway). It is atypical to combine the use of setters and\nmodifiers in a single rewrite.\n\nTo ensure consistent behavior, prefix and suffix stripping is\nperformed in the URL-decoded (unescaped, normalized) space by\ndefault except for the specific bytes where an escape sequence\nis used in the prefix or suffix pattern.\n\nFor all modifiers, paths are cleaned before being modified so that\nmultiple, consecutive slashes are collapsed into a single slash,\nand dot elements are resolved and removed. In the special case\nof a prefix, suffix, or substring containing \"//\" (repeated slashes),\nslashes will not be merged while cleaning the path so that\nthe rewrite can be interpreted literally.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite","repo":"https://github.com/caddyserver/caddy"},{"name":"templates","docs":"templates is a middleware which executes response bodies as Go templates.\nThe syntax is documented in the Go standard library's\n[text/template package](https://golang.org/pkg/text/template/).\n\n⚠️ Template functions/actions are still experimental, so they are subject to change.\n\nCustom template functions can be registered by creating a plugin module under the `http.handlers.templates.functions.*` namespace that implements the `CustomFunctions` interface.\n\n[All Sprig functions](https://masterminds.github.io/sprig/) are supported.\n\nIn addition to the standard functions and the Sprig library, Caddy adds\nextra functions and data that are available to a template:\n\n##### `.Args`\n\nA slice of arguments passed to this page/context, for example\nas the result of a [`include`](#include).\n\n```\n{{index .Args 0}} // first argument\n```\n\n##### `.Cookie`\n\nGets the value of a cookie by name.\n\n```\n{{.Cookie \"cookiename\"}}\n```\n\n##### `env`\n\nGets an environment variable.\n\n```\n{{env \"VAR_NAME\"}}\n```\n\n##### `placeholder`\n\nGets an [placeholder variable](/docs/conventions#placeholders).\nThe braces (`{}`) have to be omitted.\n\n```\n{{placeholder \"http.request.uri.path\"}}\n{{placeholder \"http.error.status_code\"}}\n```\n\nAs a shortcut, `ph` is an alias for `placeholder`.\n\n```\n{{ph \"http.request.method\"}}\n```\n\n##### `.Host`\n\nReturns the hostname portion (no port) of the Host header of the HTTP request.\n\n```\n{{.Host}}\n```\n\n##### `httpInclude`\n\nIncludes the contents of another file, and renders it in-place,\nby making a virtual HTTP request (also known as a sub-request).\nThe URI path must exist on the same virtual server because the\nrequest does not use sockets; instead, the request is crafted in\nmemory and the handler is invoked directly for increased efficiency.\n\n```\n{{httpInclude \"/foo/bar?q=val\"}}\n```\n\n##### `import`\n\nReads and returns the contents of another file, and parses it\nas a template, adding any template definitions to the template\nstack. If there are no definitions, the filepath will be the\ndefinition name. Any `{{ define }}` blocks will be accessible by\n`{{ template }}` or `{{ block }}`. Imports must happen before the\ntemplate or block action is called. Note that the contents are\nNOT escaped, so you should only import trusted template files.\n\n**filename.html**\n```\n{{ define \"main\" }}\ncontent\n{{ end }}\n```\n\n**index.html**\n```\n{{ import \"/path/to/filename.html\" }}\n{{ template \"main\" }}\n```\n\n##### `include`\n\nIncludes the contents of another file, rendering it in-place.\nOptionally can pass key-value pairs as arguments to be accessed\nby the included file. Use [`.Args N`](#args) to access the N-th\nargument, 0-indexed. Note that the contents are NOT escaped, so\nyou should only include trusted template files.\n\n```\n{{include \"path/to/file.html\"}}  // no arguments\n{{include \"path/to/file.html\" \"arg0\" 1 \"value 2\"}}  // with arguments\n```\n\n##### `readFile`\n\nReads and returns the contents of another file, as-is.\nNote that the contents are NOT escaped, so you should\nonly read trusted files.\n\n```\n{{readFile \"path/to/file.html\"}}\n```\n\n##### `listFiles`\n\nReturns a list of the files in the given directory, which is relative\nto the template context's file root.\n\n```\n{{listFiles \"/mydir\"}}\n```\n\n##### `markdown`\n\nRenders the given Markdown text as HTML and returns it. This uses the\n[Goldmark](https://github.com/yuin/goldmark) library,\nwhich is CommonMark compliant. It also has these extensions\nenabled: GitHub Flavored Markdown, Footnote, and syntax\nhighlighting provided by [Chroma](https://github.com/alecthomas/chroma).\n\n```\n{{markdown \"My _markdown_ text\"}}\n```\n\n##### `.RemoteIP`\n\nReturns the connection's IP address.\n\n```\n{{.RemoteIP}}\n```\n\n##### `.ClientIP`\n\nReturns the real client's IP address, if `trusted_proxies` was configured,\notherwise returns the connection's IP address.\n\n```\n{{.ClientIP}}\n```\n\n##### `.Req`\n\nAccesses the current HTTP request, which has various fields, including:\n\n  - `.Method` - the method\n  - `.URL` - the URL, which in turn has component fields (Scheme, Host, Path, etc.)\n  - `.Header` - the header fields\n  - `.Host` - the Host or :authority header of the request\n\n```\n{{.Req.Header.Get \"User-Agent\"}}\n```\n\n##### `.OriginalReq`\n\nLike [`.Req`](#req), except it accesses the original HTTP\nrequest before rewrites or other internal modifications.\n\n##### `.RespHeader.Add`\n\nAdds a header field to the HTTP response.\n\n```\n{{.RespHeader.Add \"Field-Name\" \"val\"}}\n```\n\n##### `.RespHeader.Del`\n\nDeletes a header field on the HTTP response.\n\n```\n{{.RespHeader.Del \"Field-Name\"}}\n```\n\n##### `.RespHeader.Set`\n\nSets a header field on the HTTP response, replacing any existing value.\n\n```\n{{.RespHeader.Set \"Field-Name\" \"val\"}}\n```\n\n##### `httpError`\n\nReturns an error with the given status code to the HTTP handler chain.\n\n```\n{{if not (fileExists $includedFile)}}{{httpError 404}}{{end}}\n```\n\n##### `splitFrontMatter`\n\nSplits front matter out from the body. Front matter is metadata that\nappears at the very beginning of a file or string. Front matter can\nbe in YAML, TOML, or JSON formats:\n\n**TOML** front matter starts and ends with `+++`:\n\n```toml\n+++\ntemplate = \"blog\"\ntitle = \"Blog Homepage\"\nsitename = \"A Caddy site\"\n+++\n```\n\n**YAML** is surrounded by `---`:\n\n```yaml\n---\ntemplate: blog\ntitle: Blog Homepage\nsitename: A Caddy site\n---\n```\n\n**JSON** is simply `{` and `}`:\n\n```json\n{\n\"template\": \"blog\",\n\"title\": \"Blog Homepage\",\n\"sitename\": \"A Caddy site\"\n}\n```\n\nThe resulting front matter will be made available like so:\n\n- `.Meta` to access the metadata fields, for example: `{{$parsed.Meta.title}}`\n- `.Body` to access the body after the front matter, for example: `{{markdown $parsed.Body}}`\n\n##### `stripHTML`\n\nRemoves HTML from a string.\n\n```\n{{stripHTML \"Shows \u003cb\u003eonly\u003c/b\u003e text content\"}}\n```\n\n##### `humanize`\n\nTransforms size and time inputs to a human readable format.\nThis uses the [go-humanize](https://github.com/dustin/go-humanize) library.\n\nThe first argument must be a format type, and the last argument\nis the input, or the input can be piped in. The supported format\ntypes are:\n- **size** which turns an integer amount of bytes into a string like `2.3 MB`\n- **time** which turns a time string into a relative time string like `2 weeks ago`\n\nFor the `time` format, the layout for parsing the input can be configured\nby appending a colon `:` followed by the desired time layout. You can\nfind the documentation on time layouts [in Go's docs](https://pkg.go.dev/time#pkg-constants).\nThe default time layout is `RFC1123Z`, i.e. `Mon, 02 Jan 2006 15:04:05 -0700`.\n\n##### `pathEscape`\n\nPasses a string through `url.PathEscape`, replacing characters that have\nspecial meaning in URL path parameters (`?`, `\u0026`, `%`).\n\nUseful e.g. to include filenames containing these characters in URL path\nparameters, or use them as an `img` element's `src` attribute.\n\n```\n{{pathEscape \"50%_valid_filename?.jpg\"}}\n```\n\n```\n{{humanize \"size\" \"2048000\"}}\n{{placeholder \"http.response.header.Content-Length\" | humanize \"size\"}}\n{{humanize \"time\" \"Fri, 05 May 2022 15:04:05 +0200\"}}\n{{humanize \"time:2006-Jan-02\" \"2022-May-05\"}}\n```","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/templates","repo":"https://github.com/caddyserver/caddy"},{"name":"tracing","docs":"tracing implements an HTTP handler that adds support for distributed tracing,\nusing OpenTelemetry. This module is responsible for the injection and\npropagation of the trace context. Configure this module via environment\nvariables (see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md).\nSome values can be overwritten in the configuration file.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/tracing","repo":"https://github.com/caddyserver/caddy"},{"name":"acme_server","docs":"acme_server is an ACME server handler.","package":"github.com/caddyserver/caddy/v2/modules/caddypki/acmeserver","repo":"https://github.com/caddyserver/caddy"},{"name":"metrics","docs":"metrics is a module that serves a /metrics endpoint so that any gathered\nmetrics can be exposed for scraping. This module is configurable by end-users\nunlike AdminMetrics.","package":"github.com/caddyserver/caddy/v2/modules/metrics","repo":"https://github.com/caddyserver/caddy"},{"name":"replace_response","docs":"replace_response manipulates response bodies by performing\nsubstring or regex replacements.","package":"github.com/caddyserver/replace-response","repo":"https://github.com/caddyserver/replace-response"},{"name":"authz","package":"github.com/casbin/caddy-authz/v2","repo":"https://github.com/casbin/caddy-authz"},{"name":"openapi","package":"github.com/chukmunnlee/caddy-openapi","repo":"https://github.com/chukmunnlee/caddy-openapi"},{"name":"geofence","docs":"geofence implements IP geofencing functionality. https://github.com/circa10a/caddy-geofence","package":"github.com/circa10a/caddy-geofence","repo":"https://github.com/circa10a/caddy-geofence"},{"name":"adobe_usage_tracker","docs":"adobe_usage_tracker implements HTTP middleware that parses\nuploaded log files from Adobe desktop applications in order to\ncollect measurements about past launches. These measurements\nare then uploaded to an InfluxDB (using the v1 HTTP API).\n\nConfiguration of the tracker requires four parameters:\n\n- the endpoint URL of the influx v1 upload api\n- the name of the influx v1 database\n- the retention policy of the influx v1 database\n- an API token authorized for writes of the database\n\nNote: this middleware uses the v1 HTTP write API because it's\nfully supported by both v1 and v3 databases.  When using a\nv3 database, you must specify a \"dbrp\" mapping from the\ndatabase and policy names to the specific bucket you want\nuploads to go to. See the influx docs for details:\n\nhttps://docs.influxdata.com/influxdb/cloud-serverless/write-data/api/v1-http/","package":"github.com/clickonetwo/tracker","repo":"https://github.com/clickonetwo/tracker"},{"name":"waf","package":"github.com/corazawaf/coraza-caddy","repo":"https://github.com/corazawaf/coraza-caddy"},{"name":"waf","docs":"waf is a Web Application Firewall implementation for Caddy.","package":"github.com/corazawaf/coraza-caddy/v2","repo":"https://github.com/corazawaf/coraza-caddy"},{"name":"ct","docs":"ct allows to transpile YAML based configuration into a JSON ignition to be used with Flatcar or Fedora CoreOS.","package":"github.com/cubic3d/caddy-ct","repo":"https://github.com/cubic3d/caddy-ct"},{"name":"quantity_limiter","docs":"quantity_limiter limits the number of successful requests for a token and allows the counter to be reset.","package":"github.com/cubic3d/caddy-quantity-limiter","repo":"https://github.com/cubic3d/caddy-quantity-limiter"},{"name":"esi","docs":"esi to handle, process and serve ESI tags.","package":"github.com/darkweak/go-esi/middleware/caddy","repo":"https://github.com/darkweak/go-esi"},{"name":"cache","docs":"cache development repository of the cache handler, allows\nthe user to set up an HTTP cache system, RFC-7234 compliant and\nsupports the tag based cache purge, distributed and not-distributed\nstorage, key generation tweaking.","package":"github.com/darkweak/souin/plugins/caddy","repo":"https://github.com/darkweak/souin"},{"name":"cache","docs":"cache development repository of the cache handler, allows\nthe user to set up an HTTP cache system, RFC-7234 compliant and\nsupports the tag based cache purge, distributed and not-distributed\nstorage, key generation tweaking.","package":"github.com/darkweak/souin/plugins/caddy","repo":"https://github.com/darkweak/souin"},{"name":"olo_signature","package":"github.com/dbaggett/caddy-olo-signature-authorization","repo":"https://github.com/dbaggett/caddy-olo-signature-authorization"},{"name":"ip_filter","package":"github.com/deanchou/caddy_ip_filter","repo":"https://github.com/deanchou/caddy_ip_filter"},{"name":"minifier","package":"github.com/devetek/caddyserver-minifier","repo":"https://github.com/devetek/caddyserver-minifier"},{"name":"mirror","docs":"mirror runs multiple handlers and aggregates their results","package":"github.com/dotvezz/caddy-mirror","repo":"https://github.com/dotvezz/caddy-mirror"},{"name":"wake_on_lan","docs":"wake_on_lan wakes up a target host on HTTP requests using wake-on-lan.","package":"github.com/dulli/caddy-wol","repo":"https://github.com/dulli/caddy-wol"},{"name":"php","package":"github.com/dunglas/frankenphp/caddy","repo":"https://github.com/dunglas/frankenphp"},{"name":"mercure","docs":"mercure implements a Mercure hub as a Caddy module. Mercure is a protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way.","package":"github.com/dunglas/mercure/caddy","repo":"https://github.com/dunglas/mercure"},{"name":"vulcain","docs":"vulcain add suport for the Vulcain protocol (fast and idiomatic client-driven REST APIs) as a Caddy module.","package":"github.com/dunglas/vulcain/caddy","repo":"https://github.com/dunglas/vulcain"},{"name":"discord","docs":"discord is used in combination with\nhttp.authentication.providers.discord to provide an authentication\nlayer based on a Discord identity.\n\nSee https://caddyserver.com/docs/modules/http.authentication.providers.discord\nor https://github.com/enum-gg/caddy-discord","package":"github.com/enum-gg/caddy-discord","repo":"https://github.com/enum-gg/caddy-discord"},{"name":"i18n","package":"github.com/ewen-lbh/caddy-i18n","repo":"https://github.com/ewen-lbh/caddy-i18n"},{"name":"forward_auth","package":"github.com/firecow/caddy-forward-auth","repo":"https://github.com/firecow/caddy-forward-auth"},{"name":"gbox","docs":"gbox implements an HTTP handler as a GraphQL reverse proxy server for caching, securing, and monitoring.","package":"github.com/gbox-proxy/gbox","repo":"https://github.com/gbox-proxy/gbox"},{"name":"upload","docs":"Middleware implements an HTTP handler that writes the\nuploaded file  to a file on the disk.","package":"github.com/git001/caddyv2-upload","repo":"https://github.com/git001/caddyv2-upload"},{"name":"authp","docs":"authp implements Form-Based, Basic, Local, LDAP,\nOpenID Connect, OAuth 2.0, SAML Authentication.","package":"github.com/greenpau/caddy-auth-portal","repo":"https://github.com/greenpau/caddy-auth-portal"},{"name":"git","docs":"git implements git repository manager.","package":"github.com/greenpau/caddy-git","repo":"https://github.com/greenpau/caddy-git"},{"name":"lambda","docs":"lambda is a middleware which triggers execution of a function when\nit is invoked.","package":"github.com/greenpau/caddy-lambda","repo":"https://github.com/greenpau/caddy-lambda"},{"name":"request_debug","docs":"request_debug is a middleware which displays the content of the request it\nhandles. It helps troubleshooting web requests by exposing headers\n(e.g. cookies), URL parameters, etc.","package":"github.com/greenpau/caddy-request-debug","repo":"https://github.com/greenpau/caddy-request-debug"},{"name":"authenticator","docs":"authenticator implements Form-Based, Basic, Local, LDAP,\nOpenID Connect, OAuth 2.0, SAML Authentication.","package":"github.com/greenpau/caddy-security","repo":"https://github.com/greenpau/caddy-security"},{"name":"trace","docs":"trace is a middleware which displays the content of the request it\nhandles. It helps troubleshooting web requests by exposing headers\n(e.g. cookies), URL parameters, etc.","package":"github.com/greenpau/caddy-trace","repo":"https://github.com/greenpau/caddy-trace"},{"name":"teapot","docs":"teapot implements a static \"418 I'm a teapot\" response to all requests on the route","package":"github.com/hairyhenderson/caddy-teapot-module","repo":"https://github.com/hairyhenderson/caddy-teapot-module"},{"name":"prometheus","docs":"prometheus -","package":"github.com/hairyhenderson/caddyprom","repo":"https://github.com/hairyhenderson/caddyprom"},{"name":"crowdsec","docs":"crowdsec matches request IPs to CrowdSec decisions to (dis)allow access","package":"github.com/hslatman/caddy-crowdsec-bouncer/http","repo":"https://github.com/hslatman/caddy-crowdsec-bouncer"},{"name":"openapi_validator","docs":"openapi_validator is used to validate OpenAPI requests and responses against an OpenAPI specification","package":"github.com/hslatman/caddy-openapi-validator","repo":"https://github.com/hslatman/caddy-openapi-validator"},{"name":"trojan","docs":"trojan implements an HTTP handler that ...","package":"github.com/imgk/caddy-trojan/handler","repo":"https://github.com/imgk/caddy-trojan"},{"name":"xtemplates","package":"github.com/infogulch/caddy-xtemplate","repo":"https://github.com/infogulch/caddy-xtemplate"},{"name":"xtemplates","package":"github.com/infogulch/caddy-xtemplates","repo":"https://github.com/infogulch/caddy-xtemplates"},{"name":"xtemplate","package":"github.com/infogulch/xtemplate-caddy","repo":"https://github.com/infogulch/xtemplate-caddy"},{"name":"xtemplate","package":"github.com/infogulch/xtemplate/caddy","repo":"https://github.com/infogulch/xtemplate"},{"name":"defender","docs":"defender implements an HTTP middleware that enforces IP-based rules to protect your site from AIs/Scrapers.\nIt allows blocking or manipulating requests based on client IP addresses using CIDR ranges or predefined ranges\nfor services such as AWS, GCP, OpenAI, and GitHub Copilot.\n\n**JSON Configuration:**\n\n```json\n\n\t{\n\t  \"handler\": \"defender\",\n\t  \"raw_responder\": \"block\",\n\t  \"ranges\": [\"openai\", \"10.0.0.0/8\"],\n\t  \"message\": \"Custom block message\" // Only for 'custom' responder\n\t}\n\n```\n\n**Caddyfile Syntax:**\n```\n\n\tdefender \u003cresponder_type\u003e {\n\t    ranges \u003ccidr_or_predefined...\u003e\n\t    message \u003ccustom_message\u003e\n\t}\n\n```\n\nSupported responder types:\n- `block`: Immediately block requests with 403 Forbidden\n- `custom`: Return a custom message (requires `message` field)\n- `drop`: Drops the connection\n- `garbage`: Respond with random garbage data\n- `redirect`: Redirect requests to a URL with 308 permanent redirect\n- `tarpit`: Stream data at a slow, but configurable rate to stall bots and pollute AI training.\n\nFor a list of predefined ranges, see the the [readme]\n[readme]: https://github.com/JasonLovesDoggo/caddy-defender#embedded-ip-ranges","package":"github.com/jasonlovesdoggo/caddy-defender","repo":"https://github.com/jasonlovesdoggo/caddy-defender"},{"name":"defender","docs":"defender implements an HTTP middleware that enforces IP-based rules.","package":"github.com/jasonlovesdoggo/caddy-defender","repo":"https://github.com/jasonlovesdoggo/caddy-defender"},{"name":"umami","docs":"A Caddy module which sends visitor information to Umami's Events REST API endpoint.","package":"github.com/jonaharagon/caddy-umami","repo":"https://github.com/jonaharagon/caddy-umami"},{"name":"simpletrace","docs":"simpletrace implements a lightweight trace context handler for Caddy","package":"github.com/jum/caddy-simpletrace","repo":"https://github.com/jum/caddy-simpletrace"},{"name":"trapdoor","package":"github.com/kassner/caddy-trapdoor","repo":"https://github.com/kassner/caddy-trapdoor"},{"name":"realip","package":"github.com/kirsch33/realip","repo":"https://github.com/kirsch33/realip"},{"name":"s3proxy","docs":"s3proxy implements a proxy to return, set, delete or browse objects from S3","package":"github.com/lindenlab/caddy-s3-proxy","repo":"https://github.com/lindenlab/caddy-s3-proxy"},{"name":"dns01proxy","docs":"Implements an API for proxying ACME DNS-01 challenges.\n\nThis is a Caddy `http.handlers` module.","package":"github.com/liujed/caddy-dns01proxy","repo":"https://github.com/liujed/caddy-dns01proxy"},{"name":"request_id","docs":"request_id implements an HTTP handler that writes a\nunique request ID to response headers.","package":"github.com/lolPants/caddy-requestid","repo":"https://github.com/lolPants/caddy-requestid"},{"name":"floaty","package":"github.com/ltgcgo/floaty","repo":"https://github.com/ltgcgo/floaty"},{"name":"grpc_web","docs":"grpc_web is an HTTP handler that bridges gRPC-Web \u003c--\u003e gRPC requests.\nThis module is EXPERIMENTAL and subject to change.","package":"github.com/mholt/caddy-grpc-web","repo":"https://github.com/mholt/caddy-grpc-web"},{"name":"public_suffix","docs":"public_suffix adds placeholders that return values based on the Public Suffix List, or PSL (https://publicsuffix.org).\nThe placeholders can be useful for routing, responses, headers, or any other logic in your server config.\n\nPlaceholders are created with these possible input prefixes:\n\n- **`qs.*`** gets a value from the query string with the named key, e.g. for a query string `?foo=example.com`,\n`qs.foo` would refer to the value `example.com`.\n- **`header.*`** gets a value from the header with the named field, e.g. for a header `Host: example.com:1234`,\n`header.Host` refers to the value `example.com`.\n\nFor all input values, ports are ignored automatically.\n\nThe placeholders created by this handler must then have one of the following output endings:\n\n- **`.is_icann`** returns true if the longest matching suffix is ICANN-managed, or false if the domain is\nprivately managed (i.e. not an ICANN ending).\n\n- **`.public_suffix`** returns the \"Effective TLD\" or the eTLD, which is basically the matching ICANN-managed\nentry in the PSL. For example, the eTLD of `sub.example.com` is `com`, and the eTLD of `foo.bar.com.au` is\n`com.au`. Privately-managed endings are NOT matched by this placeholder, so `foo.blogspot.com` would return\n`com`, not `blogspot.com` even though `blogspot.com` is on the PSL.\n\n- **`.domain_suffix`** is the same as the `.public_suffix` placeholder ending, except that it doesn't\ndiscriminate ICANN-managed labels. In other words, in `foo.blogspot.com`, this one would return `blogspot.com`.\n\n- **`.registered_domain`** returns the \"Effective TLD+1\" or \"eTLD+1\", using only ICANN-managed labels as the\nauthority. For example, in `sub.example.com`, the registered domain is `example.com` because the public suffix\nis `com`. In `sub.example.co.uk`, the registered domain is `example.co.uk` because the public suffix is `co.uk`.\nIn `foo.blogspot.com`, the registered domain is `blogspot.com` even though `blogspot.com` is itself on the PSL;\nthis is because `blogspot.com` is privately-managed, not an ICANN suffix.\n\n- **`.public_registered_domain`** is the same as the `.registered_domain` placeholder, except that it\nonly returns a value if the suffix is an ICANN ending. In other words, it returns the registered domain\nonly if `is_icann` is true.\n\nConcatenate any of the placeholder prefixes with any of the placeholder endings to use the placeholder.\n\nExamples:\n\n- `{qs.domain.public_suffix}` returns the public suffix of the value in the `domain` query string parameter.\n- `{header.Host.registered_domain}` returns the registered domain of the value in the `Host` header field.\n- `{header.Host.public_registered_domain}` is the same as the previous, but only returns a non-empty value if\nthe domain suffix is a public/ICANN-managed ending.","package":"github.com/mholt/caddy-psl","repo":"https://github.com/mholt/caddy-psl"},{"name":"rate_limit","docs":"rate_limit implements rate limiting functionality.\n\nIf a rate limit is exceeded, an HTTP error with status 429 will be\nreturned. This error can be handled using the conventional error\nhandling routes in your config. An additional placeholder is made\navailable, called `{http.rate_limit.exceeded.name}`, which you can\nuse for logging or handling; it contains the name of the rate limit\nzone which limit was exceeded.","package":"github.com/mholt/caddy-ratelimit","repo":"https://github.com/mholt/caddy-ratelimit"},{"name":"webdav","docs":"webdav implements an HTTP handler for responding to WebDAV clients.","package":"github.com/mholt/caddy-webdav","repo":"https://github.com/mholt/caddy-webdav"},{"name":"blockaws","docs":"blockaws is a Caddy module that blocks all AWS IP addresses taken from https://ip-ranges.amazonaws.com/ip-ranges.json","package":"github.com/mkalus/caddy_block_aws","repo":"https://github.com/mkalus/caddy_block_aws"},{"name":"nobots","docs":"nobots is a Caddy Server plugin to protect your website against web crawlers and bots. It is an enhancement of the\nv1 version https://github.com/caddy-plugins/nobots","package":"github.com/mkalus/caddy_nobots_v2","repo":"https://github.com/mkalus/caddy_nobots_v2"},{"name":"pocketbase","docs":"pocketbase implements an HTTP handler that proxies requests internally to a PocketBase server.\nIt can be used in conjunction with the PocketBase app. If the PocketBase app is not explicitly configured,\na PocketBase app with default config is used.","package":"github.com/mohammed90/caddy-pocketbase","repo":"https://github.com/mohammed90/caddy-pocketbase"},{"name":"pirsch","package":"github.com/muety/caddy-pirsch-plugin","repo":"https://github.com/muety/caddy-pirsch-plugin"},{"name":"plausible","package":"github.com/muety/caddy-plausible-plugin","repo":"https://github.com/muety/caddy-plausible-plugin"},{"name":"user_agent_parse","package":"github.com/neodyme-labs/user_agent_parse","repo":"https://github.com/neodyme-labs/user_agent_parse"},{"name":"redir_dns","docs":"redir_dns is a Caddy module implementing HTTP redirects stored in DNS TXT records","package":"github.com/pberkel/caddy-redir-dns","repo":"https://github.com/pberkel/caddy-redir-dns"},{"name":"pmtiles_proxy","docs":"pmtiles_proxy creates a Z/X/Y tileserver backed by a local or remote bucket of PMTiles archives.","package":"github.com/protomaps/go-pmtiles/caddy","repo":"https://github.com/protomaps/go-pmtiles"},{"name":"image_processor","docs":"image_processor allow user to do image processing on the fly using libvips\nWith simple queries parameters you can resize, convert, crop your served images","package":"github.com/quix-labs/caddy-image-processor","repo":"https://github.com/quix-labs/caddy-image-processor"},{"name":"sablier","package":"github.com/sablierapp/sablier/plugins/caddy","repo":"https://github.com/sablierapp/sablier"},{"name":"k8s_admission","docs":"k8s_admission is a Caddy HTTP handler that processes Kubernetes admission webhook requests.\n\nIt acts as a host module that loads guest admission controller modules.","package":"github.com/sagikazarmark/caddy-k8s-admission","repo":"https://github.com/sagikazarmark/caddy-k8s-admission"},{"name":"scion","package":"github.com/scionproto-contrib/caddy-scion","repo":"https://github.com/scionproto-contrib/caddy-scion"},{"name":"cookiecrypt","package":"github.com/sebdroid/cookiecrypt","repo":"https://github.com/sebdroid/cookiecrypt"},{"name":"geoip","docs":"Allows looking up the Country Code of an IP address based on the Maxmind database","package":"github.com/shift72/caddy-geo-ip","repo":"https://github.com/shift72/caddy-geo-ip"},{"name":"http_cache","docs":"http_cache is a http handler as a middleware to cache the response","package":"github.com/sillygod/cdp-cache","repo":"https://github.com/sillygod/cdp-cache"},{"name":"filter","docs":"filter implements an HTTP handler that writes the\nvisitor's IP address to a file or stream.","package":"github.com/sjtug/caddy2-filter","repo":"https://github.com/sjtug/caddy2-filter"},{"name":"cerberus","package":"github.com/sjtug/cerberus","repo":"https://github.com/sjtug/cerberus"},{"name":"basicauthtotp","docs":"basicauthtotp is a Caddy module that enhances Caddy's `basic_auth` directive by adding\nTime-based One-Time Password (TOTP) two-factor authentication (2FA). This module supplements\n`basic_auth` and does not replace it; therefore, `basic_auth` must be configured and active\nfor BasicAuthTOTP to function correctly. Together, these two directives provide an additional\nsecurity layer for sensitive routes by requiring both standard credentials and a valid TOTP\ncode from a compatible authenticator app.\n\nThis module is suitable for scenarios where extra security is necessary but may not be\nintended for production environments without additional testing, as it is in an experimental phase.\n\nKey features include:\n  - JWT(JSON Web Token)-session-based TOTP authentication with configurable inactivity timeouts.\n  - IP binding for session validation, requiring re-authentication if the user's IP changes.\n  - Customizable session cookie options, including name and path scope.\n\nInstead of server-side session management, this module uses JWTs stored in cookies to manage\nsessions. This approach simplifies session handling and no sessions are lost when\nCaddy is reloaded or restarted.\nHowever, this approach is less secure than server-side session management, as JWTs are\nnot invalidated or blacklisted and no logout is provided. To mitigate risks, the module uses IP binding\nto ensure that the JWT is only valid for the client IP address that created it.\nIf the client IP changes, the JWT cookie is removed and the user must re-authenticate.\n\nConfiguration options in BasicAuthTOTP provide flexibility in securing routes, and\nmanaging session inactivity timeout. Secrets are loaded from a specified JSON file that maps\nusernames to TOTP secrets.\n\nExample use case:\nBasicAuthTOTP is ideal for protecting sensitive or restricted resources by requiring an\nadditional TOTP code, making it a good fit for applications where higher assurance of\nidentity is required.","package":"github.com/steffenbusch/caddy-basicauth-totp","repo":"https://github.com/steffenbusch/caddy-basicauth-totp"},{"name":"bot_barrier","docs":"bot_barrier is a Caddy middleware module that requires clients to solve a computational challenge\nbefore granting access to HTTP resources. It helps mitigate bot traffic.","package":"github.com/steffenbusch/caddy-bot-barrier","repo":"https://github.com/steffenbusch/caddy-bot-barrier"},{"name":"extra_placeholders","docs":"extra_placeholders provides additional placeholders that can be used within Caddy configurations:\n\nPlaceholder | Description\n------------|-------------\n`{extra.caddy.version.simple}` | Simple version information of the Caddy server (e.g., v2.8.4).\n`{extra.caddy.version.full}` | Full version information of the Caddy server (e.g., v2.8.4 h1:q3pe...k=).\n`{extra.rand.float}` | Random float value between 0.0 and 1.0.\n`{extra.rand.int}` | Random integer value between the configured min and max (default is 0 to 100).\n`{extra.loadavg.1}` | System load average over the last 1 minute.\n`{extra.loadavg.5}` | System load average over the last 5 minutes.\n`{extra.loadavg.15}` | System load average over the last 15 minutes.\n`{extra.hostinfo.uptime}` | System uptime in a human-readable format.\n`{extra.newline}` | Newline character (\\n).\n\nCurrent local time placeholders:\n\nPlaceholder | Description\n------------|-------------\n`{extra.time.now.month}` | Current month as an integer (e.g., 5 for May).\n`{extra.time.now.month_padded}` | Current month as a zero-padded string (e.g., \"05\" for May).\n`{extra.time.now.day}` | Current day of the month as an integer.\n`{extra.time.now.day_padded}` | Current day of the month as a zero-padded string.\n`{extra.time.now.hour}` | Current hour in 24-hour format as an integer.\n`{extra.time.now.hour_padded}` | Current hour in 24-hour format as a zero-padded string.\n`{extra.time.now.minute}` | Current minute as an integer.\n`{extra.time.now.minute_padded}` | Current minute as a zero-padded string.\n`{extra.time.now.second}` | Current second as an integer.\n`{extra.time.now.second_padded}` | Current second as a zero-padded string.\n`{extra.time.now.timezone_offset}` | Current timezone offset from UTC (e.g., +0200).\n`{extra.time.now.timezone_name}` | Current timezone abbreviation (e.g., CEST).\n`{extra.time.now.iso_week}` | Current ISO week number of the year.\n`{extra.time.now.iso_year}` | ISO year corresponding to the current ISO week.\n`{extra.time.now.weekday_int}` | Current day of the week as an integer (Sunday = 0, Monday = 1, ..., Saturday = 6).\n`{extra.time.now.custom}` | Current time in a custom format, configurable via the `time_format_custom` directive.\n\nUTC equivalents of the current time placeholders (with `.utc` added):\n\nPlaceholder | Description\n------------|-------------\n`{extra.time.now.utc.month}` | Current month in UTC as an integer (e.g., 5 for May).\n`{extra.time.now.utc.month_padded}` | Current month in UTC as a zero-padded string (e.g., \"05\" for May).\n`{extra.time.now.utc.day}` | Current day of the month in UTC as an integer.\n`{extra.time.now.utc.day_padded}` | Current day of the month in UTC as a zero-padded string.\n`{extra.time.now.utc.hour}` | Current hour in UTC in 24-hour format as an integer.\n`{extra.time.now.utc.hour_padded}` | Current hour in UTC in 24-hour format as a zero-padded string.\n`{extra.time.now.utc.minute}` | Current minute in UTC as an integer.\n`{extra.time.now.utc.minute_padded}` | Current minute in UTC as a zero-padded string.\n`{extra.time.now.utc.second}` | Current second in UTC as an integer.\n`{extra.time.now.utc.second_padded}` | Current second in UTC as a zero-padded string.\n`{extra.time.now.utc.timezone_offset}` | UTC timezone offset (always +0000).\n`{extra.time.now.utc.timezone_name}` | UTC timezone abbreviation (always UTC).\n`{extra.time.now.utc.iso_week}` | Current ISO week number of the year in UTC.\n`{extra.time.now.utc.iso_year}` | ISO year corresponding to the current ISO week in UTC.\n`{extra.time.now.utc.weekday_int}` | Current day of the week in UTC as an integer (Sunday = 0, Monday = 1, ..., Saturday = 6).\n`{extra.time.now.utc.custom}` | Current UTC time in a custom format, configurable via the `time_format_custom` directive.","package":"github.com/steffenbusch/caddy-extra-placeholders","repo":"https://github.com/steffenbusch/caddy-extra-placeholders"},{"name":"jwt_issuer","docs":"jwt_issuer is a Caddy module that issues JSON Web Tokens (JWT) after username\nand password authentication. It is intended to generate JWTs that are checked\nwith https://github.com/ggicci/caddy-jwt, which provides the JWT Authentication.","package":"github.com/steffenbusch/caddy-jwt-issuer","repo":"https://github.com/steffenbusch/caddy-jwt-issuer"},{"name":"metric_injector","docs":"metric_injector is a Caddy HTTP middleware module that defines and\nincrements custom Prometheus counters.\n\nThe module allows defining one or more counters, with optional labels,\nthat are incremented when incoming requests match configured Caddy HTTP\nrequest matchers.\n\nEach counter may define optional matcher conditions. If the matchers\nevaluate to true for a request, the corresponding counter is incremented.\nCounters without matchers act as match-all counters and increment for every\nrequest passing through the handler.\n\nCounter evaluation occurs after the remaining handler chain has executed,\nensuring that metric collection does not interfere with request processing.\n\nAll counters are registered in Caddy's metrics registry and become available\nthrough the standard Prometheus metrics endpoint when the global `metrics`\noption is enabled.","package":"github.com/steffenbusch/caddy-metric-injector","repo":"https://github.com/steffenbusch/caddy-metric-injector"},{"name":"placeholder_dump","docs":"placeholder_dump is a Caddy module that dumps a placeholder to a file or logs it to a specified logger.\nIt logs the resolved placeholder values to the specified file or logger.","package":"github.com/steffenbusch/caddy-placeholder-dump","repo":"https://github.com/steffenbusch/caddy-placeholder-dump"},{"name":"postauth2fa","docs":"postauth2fa is a Caddy HTTP handler module that adds TOTP-based two-factor authentication (2FA)\nafter a primary authentication handler (such as basic_auth). It enforces an additional TOTP code\ncheck for protected routes. The module supports per-user TOTP secrets (plaintext or AES-GCM-encrypted),\nsession management via JWT cookies, and optional IP binding for session validation.\nFeatures:\n  - TOTP 2FA enforcement after primary authentication (e.g., basic_auth, jwtauth, etc.)\n  - Per-user TOTP secrets (plaintext or encrypted), loaded from a JSON file (map of usernames)\n  - Configurable inactivity timeout for 2FA sessions (JWT-based, stateless, cookie storage)\n  - Optional IP binding for session validation (enabled by default, can be disabled or templated)\n  - Customizable session cookie name, path, and domain\n  - Customizable HTML form template for TOTP code entry\n  - Per-user or global TOTP code length (6 or 8 digits)\n  - Secure handling of secrets and keys (Caddy placeholders and file includes supported)\n  - No server-side session state: JWTs are stateless, reloads/restarts do not invalidate sessions\n\nNote: This module does not provide user management, TOTP provisioning, or logout functionality.\nIt is intended to be used together with a primary authentication handler.","package":"github.com/steffenbusch/caddy-postauth-2fa","repo":"https://github.com/steffenbusch/caddy-postauth-2fa"},{"name":"argsort","docs":"argsort sort the query arguments after optionally lowercasing them.\n\nSyntax:\n\n\targsort [lowercase]","package":"github.com/teodorescuserban/caddy-argsort","repo":"https://github.com/teodorescuserban/caddy-argsort"},{"name":"argsort","docs":"argsort implements an HTTP handler that\nreorders the query arguments.","package":"github.com/teodorescuserban/caddy-argsort","repo":"https://github.com/teodorescuserban/caddy-argsort"},{"name":"cookieflag","docs":"cookieflag manipulate various flags (Secure, HttpOnly, ...) in the Set-Cookie reponse headers.\n\nSyntax:\n\n\tcookieflag [\u003cmatcher\u003e] [(+|-)\u003cfield\u003e] {\n\t\t+\u003cfield\u003e\n\t\t-\u003cfield\u003e\n\t}","package":"github.com/teodorescuserban/caddy-cookieflag","repo":"https://github.com/teodorescuserban/caddy-cookieflag"},{"name":"ipmap","docs":"ipmap implements a middleware that maps IP / Subnets as inputs to outputs.\nSpecifically, it compares a source value against the map inputs, and for one\nthat matches, it applies the output values to each destination. Destinations\nbecome placeholder names.\n\nMapped placeholders are not evaluated until they are used, so even for very\nlarge mappings, this handler is quite efficient.","package":"github.com/teodorescuserban/caddy-ip-map","repo":"https://github.com/teodorescuserban/caddy-ip-map"},{"name":"image_filter","docs":"image_filter is a caddy module that can apply image filters to images from the filesystem at\nruntime. It should be used together with a cache module, so filters don't have to be applied\nrepeatedly because it's an expensive operation.","package":"github.com/ueffel/caddy-imagefilter","repo":"https://github.com/ueffel/caddy-imagefilter"},{"name":"image_filter","docs":"image_filter is a caddy module that can apply image filters to images from the filesystem at\nruntime. It should be used together with a cache module, so filters don't have to be applied\nrepeatedly because it's an expensive operation.","package":"github.com/ueffel/caddy-imagefilter/v2","repo":"https://github.com/ueffel/caddy-imagefilter"},{"name":"lura","docs":"lura implements a high-performance API Gateway using the Lura framework (https://luraproject.org/).\n\nThis module provides advanced API gateway functionalities.\nIt allows defining multiple endpoints, each specifying backend services for request processing.\nThe module supports response aggregation and transformation rules per endpoint, facilitating\ncomplex API orchestrations.","package":"github.com/xico42/caddy-lura","repo":"https://github.com/xico42/caddy-lura"},{"name":"simple_password","docs":"simple_password is a Caddy HTTP handler module that adds simple password authentication\nwith cookie-based session persistence. It protects routes with a single shared password.\nSessions are persisted via hashed-password cookies so users don't need to\nre-authenticate on every browser session.","package":"github.com/xupefei/caddy-simple-password","repo":"https://github.com/xupefei/caddy-simple-password"},{"name":"guard","docs":"guard is an elegant IPQS plugin for Caddy.","package":"github.com/z3ntl3/caddyguard","repo":"https://github.com/z3ntl3/caddyguard"},{"name":"geoip2","docs":"http.handlers.geoip2 is an GeoIP2 server handler.\nit uses GeoIP2 Data to identify the location of the IP","package":"github.com/zhangjiayin/caddy-geoip2","repo":"https://github.com/zhangjiayin/caddy-geoip2"},{"name":"gopkg","docs":"gopkg implements vanity go package import paths.\n\nVanity go package import paths give a cleaner appearance to go projects by separating the source code location from\nthe import path. It also gives flexibility to developers by allowing them to change a project's source code hosting\nplatform without requiring the project to be renamed. Finally, it allows projects hosted on various platforms to be\ngrouped under a common import path.","package":"magnax.ca/caddy/gopkg","repo":"https://github.com/MagnaXSoftware/gopkg"},{"name":"gopkg","docs":"gopkg represents the GoPkg Caddy module.","package":"magnax.ca/caddy/gopkg","repo":"https://github.com/MagnaXSoftware/gopkg"},{"name":"speedtest","docs":"[Speedtest] implements an HTTP handler that performs speed tests.","package":"maxchernoff.ca/tools/speedtest","repo":"https://github.com/gucci-on-fleek/caddy-speedtest.git"},{"name":"defender","docs":"defender implements an HTTP middleware that enforces IP-based rules to protect your site from AIs/Scrapers.\nIt allows blocking or manipulating requests based on client IP addresses using CIDR ranges or predefined ranges\nfor services such as AWS, GCP, OpenAI, and GitHub Copilot.\n\n**JSON Configuration:**\n\n```json\n\n\t{\n\t  \"handler\": \"defender\",\n\t  \"raw_responder\": \"block\",\n\t  \"ranges\": [\"openai\", \"10.0.0.0/8\"],\n\t  \"message\": \"Custom block message\" // Only for 'custom' responder\n\t}\n\n```\n\n**Caddyfile Syntax:**\n```\n\n\tdefender \u003cresponder_type\u003e {\n\t    ranges \u003ccidr_or_predefined...\u003e\n\t    message \u003ccustom_message\u003e\n\t}\n\n```\n\nSupported responder types:\n- `block`: Immediately block requests with 403 Forbidden\n- `custom`: Return a custom message (requires `message` field)\n- `drop`: Drops the connection\n- `garbage`: Respond with random garbage data\n- `redirect`: Redirect requests to a URL with 308 permanent redirect\n- `tarpit`: Stream data at a slow, but configurable rate to stall bots and pollute AI training.\n\nFor a list of predefined ranges, see the [readme]\n[readme]: https://github.com/JasonLovesDoggo/caddy-defender#embedded-ip-ranges","package":"pkg.jsn.cam/caddy-defender","repo":"https://github.com/JasonLovesDoggo/caddy-defender"},{"name":"imageproxy","package":"willnorris.com/go/imageproxy/caddy","repo":"https://github.com/willnorris/imageproxy"}],"http.ip_sources":[{"name":"edgeone","docs":"edgeone provides a range of IP address prefixes (CIDRs) retrieved from EdgeOne.","package":"github.com/LeenHawk/caddy-edgeone-ip","repo":"https://github.com/LeenHawk/caddy-edgeone-ip"},{"name":"cloudflare","docs":"cloudflare provides a range of IP address prefixes (CIDRs) retrieved from cloudflare.","package":"github.com/WeidiDeng/caddy-cloudflare-ip","repo":"https://github.com/WeidiDeng/caddy-cloudflare-ip"},{"name":"bunnynet","docs":"bunnynet provides a range of IP address prefixes (CIDRs) retrieved from bunny.net.","package":"github.com/alectrocute/caddy-bunnynet-ip","repo":"https://github.com/alectrocute/caddy-bunnynet-ip"},{"name":"parspack","docs":"parspack retrieves ParsPack CDN IP ranges from their official sources","package":"github.com/azolfagharj/caddy_parspack_ip","repo":"https://github.com/azolfagharj/caddy_parspack_ip"},{"name":"static","docs":"static provides a static range of IP address prefixes (CIDRs).","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"bunny","docs":"bunny provides a range of IP address prefixes (CIDRs) retrieved from https://api.bunny.net/system/edgeserverlist and https://api.bunny.net/system/edgeserverlist/ipv6.","package":"github.com/digilolnet/caddy-bunny-ip","repo":"https://github.com/digilolnet/caddy-bunny-ip"},{"name":"combine","docs":"This module combines the prefixes returned by several other IP source plugins.\nIn a caddyfile, you can specify these in the block following the \"combine\" tag.","package":"github.com/fvbommel/caddy-combine-ip-ranges","repo":"https://github.com/fvbommel/caddy-combine-ip-ranges"},{"name":"dns","docs":"dns provides a range of IP addresses associated with a DNS name.\nEach range will only contain a single IP.","package":"github.com/fvbommel/caddy-dns-ip-range","repo":"https://github.com/fvbommel/caddy-dns-ip-range"},{"name":"list","docs":"list provides a range of IP address prefixes (CIDRs) retrieved from url.","package":"github.com/monobilisim/caddy-ip-list","repo":"https://github.com/monobilisim/caddy-ip-list"},{"name":"cdn_ranges","docs":"cdn_ranges is a Caddy IP source module that automatically fetches and maintains\na list of trusted proxy IP ranges from CDN and cloud providers. It periodically updates the\nIP ranges and makes them available to Caddy's trusted proxies configuration.\n\nThe module supports:\n  - Built-in providers (Cloudflare, AWS CloudFront, Google Cloud, etc.) from the cdn-ranges library\n  - Custom providers with configurable URL endpoints and JMESPath filters\n  - Autonomous System Number (ASN) based IP range lookups\n  - Both JSON and plain text response formats\n  - Separate IPv4 and IPv6 filtering\n  - Concurrent fetching for improved performance\n\nExample Caddyfile configuration (short form):\n\n\tservers {\n\t\ttrusted_proxies {\n\t\t\tsource cdn_ranges {\n\t\t\t\tinterval 24h\n\t\t\t\tprovider cloudflare cloudfront\n\t\t\t\tconcurrency 5\n\t\t\t\tipv4 true\n\t\t\t\tipv6 true\n\t\t\t}\n\t\t}\n\t}\n\nExample with custom provider (block form):\n\n\tservers {\n\t\ttrusted_proxies {\n\t\t\tsource cdn_ranges {\n\t\t\t\tprovider {\n\t\t\t\t\tcloudflare\n\t\t\t\t\tcustom_cdn {\n\t\t\t\t\t\tipv4_url https://api.example.com/ipv4.json \"prefixes[].cidr\"\n\t\t\t\t\t\tipv6_url https://api.example.com/ipv6.json \"prefixes[].cidr\"\n\t\t\t\t\t\tasn_list 13335 20940\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}","package":"github.com/sarumaj/caddy-cdn-ranges","repo":"https://github.com/sarumaj/caddy-cdn-ranges"},{"name":"cdn_ranges","docs":"cdn_ranges is a Caddy IP source module that automatically fetches and maintains\na list of trusted proxy IP ranges from CDN and cloud providers. It periodically updates the\nIP ranges and makes them available to Caddy's trusted proxies configuration.\n\nThe module supports:\n  - Built-in providers (Cloudflare, AWS CloudFront, Google Cloud, etc.) from the cdn-ranges library\n  - Custom providers with configurable URL endpoints and JMESPath filters\n  - Autonomous System Number (ASN) based IP range lookups\n  - Both JSON and plain text response formats\n  - Separate IPv4 and IPv6 filtering\n  - Concurrent fetching for improved performance\n\nExample Caddyfile configuration (short form):\n\n\tservers {\n\t\ttrusted_proxies {\n\t\t\tsource cdn_ranges {\n\t\t\t\tinterval 24h\n\t\t\t\tprovider cloudflare cloudfront\n\t\t\t\tconcurrency 5\n\t\t\t\tipv4 true\n\t\t\t\tipv6 true\n\t\t\t}\n\t\t}\n\t}\n\nExample with custom provider (block form):\n\n\tservers {\n\t\ttrusted_proxies {\n\t\t\tsource cdn_ranges {\n\t\t\t\tprovider {\n\t\t\t\t\tcloudflare\n\t\t\t\t\tcustom_cdn {\n\t\t\t\t\t\tipv4_url https://api.example.com/ipv4.json \"prefixes[].cidr\"\n\t\t\t\t\t\tipv6_url https://api.example.com/ipv6.json \"prefixes[].cidr\"\n\t\t\t\t\t\tasn_list 13335 20940\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}","package":"github.com/sarumaj/caddy-cdn-ranges/v2","repo":"https://github.com/sarumaj/caddy-cdn-ranges"},{"name":"cloudfront","docs":"The module that auto trusted_proxies `AWS CloudFront EDGE servers` from CloudFront.\nDoc: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LocationsOfEdgeServers.html\nRange from: https://d7uri8nf7uskq.cloudfront.net/tools/list-cloudfront-ips","package":"github.com/xcaddyplugins/caddy-trusted-cloudfront","repo":"https://github.com/xcaddyplugins/caddy-trusted-cloudfront"},{"name":"gcp_cloudcdn","docs":"The module auto trusted_proxies `GCP CloudCDN EDGE servers` from `_cloud-eoips.googleusercontent.com` TXT record\nDoc: https://cloud.google.com/cdn/docs/set-up-external-backend-internet-neg\nRange from: _cloud-eoips.googleusercontent.com","package":"github.com/xcaddyplugins/caddy-trusted-gcp-cloudcdn","repo":"https://github.com/xcaddyplugins/caddy-trusted-gcp-cloudcdn"}],"http.matchers":[{"name":"crawler","docs":"crawler is a HTTP request matcher to detect crawlers.\nIt allows you to detect known crawlers/spiders/bots via the `User-Agent`.\n\nCaddyfile syntax:\n\n\t@is-crawler crawler\n\tabort @is-crawler","package":"git.gorbe.io/caddy/crawler","repo":"https://git.gorbe.io/caddy/crawler.git"},{"name":"client_asn","docs":"client_asn matches requests by the client_ip GeoIP ASN.\n\nCaddyfile syntax:\n\n\t@asn-matcher client_asn \"24940\"\n\trespond @asn-matcher \"Hetzner Online GmbH\"\n\n# Logging\n\nTo ERROR level when failed to parse client IP:\n\n\t{\"level\":\"error\", ... ,\"logger\":\"http.matchers.client_asn\",\"msg\":\"Failed to parse client IP\",\"client_ip\":\"...\",\"error\":\"...\"}\n\nTo ERROR when failed to get ASN for client IP:\n\n\t{\"level\":\"error\", ... ,\"logger\":\"http.matchers.client_asn\",\"msg\":\"Failed to get ASN for client IP\",\"client_ip\":\"...\",\"error\":\"...\"}\n\nTo WARN level when there is no data for the client IP:\n\n\t{\"level\":\"warn\", ... ,\"logger\":\"http.matchers.client_asn\",\"msg\":\"No data for client IP\",\"client_ip\":\"...\"}\n\nTo INFO level when request matched:\n\n\t{\"level\":\"info\", ... ,\"logger\":\"http.matchers.client_asn\",\"msg\":\"Request matched\",\"client_ip\":\"...\", \"asn\": \"...\"}","package":"git.gorbe.io/caddy/geoip","repo":"https://git.gorbe.io/caddy/geoip.git"},{"name":"client_country","docs":"client_country matches requests by the client_ip GeoIP Country.\n\nCaddyfile syntax:\n\n\t@country-matcher client_country \"HU\" \"DE\"\n\trespond @country-matcher \"Country matcher\"\n\n# Logging\n\nTo ERROR level when failed to parse client IP:\n\n\t{\"level\":\"error\", ... ,\"logger\":\"http.matchers.client_country\",\"msg\":\"Failed to parse client IP\",\"client_ip\":\"...\",\"error\":\"...\"}\n\nTo ERROR when failed to get Country for client IP:\n\n\t{\"level\":\"error\", ... ,\"logger\":\"http.matchers.client_country\",\"msg\":\"Failed to get Country for client IP\",\"client_ip\":\"...\",\"error\":\"...\"}\n\nTo WARN level when there is no data for the client IP:\n\n\t{\"level\":\"warn\", ... ,\"logger\":\"http.matchers.client_country\",\"msg\":\"No data for client IP\",\"client_ip\":\"...\"}\n\nTo INFO level when request matched:\n\n\t{\"level\":\"info\", ... ,\"logger\":\"http.matchers.client_country\",\"msg\":\"Request matched\",\"client_ip\":\"...\", \"country\": \"...\"}","package":"git.gorbe.io/caddy/geoip","repo":"https://git.gorbe.io/caddy/geoip.git"},{"name":"geoip_asn","docs":"geoip_asn matches requests by the client_ip GeoIP ASN.\n\nCaddyfile syntax:\n\n\t@asn-matcher geoip_asn \"24940\"\n\trespond @asn-matcher \"Hetzner Online GmbH\"","package":"git.gorbe.io/caddy/geoip","repo":"https://git.gorbe.io/caddy/geoip.git"},{"name":"geoip_country","docs":"geoip_country matches requests by the client_ip GeoIP Country.\n\nCaddyfile syntax:\n\n\t@country-matcher geoip_country \"HU\" \"DE\"\n\trespond @country-mathers \"Country matcher\"","package":"git.gorbe.io/caddy/geoip","repo":"https://git.gorbe.io/caddy/geoip.git"},{"name":"fail2ban","docs":"fail2ban implements an HTTP handler that checks a specified file for banned\nIPs and matches if they are found","package":"github.com/Javex/caddy-fail2ban","repo":"https://github.com/Javex/caddy-fail2ban"},{"name":"exec_noop","docs":"exec_noop is a matcher that blocks all requests.\nIt's primary purpose is to ensure the command is not\nexecuted when no route/matcher is specified.\nLimitation of Caddyfile config. JSON/API config do not need this.","package":"github.com/abiosoft/caddy-exec","repo":"https://github.com/abiosoft/caddy-exec"},{"name":"execnopmatch","docs":"execnopmatch is a matcher that blocks all request.\nIt's primary purpose is to ensure the command is not\nexecuted when no route/matcher is specified.\nLimitation of Caddyfile config. JSON/API config do not need this.","package":"github.com/abiosoft/caddy-exec","repo":"https://github.com/abiosoft/caddy-exec"},{"name":"dnsfetcher","package":"github.com/anthemaker/caddy-dns-fetcher","repo":"https://github.com/anthemaker/caddy-dns-fetcher"},{"name":"signed","package":"github.com/anthemaker/caddy-signed-urls","repo":"https://github.com/anthemaker/caddy-signed-urls"},{"name":"ipgate","docs":"ipgate matches requests whose client IP is in the shared\nwhitelist managed by the ipgate_trigger handler, or falls within\nany of the configured allow CIDR ranges.\n\nAfter a user authenticates and their IP is whitelisted, this matcher\nreturns true for all subsequent requests from that IP until the TTL\nexpires. IPs in the allow ranges are always allowed without\nauthentication.\n\nThis enables non-browser clients (mobile apps, media players, API\nconsumers) to access services without cookie-based authentication.\n\nCaddyfile syntax:\n\n\t@name ipgate [allow \u003ccidr\u003e ...] [allow \u003ccidr\u003e ...]","package":"github.com/anujc4/caddy-dynamic-ip-whitelist","repo":"https://github.com/anujc4/caddy-dynamic-ip-whitelist"},{"name":"geoblock","docs":"geoblock implements a request matcher that matches requests based on\ngeographic location and network information from MaxMind databases.\n\nWhen a request matches (would be blocked by the geo rules), it returns true,\nallowing you to handle matched requests with custom logic such as serving\na static site or redirecting.\n\nThe matcher sets various placeholders with geo information that can be used\nby downstream handlers:\n  - {geoblock.country_code}\n  - {geoblock.country_name}\n  - {geoblock.city_name}\n  - {geoblock.continent_code}\n  - {geoblock.subdivision_code}\n  - {geoblock.asn}\n  - {geoblock.asn_org}\n  - {geoblock.latitude}\n  - {geoblock.longitude}\n  - {geoblock.time_zone}\n  - {geoblock.postal_code}\n  - {geoblock.blocked}\n  - {geoblock.blocked_reason}","package":"github.com/anujc4/caddy-geoblock","repo":"https://github.com/anujc4/caddy-geoblock"},{"name":"client_ip","docs":"client_ip matches requests by the client IP address,\ni.e. the resolved address, considering trusted proxies.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"expression","docs":"expression matches requests by evaluating a\n[CEL](https://github.com/google/cel-spec) expression.\nThis enables complex logic to be expressed using a comfortable,\nfamiliar syntax. Please refer to\n[the standard definitions of CEL functions and operators](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions).\n\nThis matcher's JSON interface is actually a string, not a struct.\nThe generated docs are not correct because this type has custom\nmarshaling logic.\n\nCOMPATIBILITY NOTE: This module is still experimental and is not\nsubject to Caddy's compatibility guarantee.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"header","docs":"header matches requests by header fields. The key is the field\nname and the array is the list of field values. It performs fast,\nexact string comparisons of the field values. Fast prefix, suffix,\nand substring matches can also be done by suffixing, prefixing, or\nsurrounding the value with the wildcard `*` character, respectively.\nIf a list is null, the header must not exist. If the list is empty,\nthe field must simply exist, regardless of its value.\n\n**NOTE:** Notice that header values are arrays, not singular values. This is\nbecause repeated fields are valid in headers, and each one may have a\ndifferent value. This matcher will match for a field if any one of its configured\nvalues matches in the header. Backend applications relying on headers MUST take\ninto consideration that header field values are arrays and can have multiple\nvalues.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"header_regexp","docs":"header_regexp matches requests by a regular expression on header fields.\n\nUpon a match, it adds placeholders to the request: `{http.regexp.name.capture_group}`\nwhere `name` is the regular expression's name, and `capture_group` is either\nthe named or positional capture group from the expression itself. If no name\nis given, then the placeholder omits the name: `{http.regexp.capture_group}`\n(potentially leading to collisions).","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"host","docs":"host matches requests by the Host value (case-insensitive).\n\nWhen used in a top-level HTTP route,\n[qualifying domain names](/docs/automatic-https#hostname-requirements)\nmay trigger [automatic HTTPS](/docs/automatic-https), which automatically\nprovisions and renews certificates for you. Before doing this, you\nshould ensure that DNS records for these domains are properly configured,\nespecially A/AAAA pointed at your server.\n\nAutomatic HTTPS can be\n[customized or disabled](/docs/modules/http#servers/automatic_https).\n\nWildcards (`*`) may be used to represent exactly one label of the\nhostname, in accordance with RFC 1034 (because host matchers are also\nused for automatic HTTPS which influences TLS certificates). Thus,\na host of `*` matches hosts like `localhost` or `internal` but not\n`example.com`. To catch all hosts, omit the host matcher entirely.\n\nThe wildcard can be useful for matching all subdomains, for example:\n`*.example.com` matches `foo.example.com` but not `foo.bar.example.com`.\n\nDuplicate entries will return an error.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"method","docs":"method matches requests by the method.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"not","docs":"not matches requests by negating the results of its matcher\nsets. A single \"not\" matcher takes one or more matcher sets. Each\nmatcher set is OR'ed; in other words, if any matcher set returns\ntrue, the final result of the \"not\" matcher is false. Individual\nmatchers within a set work the same (i.e. different matchers in\nthe same set are AND'ed).\n\nNOTE: The generated docs which describe the structure of this\nmodule are wrong because of how this type unmarshals JSON in a\ncustom way. The correct structure is:\n\n```json\n[\n\t{},\n\t{}\n]\n```\n\nwhere each of the array elements is a matcher set, i.e. an\nobject keyed by matcher name.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"path","docs":"path case-insensitively matches requests by the URI's path. Path\nmatching is exact, not prefix-based, giving you more control and clarity\nover matching. Wildcards (`*`) may be used:\n\n- At the end only, for a prefix match (`/prefix/*`)\n- At the beginning only, for a suffix match (`*.suffix`)\n- On both sides only, for a substring match (`*/contains/*`)\n- In the middle, for a globular match (`/accounts/*/info`)\n\nSlashes are significant; i.e. `/foo*` matches `/foo`, `/foo/`, `/foo/bar`,\nand `/foobar`; but `/foo/*` does not match `/foo` or `/foobar`. Valid\npaths start with a slash `/`.\n\nBecause there are, in general, multiple possible escaped forms of any\npath, path matchers operate in unescaped space; that is, path matchers\nshould be written in their unescaped form to prevent ambiguities and\npossible security issues, as all request paths will be normalized to\ntheir unescaped forms before matcher evaluation.\n\nHowever, escape sequences in a match pattern are supported; they are\ncompared with the request's raw/escaped path for those bytes only.\nIn other words, a matcher of `/foo%2Fbar` will match a request path\nof precisely `/foo%2Fbar`, but not `/foo/bar`. It follows that matching\nthe literal percent sign (%) in normalized space can be done using the\nescaped form, `%25`.\n\nEven though wildcards (`*`) operate in the normalized space, the special\nescaped wildcard (`%*`), which is not a valid escape sequence, may be\nused in place of a span that should NOT be decoded; that is, `/bands/%*`\nwill match `/bands/AC%2fDC` whereas `/bands/*` will not.\n\nEven though path matching is done in normalized space, the special\nwildcard `%*` may be used in place of a span that should NOT be decoded;\nthat is, `/bands/%*/` will match `/bands/AC%2fDC/` whereas `/bands/*/`\nwill not.\n\nThis matcher is fast, so it does not support regular expressions or\ncapture groups. For slower but more powerful matching, use the\npath_regexp matcher. (Note that due to the special treatment of\nescape sequences in matcher patterns, they may perform slightly slower\nin high-traffic environments.)","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"path_regexp","docs":"path_regexp matches requests by a regular expression on the URI's path.\nPath matching is performed in the unescaped (decoded) form of the path.\n\nUpon a match, it adds placeholders to the request: `{http.regexp.name.capture_group}`\nwhere `name` is the regular expression's name, and `capture_group` is either\nthe named or positional capture group from the expression itself. If no name\nis given, then the placeholder omits the name: `{http.regexp.capture_group}`\n(potentially leading to collisions).","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"protocol","docs":"protocol matches requests by protocol. Recognized values are\n\"http\", \"https\", and \"grpc\" for broad protocol matches, or specific\nHTTP versions can be specified like so: \"http/1\", \"http/1.1\",\n\"http/2\", \"http/3\", or minimum versions: \"http/2+\", etc.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"query","docs":"query matches requests by the URI's query string. It takes a JSON object\nkeyed by the query keys, with an array of string values to match for that key.\nQuery key matches are exact, but wildcards may be used for value matches. Both\nkeys and values may be placeholders.\n\nAn example of the structure to match `?key=value\u0026topic=api\u0026query=something` is:\n\n```json\n{\n\t\"key\": [\"value\"],\n\t\"topic\": [\"api\"],\n\t\"query\": [\"*\"]\n}\n```\n\nInvalid query strings, including those with bad escapings or illegal characters\nlike semicolons, will fail to parse and thus fail to match.\n\n**NOTE:** Notice that query string values are arrays, not singular values. This is\nbecause repeated keys are valid in query strings, and each one may have a\ndifferent value. This matcher will match for a key if any one of its configured\nvalues is assigned in the query string. Backend applications relying on query\nstrings MUST take into consideration that query string values are arrays and can\nhave multiple values.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"remote_ip","docs":"remote_ip matches requests by the remote IP address,\ni.e. the IP address of the direct connection to Caddy.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"tls","docs":"tls matches HTTP requests based on the underlying\nTLS connection state. If this matcher is specified but\nthe request did not come over TLS, it will never match.\nIf this matcher is specified but is empty and the request\ndid come in over TLS, it will always match.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"vars_regexp","docs":"vars_regexp matches the value of the context variables by a given regular expression.\n\nUpon a match, it adds placeholders to the request: `{http.regexp.name.capture_group}`\nwhere `name` is the regular expression's name, and `capture_group` is either\nthe named or positional capture group from the expression itself. If no name\nis given, then the placeholder omits the name: `{http.regexp.capture_group}`\n(potentially leading to collisions).","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"vars","docs":"vars is an HTTP request matcher which can match\nrequests based on variables in the context or placeholder\nvalues. The key is the placeholder or name of the variable,\nand the values are possible values the variable can be in\norder to match (logical OR'ed).\n\nIf the key is surrounded by `{ }` it is assumed to be a\nplaceholder. Otherwise, it will be considered a variable\nname.\n\nPlaceholders in the keys are not expanded, but\nplaceholders in the values are.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp","repo":"https://github.com/caddyserver/caddy"},{"name":"file","docs":"file is an HTTP request matcher that can match\nrequests based upon file existence.\n\nUpon matching, three new placeholders will be made\navailable:\n\n- `{http.matchers.file.relative}` The root-relative\npath of the file. This is often useful when rewriting\nrequests.\n- `{http.matchers.file.absolute}` The absolute path\nof the matched file.\n- `{http.matchers.file.type}` Set to \"directory\" if\nthe matched file is a directory, \"file\" otherwise.\n- `{http.matchers.file.remainder}` Set to the remainder\nof the path if the path was split by `split_path`.\n\nEven though file matching may depend on the OS path\nseparator, the placeholder values always use /.","package":"github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver","repo":"https://github.com/caddyserver/caddy"},{"name":"fail2ban","docs":"fail2ban implements an HTTP handler that checks a specified file for banned\nIPs and matches if they are found","package":"github.com/chris-swift-dev/caddy-fail2ban","repo":"https://github.com/chris-swift-dev/caddy-fail2ban"},{"name":"ipset","docs":"ipset matches the client_ip against Linux ipset lists using native netlink communication.\nThis enables efficient filtering against large, dynamic sets of IPs and CIDR ranges.\n\nRequirements:\n  - Linux system with `ip_set` kernel module loaded\n  - CAP_NET_ADMIN capability, grant with: `sudo setcap cap_net_admin+ep /path/to/caddy`\n  - Existing ipset list, create with the `ipset` command\n\nSupports both IPv4 and IPv6 ipsets, performing validation during initialization.\nProtocol mismatches (e.g., testing an IPv4 address against an IPv6 set) return false.\n\nIf multiple ipsets are configured, the matcher applies OR logic: it returns true\nif the IP is found in *any* of the provided sets.\n\nInternally, it utilizes a buffered channel to pool netlink handles. This ensures\nhigh-performance concurrency while capping idle resources to prevent leaks.\n\nThe matcher integrates with Caddy's logging and metrics systems, providing detailed\ndebug logs and Prometheus metrics for monitoring.\n\nExample Caddyfile usage:\n\n```\n\n\texample.com {\n\t\t@matcher {\n\t\t\tipset test-ipset-v4\n\t\t\tipset test-ipset-v6\n\t\t}\n\t\thandle @matcher {\n\t\t\trespond \"IP matches an ipset\" 200\n\t\t}\n\t\trespond \"IP does NOT match any of the ipsets\" 403\n\t}\n\n```\n\nExtended documentation can be found in [README.md](https://github.com/deovero/caddy-ipset/blob/main/README.md)","package":"github.com/deovero/caddy-ipset","repo":"https://github.com/deovero/caddy-ipset"},{"name":"signed_url","package":"github.com/hookenz/caddy-signed-urls","repo":"https://github.com/hookenz/caddy-signed-urls"},{"name":"ipfilter_geolocation","docs":"ipfilter_geolocation allows filtering requests based on source IP country using jpillora/ipfilter.","package":"github.com/jpillora/ipfilter-caddy","repo":"https://github.com/jpillora/ipfilter-caddy"},{"name":"dynamic_remote_ip","docs":"dynamic_remote_ip matchers the requests by the remote IP address.\nThe IP ranges are provided by modules to allow for dynamic ranges.","package":"github.com/lanrat/caddy-dynamic-remoteip","repo":"https://github.com/lanrat/caddy-dynamic-remoteip"},{"name":"conneg","docs":"conneg matches requests by comparing results of a\ncontent negotiation process to a (list of) value(s).\n\nLists of media types, languages, charsets, and encodings to match\nthe request against can be given - and at least one of them MUST\nbe specified.\n\nOPTIONAL parameters are strings for identifying URL query string\nparameter keys that allow requests to override/skip the connection\nnegotiation process and force a media type, a language, a charset\nor an encoding.\n\nSome shorthand values for query string parameters translating to\nfull media types (languages, encodings, etc.) are hardcoded in a\nvariable called `aliases`: They presently cover `htm` and `html` for\n`text/html`, `rdf` for `application/rdf+xml`, `tei` and `xml` for\n`application/tei+xml`, and `pdf` for `application/pdf`. For instance,\nif `force_type_query_string` is set to `format`, a request uri\nending in `foo.com?format=tei` will result in content type\n`application/tei+xml` and then succeed or not based on whether that\ncontent type is listed in `match_types`.\n\nCOMPATIBILITY NOTE: This module is still experimental and is not\nsubject to Caddy's compatibility guarantee.","package":"github.com/mpilhlt/caddy-conneg","repo":"https://github.com/mpilhlt/caddy-conneg"},{"name":"remote_host","docs":"remote_host matches based on the remote IP of the\nconnection. A host name can be specified, whose A and AAAA\nDNS records will be resolved to a corresponding IP for matching.\n\nNote that IPs can sometimes be spoofed, so do not rely\non this as a replacement for actual authentication.","package":"github.com/muety/caddy-remote-host","repo":"https://github.com/muety/caddy-remote-host"},{"name":"maxmind_geolocation","docs":"Allows to filter requests based on source IP country.","package":"github.com/porech/caddy-maxmind-geolocation","repo":"https://github.com/porech/caddy-maxmind-geolocation"},{"name":"cron","docs":"cron matches requests based on multiple sets of cron expressions.\nIt allows you to define multiple time windows during which requests should be matched.\nThe matcher becomes active after any of the time windows specified by EnableAt\nand inactive after any corresponding DisableAt.","package":"github.com/steffenbusch/caddy-cron-matcher","repo":"https://github.com/steffenbusch/caddy-cron-matcher"},{"name":"dynamic_client_ip","docs":"dynamic_client_ip matchers the requests by the client IP address.\nThe IP ranges are provided by modules to allow for dynamic ranges.","package":"github.com/tuzzmaniandevil/caddy-dynamic-clientip","repo":"https://github.com/tuzzmaniandevil/caddy-dynamic-clientip"},{"name":"geocn","package":"github.com/ysicing/caddy2-geocn","repo":"https://github.com/ysicing/caddy2-geocn"},{"name":"geocity","package":"github.com/ysicing/caddy2-geocn","repo":"https://github.com/ysicing/caddy2-geocn"},{"name":"dynamic_host","docs":"dynamic_host implements a Caddy HTTP request matcher that dynamically loads\nhost lists from HTTP endpoints.","package":"github.com/zidsa/caddy-dynamic-host-matcher","repo":"https://github.com/zidsa/caddy-dynamic-host-matcher"}],"tls.ca_pool.source":[{"name":"file","docs":"file generates trusted root certificates pool from the designated DER and PEM file","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"http","docs":"The HTTPCertPool fetches the trusted root certificates from HTTP(S)\nendpoints. The TLS connection properties can be customized, including custom\ntrusted root certificate. One example usage of this module is to get the trusted\ncertificates from another Caddy instance that is running the PKI app and ACME server.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"inline","docs":"inline is a certificate authority pool provider coming from\na DER-encoded certificates in the config","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"lazy","docs":"lazy defers the generation of the certificate pool from the\nguest module to demand-time rather than at provisionig time. The gain of the\nlazy load adds a risk of failure to load the certificates at demand time\nbecause the validation that's typically done at provisioning is deferred.\nThe validation can be enforced to run before runtime by setting\n`EagerValidation`/`eager_validation` to `true`. It is the operator's responsibility\nto ensure the resources are available if `EagerValidation`/`eager_validation`\nis set to `true`. The module also incurs performance cost at every demand.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"pki_intermediate","docs":"pki_intermediate extracts the trusted intermediate certificates from Caddy's native 'pki' app","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"pki_root","docs":"pki_root extracts the trusted root certificates from Caddy's native 'pki' app","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"storage","docs":"storage extracts the trusted certificates root from Caddy storage","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"}],"tls.client_auth.verifier":[{"name":"leaf","docs":"leaf verifies the client's leaf certificate.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"san_dns","package":"github.com/exante/caddy-tls-san-dns","repo":"https://github.com/exante/caddy-tls-san-dns"},{"name":"fnmt","package":"github.com/pblop/caddy-tls-fnmt","repo":"https://github.com/pblop/caddy-tls-fnmt"},{"name":"ldap_validator","package":"github.com/thestaticturtle/caddy-client-tls-ldap-validator","repo":"https://github.com/thestaticturtle/caddy-client-tls-ldap-validator"}],"tls.context":null,"tls.handshake_match":[{"name":"local_ip","docs":"local_ip matches based on the IP address of the interface\nreceiving the connection. Specific IPs or CIDR ranges can be specified.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"remote_ip","docs":"remote_ip matches based on the remote IP of the\nconnection. Specific IPs or CIDR ranges can be specified.\n\nNote that IPs can sometimes be spoofed, so do not rely\non this as a replacement for actual authentication.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"sni","docs":"sni matches based on SNI. Names in\nthis list may use left-most-label wildcards,\nsimilar to wildcard certificates.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"sni_regexp","docs":"sni_regexp matches based on SNI using a regular expression.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"alpn","package":"github.com/mholt/caddy-l4/modules/l4tls","repo":"https://github.com/mholt/caddy-l4"}],"tls.issuance":[{"name":"acme","docs":"acme manages certificates using the ACME protocol (RFC 8555).","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"internal","docs":"internal is a certificate issuer that generates\ncertificates internally using a locally-configured\nCA which can be customized using the `pki` app.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"zerossl","docs":"zerossl uses the ZeroSSL API to get certificates.\nNote that this is distinct from ZeroSSL's ACME endpoint.\nTo use ZeroSSL's ACME endpoint, use the ACMEIssuer\nconfigured with ZeroSSL's ACME directory endpoint.","package":"github.com/caddyserver/caddy/v2/modules/caddytls","repo":"https://github.com/caddyserver/caddy"},{"name":"certsrv","docs":"certsrv can request certificates from a\nMicrosoft Active Directory Certificate Services instance","package":"github.com/davidventura/caddy-certsrv","repo":"https://github.com/davidventura/caddy-certsrv"},{"name":"opportunistic","docs":"opportunistic is a TLS certificate issuer (module ID:\ntls.issuance.opportunistic) that selects between two inner issuers at\nissuance time based on whether DNS-01 prerequisites are met. When\nprerequisites are met it issues wildcard certificates via the primary issuer;\notherwise it falls back to the secondary issuer (typically HTTP-01 or\nTLS-ALPN-01). Subject transformation is registered automatically via\nSetConfig so no separate subject_transformer directive is required.","package":"github.com/pberkel/caddy-tls-issuer-opportunistic","repo":"https://github.com/pberkel/caddy-tls-issuer-opportunistic"},{"name":"rate_limit","docs":"rate_limit is a TLS issuer (module ID: tls.issuance.rate_limit) that\nwraps an inner certmagic.Issuer and enforces configurable issuance rate\nlimits.\n\nLimits are enforced at issuance time, after certmagic's SubjectTransformer\nhas run, so counts apply to the effective certificate subject — not the raw\nhostname from the TLS handshake. This makes RateLimitIssuer correct when\nused with tls.issuance.opportunistic, where multiple hostnames may map to\nthe same wildcard certificate.\n\n# Local limits\n\nRateLimit and PerDomainRateLimit are local to this instance — each\nRateLimitIssuer maintains independent in-memory windows.\n\n# Shared pools\n\nSharedPools allows multiple RateLimitIssuer instances within the same Caddy\nprocess to share rate limit state. Instances referencing the same pool name\nshare in-memory sliding windows. Shared pool state is persisted to Caddy's\nconfigured storage backend and restored on startup.","package":"github.com/pberkel/caddy-tls-issuer-rate-limit","repo":"https://github.com/pberkel/caddy-tls-issuer-rate-limit"}]},"breadcrumb":{"":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.Config","struct_fields":[{"key":"admin","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.AdminConfig","struct_fields":[{"key":"disabled","value":{"type":"bool","doc":"If true, the admin endpoint will be completely disabled.\nNote that this makes any runtime changes to the config\nimpossible, since the interface to do so is through the\nadmin endpoint."},"doc":"If true, the admin endpoint will be completely disabled.\nNote that this makes any runtime changes to the config\nimpossible, since the interface to do so is through the\nadmin endpoint."},{"key":"listen","value":{"type":"string","doc":"The address to which the admin endpoint's listener should\nbind itself. Can be any single network address that can be\nparsed by Caddy. Default: localhost:2019"},"doc":"The address to which the admin endpoint's listener should\nbind itself. Can be any single network address that can be\nparsed by Caddy. Default: localhost:2019"},{"key":"enforce_origin","value":{"type":"bool","doc":"If true, CORS headers will be emitted, and requests to the\nAPI will be rejected if their `Host` and `Origin` headers\ndo not match the expected value(s). Use `origins` to\ncustomize which origins/hosts are allowed. If `origins` is\nnot set, the listen address is the only value allowed by\ndefault. Enforced only on local (plaintext) endpoint."},"doc":"If true, CORS headers will be emitted, and requests to the\nAPI will be rejected if their `Host` and `Origin` headers\ndo not match the expected value(s). Use `origins` to\ncustomize which origins/hosts are allowed. If `origins` is\nnot set, the listen address is the only value allowed by\ndefault. Enforced only on local (plaintext) endpoint."},{"key":"origins","value":{"type":"array","elems":{"type":"string","doc":"The list of allowed origins/hosts for API requests. Only needed\nif accessing the admin endpoint from a host different from the\nsocket's network interface or if `enforce_origin` is true. If not\nset, the listener address will be the default value. If set but\nempty, no origins will be allowed. Enforced only on local\n(plaintext) endpoint."}},"doc":"The list of allowed origins/hosts for API requests. Only needed\nif accessing the admin endpoint from a host different from the\nsocket's network interface or if `enforce_origin` is true. If not\nset, the listener address will be the default value. If set but\nempty, no origins will be allowed. Enforced only on local\n(plaintext) endpoint."},{"key":"config","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.ConfigSettings","struct_fields":[{"key":"persist","value":{"type":"bool","doc":"Whether to keep a copy of the active config on disk. Default is true.\nNote that \"pulled\" dynamic configs (using the neighboring \"load\" module)\nare not persisted; only configs that are pushed to Caddy get persisted."},"doc":"Whether to keep a copy of the active config on disk. Default is true.\nNote that \"pulled\" dynamic configs (using the neighboring \"load\" module)\nare not persisted; only configs that are pushed to Caddy get persisted."},{"key":"load","value":{"type":"module","doc":"Loads a configuration to use. This is helpful if your configs are\nmanaged elsewhere, and you want Caddy to pull its config dynamically\nwhen it starts. The pulled config completely replaces the current\none, just like any other config load. It is an error if a pulled\nconfig is configured to pull another config.\n\nEXPERIMENTAL: Subject to change.","module_namespace":"caddy.config_loaders","module_inline_key":"module"},"doc":"Loads a configuration to use. This is helpful if your configs are\nmanaged elsewhere, and you want Caddy to pull its config dynamically\nwhen it starts. The pulled config completely replaces the current\none, just like any other config load. It is an error if a pulled\nconfig is configured to pull another config.\n\nEXPERIMENTAL: Subject to change."}],"doc":"Options pertaining to configuration management.\n\n\nConfigSettings configures the management of configuration."},"doc":"Options pertaining to configuration management.\n\n\nConfigSettings configures the management of configuration."},{"key":"identity","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.IdentityConfig","struct_fields":[{"key":"identifiers","value":{"type":"array","elems":{"type":"string","doc":"List of names or IP addresses which refer to this server.\nCertificates will be obtained for these identifiers so\nsecure TLS connections can be made using them."}},"doc":"List of names or IP addresses which refer to this server.\nCertificates will be obtained for these identifiers so\nsecure TLS connections can be made using them."},{"key":"issuers","value":{"type":"array","elems":{"type":"module","doc":"Issuers that can provide this admin endpoint its identity\ncertificate(s). Default: ACME issuers configured for\nZeroSSL and Let's Encrypt. Be sure to change this if you\nrequire credentials for private identifiers.","module_namespace":"tls.issuance","module_inline_key":"module"}},"doc":"Issuers that can provide this admin endpoint its identity\ncertificate(s). Default: ACME issuers configured for\nZeroSSL and Let's Encrypt. Be sure to change this if you\nrequire credentials for private identifiers."}],"doc":"Options that establish this server's identity. Identity refers to\ncredentials which can be used to uniquely identify and authenticate\nthis server instance. This is required if remote administration is\nenabled (but does not require remote administration to be enabled).\nDefault: no identity management.\n\n\nIdentityConfig configures management of this server's identity. An identity\nconsists of credentials that uniquely verify this instance; for example,\nTLS certificates (public + private key pairs)."},"doc":"Options that establish this server's identity. Identity refers to\ncredentials which can be used to uniquely identify and authenticate\nthis server instance. This is required if remote administration is\nenabled (but does not require remote administration to be enabled).\nDefault: no identity management.\n\n\nIdentityConfig configures management of this server's identity. An identity\nconsists of credentials that uniquely verify this instance; for example,\nTLS certificates (public + private key pairs)."},{"key":"remote","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.RemoteAdmin","struct_fields":[{"key":"listen","value":{"type":"string","doc":"The address on which to start the secure listener.\nDefault: :2021"},"doc":"The address on which to start the secure listener.\nDefault: :2021"},{"key":"access_control","value":{"type":"array","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.AdminAccess","struct_fields":[{"key":"public_keys","value":{"type":"array","elems":{"type":"string","doc":"Base64-encoded DER certificates containing public keys to accept.\n(The contents of PEM certificate blocks are base64-encoded DER.)\nAny of these public keys can appear in any part of a verified chain."}},"doc":"Base64-encoded DER certificates containing public keys to accept.\n(The contents of PEM certificate blocks are base64-encoded DER.)\nAny of these public keys can appear in any part of a verified chain."},{"key":"permissions","value":{"type":"array","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.AdminPermissions","struct_fields":[{"key":"paths","value":{"type":"array","elems":{"type":"string","doc":"The API paths allowed. Paths are simple prefix matches.\nAny subpath of the specified paths will be allowed."}},"doc":"The API paths allowed. Paths are simple prefix matches.\nAny subpath of the specified paths will be allowed."},{"key":"methods","value":{"type":"array","elems":{"type":"string","doc":"The HTTP methods allowed for the given paths."}},"doc":"The HTTP methods allowed for the given paths."}],"doc":"Limits what the associated identities are allowed to do.\nIf unspecified, all permissions are granted.\n\n\nAdminPermissions specifies what kinds of requests are allowed\nto be made to the admin endpoint."}},"doc":"Limits what the associated identities are allowed to do.\nIf unspecified, all permissions are granted.\n\n\nAdminPermissions specifies what kinds of requests are allowed\nto be made to the admin endpoint."}],"doc":"List of access controls for this secure admin endpoint.\nThis configures TLS mutual authentication (i.e. authorized\nclient certificates), but also application-layer permissions\nlike which paths and methods each identity is authorized for.\n\n\nAdminAccess specifies what permissions an identity or group\nof identities are granted."}},"doc":"List of access controls for this secure admin endpoint.\nThis configures TLS mutual authentication (i.e. authorized\nclient certificates), but also application-layer permissions\nlike which paths and methods each identity is authorized for.\n\n\nAdminAccess specifies what permissions an identity or group\nof identities are granted."}],"doc":"Options pertaining to remote administration. By default, remote\nadministration is disabled. If enabled, identity management must\nalso be configured, as that is how the endpoint is secured.\nSee the neighboring \"identity\" object.\n\nEXPERIMENTAL: This feature is subject to change.\n\n\nRemoteAdmin enables and configures remote administration. If enabled,\na secure listener enforcing mutual TLS authentication will be started\non a different port from the standard plaintext admin server.\n\nThis endpoint is secured using identity management, which must be\nconfigured separately (because identity management does not depend\non remote administration). See the admin/identity config struct.\n\nEXPERIMENTAL: Subject to change."},"doc":"Options pertaining to remote administration. By default, remote\nadministration is disabled. If enabled, identity management must\nalso be configured, as that is how the endpoint is secured.\nSee the neighboring \"identity\" object.\n\nEXPERIMENTAL: This feature is subject to change.\n\n\nRemoteAdmin enables and configures remote administration. If enabled,\na secure listener enforcing mutual TLS authentication will be started\non a different port from the standard plaintext admin server.\n\nThis endpoint is secured using identity management, which must be\nconfigured separately (because identity management does not depend\non remote administration). See the admin/identity config struct.\n\nEXPERIMENTAL: Subject to change."}],"doc":"AdminConfig configures Caddy's API endpoint, which is used\nto manage Caddy while it is running.\n"},"doc":"AdminConfig configures Caddy's API endpoint, which is used\nto manage Caddy while it is running.\n"},{"key":"logging","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.Logging","struct_fields":[{"key":"sink","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.StandardLibLog","struct_fields":[{"key":"writer","value":{"type":"module","doc":"The module that writes out log entries for the sink.","module_namespace":"caddy.logging.writers","module_inline_key":"output"},"doc":"The module that writes out log entries for the sink."}],"doc":"Sink is the destination for all unstructured logs emitted\nfrom Go's standard library logger. These logs are common\nin dependencies that are not designed specifically for use\nin Caddy. Because it is global and unstructured, the sink\nlacks most advanced features and customizations.\n\n\nStandardLibLog configures the default Go standard library\nglobal logger in the log package. This is necessary because\nmodule dependencies which are not built specifically for\nCaddy will use the standard logger. This is also known as\nthe \"sink\" logger."},"doc":"Sink is the destination for all unstructured logs emitted\nfrom Go's standard library logger. These logs are common\nin dependencies that are not designed specifically for use\nin Caddy. Because it is global and unstructured, the sink\nlacks most advanced features and customizations.\n\n\nStandardLibLog configures the default Go standard library\nglobal logger in the log package. This is necessary because\nmodule dependencies which are not built specifically for\nCaddy will use the standard logger. This is also known as\nthe \"sink\" logger."},{"key":"logs","value":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.CustomLog","struct_fields":[{"key":"writer","value":{"type":"module","doc":"The writer defines where log entries are emitted.","module_namespace":"caddy.logging.writers","module_inline_key":"output"},"doc":"The writer defines where log entries are emitted."},{"key":"encoder","value":{"type":"module","doc":"The encoder is how the log entries are formatted or encoded.","module_namespace":"caddy.logging.encoders","module_inline_key":"format"},"doc":"The encoder is how the log entries are formatted or encoded."},{"key":"level","value":{"type":"string","doc":"Level is the minimum level to emit, and is inclusive.\nPossible levels: DEBUG, INFO, WARN, ERROR, PANIC, and FATAL"},"doc":"Level is the minimum level to emit, and is inclusive.\nPossible levels: DEBUG, INFO, WARN, ERROR, PANIC, and FATAL"},{"key":"sampling","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2.LogSampling","struct_fields":[{"key":"interval","value":{"type":"int","type_name":"time.Duration","doc":"The window over which to conduct sampling.\n\n\nA Duration represents the elapsed time between two instants\nas an int64 nanosecond count. The representation limits the\nlargest representable duration to approximately 290 years."},"doc":"The window over which to conduct sampling.\n\n\nA Duration represents the elapsed time between two instants\nas an int64 nanosecond count. The representation limits the\nlargest representable duration to approximately 290 years."},{"key":"first","value":{"type":"int","doc":"Log this many entries within a given level and\nmessage for each interval."},"doc":"Log this many entries within a given level and\nmessage for each interval."},{"key":"thereafter","value":{"type":"int","doc":"If more entries with the same level and message\nare seen during the same interval, keep one in\nthis many entries until the end of the interval."},"doc":"If more entries with the same level and message\nare seen during the same interval, keep one in\nthis many entries until the end of the interval."}],"doc":"Sampling configures log entry sampling. If enabled,\nonly some log entries will be emitted. This is useful\nfor improving performance on extremely high-pressure\nservers.\n\n\nLogSampling configures log entry sampling."},"doc":"Sampling configures log entry sampling. If enabled,\nonly some log entries will be emitted. This is useful\nfor improving performance on extremely high-pressure\nservers.\n\n\nLogSampling configures log entry sampling."},{"key":"include","value":{"type":"array","elems":{"type":"string","doc":"Include defines the names of loggers to emit in this\nlog. For example, to include only logs emitted by the\nadmin API, you would include \"admin.api\"."}},"doc":"Include defines the names of loggers to emit in this\nlog. For example, to include only logs emitted by the\nadmin API, you would include \"admin.api\"."},{"key":"exclude","value":{"type":"array","elems":{"type":"string","doc":"Exclude defines the names of loggers that should be\nskipped by this log. For example, to exclude only\nHTTP access logs, you would exclude \"http.log.access\"."}},"doc":"Exclude defines the names of loggers that should be\nskipped by this log. For example, to exclude only\nHTTP access logs, you would exclude \"http.log.access\"."}],"doc":"Logs are your logs, keyed by an arbitrary name of your\nchoosing. The default log can be customized by defining\na log called \"default\". You can further define other logs\nand filter what kinds of entries they accept.\n\n\nCustomLog represents a custom logger configuration.\n\nBy default, a log will emit all log entries. Some entries\nwill be skipped if sampling is enabled. Further, the Include\nand Exclude parameters define which loggers (by name) are\nallowed or rejected from emitting in this log. If both Include\nand Exclude are populated, their values must be mutually\nexclusive, and longer namespaces have priority. If neither\nare populated, all logs are emitted."}},"doc":"Logs are your logs, keyed by an arbitrary name of your\nchoosing. The default log can be customized by defining\na log called \"default\". You can further define other logs\nand filter what kinds of entries they accept.\n\n\nCustomLog represents a custom logger configuration.\n\nBy default, a log will emit all log entries. Some entries\nwill be skipped if sampling is enabled. Further, the Include\nand Exclude parameters define which loggers (by name) are\nallowed or rejected from emitting in this log. If both Include\nand Exclude are populated, their values must be mutually\nexclusive, and longer namespaces have priority. If neither\nare populated, all logs are emitted."}],"doc":"Logging facilitates logging within Caddy. The default log is\ncalled \"default\" and you can customize it. You can also define\nadditional logs.\n\nBy default, all logs at INFO level and higher are written to\nstandard error (\"stderr\" writer) in a human-readable format\n(\"console\" encoder if stdout is an interactive terminal, \"json\"\nencoder otherwise).\n\nAll defined logs accept all log entries by default, but you\ncan filter by level and module/logger names. A logger's name\nis the same as the module's name, but a module may append to\nlogger names for more specificity. For example, you can\nfilter logs emitted only by HTTP handlers using the name\n\"http.handlers\", because all HTTP handler module names have\nthat prefix.\n\nCaddy logs (except the sink) are zero-allocation, so they are\nvery high-performing in terms of memory and CPU time. Enabling\nsampling can further increase throughput on extremely high-load\nservers.\n"},"doc":"Logging facilitates logging within Caddy. The default log is\ncalled \"default\" and you can customize it. You can also define\nadditional logs.\n\nBy default, all logs at INFO level and higher are written to\nstandard error (\"stderr\" writer) in a human-readable format\n(\"console\" encoder if stdout is an interactive terminal, \"json\"\nencoder otherwise).\n\nAll defined logs accept all log entries by default, but you\ncan filter by level and module/logger names. A logger's name\nis the same as the module's name, but a module may append to\nlogger names for more specificity. For example, you can\nfilter logs emitted only by HTTP handlers using the name\n\"http.handlers\", because all HTTP handler module names have\nthat prefix.\n\nCaddy logs (except the sink) are zero-allocation, so they are\nvery high-performing in terms of memory and CPU time. Enabling\nsampling can further increase throughput on extremely high-load\nservers.\n"},{"key":"storage","value":{"type":"module","doc":"StorageRaw is a storage module that defines how/where Caddy\nstores assets (such as TLS certificates). The default storage\nmodule is `caddy.storage.file_system` (the local file system),\nand the default path\n[depends on the OS and environment](/docs/conventions#data-directory).","module_namespace":"caddy.storage","module_inline_key":"module"},"doc":"StorageRaw is a storage module that defines how/where Caddy\nstores assets (such as TLS certificates). The default storage\nmodule is `caddy.storage.file_system` (the local file system),\nand the default path\n[depends on the OS and environment](/docs/conventions#data-directory)."},{"key":"apps","value":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"AppsRaw are the apps that Caddy will load and run. The\napp module name is the key, and the app's config is the\nassociated value.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":""},"doc":"AppsRaw are the apps that Caddy will load and run. The\napp module name is the key, and the app's config is the\nassociated value.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."}],"doc":"Config is the top (or beginning) of the Caddy configuration structure.\nCaddy config is expressed natively as a JSON document. If you prefer\nnot to work with JSON directly, there are [many config adapters](/docs/config-adapters)\navailable that can convert various inputs into Caddy JSON.\n\nMany parts of this config are extensible through the use of Caddy modules.\nFields which have a json.RawMessage type and which appear as dots (•••) in\nthe online docs can be fulfilled by modules in a certain module\nnamespace. The docs show which modules can be used in a given place.\n\nWhenever a module is used, its name must be given either inline as part of\nthe module, or as the key to the module's value. The docs will make it clear\nwhich to use.\n\nGenerally, all config settings are optional, as it is Caddy convention to\nhave good, documented default values. If a parameter is required, the docs\nshould say so.\n\nGo programs which are directly building a Config struct value should take\ncare to populate the JSON-encodable fields of the struct (i.e. the fields\nwith `json` struct tags) if employing the module lifecycle (e.g. Provision\nmethod calls).\n"},"apps":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"AppsRaw are the apps that Caddy will load and run. The\napp module name is the key, and the app's config is the\nassociated value.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.\n","module_namespace":""},"apps/http":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.App","struct_fields":[{"key":"http_port","value":{"type":"int","doc":"HTTPPort specifies the port to use for HTTP (as opposed to HTTPS),\nwhich is used when setting up HTTP-\u003eHTTPS redirects or ACME HTTP\nchallenge solvers. Default: 80."},"doc":"HTTPPort specifies the port to use for HTTP (as opposed to HTTPS),\nwhich is used when setting up HTTP-\u003eHTTPS redirects or ACME HTTP\nchallenge solvers. Default: 80."},{"key":"https_port","value":{"type":"int","doc":"HTTPSPort specifies the port to use for HTTPS, which is used when\nsolving the ACME TLS-ALPN challenges, or whenever HTTPS is needed\nbut no specific port number is given. Default: 443."},"doc":"HTTPSPort specifies the port to use for HTTPS, which is used when\nsolving the ACME TLS-ALPN challenges, or whenever HTTPS is needed\nbut no specific port number is given. Default: 443."},{"key":"grace_period","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"GracePeriod is how long to wait for active connections when shutting\ndown the servers. During the grace period, no new connections are\naccepted, idle connections are closed, and active connections will\nbe given the full length of time to become idle and close.\nOnce the grace period is over, connections will be forcefully closed.\nIf zero, the grace period is eternal. Default: 0.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"GracePeriod is how long to wait for active connections when shutting\ndown the servers. During the grace period, no new connections are\naccepted, idle connections are closed, and active connections will\nbe given the full length of time to become idle and close.\nOnce the grace period is over, connections will be forcefully closed.\nIf zero, the grace period is eternal. Default: 0.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"shutdown_delay","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"ShutdownDelay is how long to wait before initiating the grace\nperiod. When this app is stopping (e.g. during a config reload or\nprocess exit), all servers will be shut down. Normally this immediately\ninitiates the grace period. However, if this delay is configured, servers\nwill not be shut down until the delay is over. During this time, servers\ncontinue to function normally and allow new connections. At the end, the\ngrace period will begin. This can be useful to allow downstream load\nbalancers time to move this instance out of the rotation without hiccups.\n\nWhen shutdown has been scheduled, placeholders {http.shutting_down} (bool)\nand {http.time_until_shutdown} (duration) may be useful for health checks.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"ShutdownDelay is how long to wait before initiating the grace\nperiod. When this app is stopping (e.g. during a config reload or\nprocess exit), all servers will be shut down. Normally this immediately\ninitiates the grace period. However, if this delay is configured, servers\nwill not be shut down until the delay is over. During this time, servers\ncontinue to function normally and allow new connections. At the end, the\ngrace period will begin. This can be useful to allow downstream load\nbalancers time to move this instance out of the rotation without hiccups.\n\nWhen shutdown has been scheduled, placeholders {http.shutting_down} (bool)\nand {http.time_until_shutdown} (duration) may be useful for health checks.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"servers","value":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Server","struct_fields":[{"key":"listen","value":{"type":"array","elems":{"type":"string","doc":"Socket addresses to which to bind listeners. Accepts\n[network addresses](/docs/conventions#network-addresses)\nthat may include port ranges. Listener addresses must\nbe unique; they cannot be repeated across all defined\nservers."}},"doc":"Socket addresses to which to bind listeners. Accepts\n[network addresses](/docs/conventions#network-addresses)\nthat may include port ranges. Listener addresses must\nbe unique; they cannot be repeated across all defined\nservers."},{"key":"listener_wrappers","value":{"type":"array","elems":{"type":"module","doc":"A list of listener wrapper modules, which can modify the behavior\nof the base listener. They are applied in the given order.","module_namespace":"caddy.listeners","module_inline_key":"wrapper"}},"doc":"A list of listener wrapper modules, which can modify the behavior\nof the base listener. They are applied in the given order."},{"key":"read_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"How long to allow a read from a client's upload. Setting this\nto a short, non-zero value can mitigate slowloris attacks, but\nmay also affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"How long to allow a read from a client's upload. Setting this\nto a short, non-zero value can mitigate slowloris attacks, but\nmay also affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"read_header_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"ReadHeaderTimeout is like ReadTimeout but for request headers.\nDefault is 1 minute.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"ReadHeaderTimeout is like ReadTimeout but for request headers.\nDefault is 1 minute.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"write_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"WriteTimeout is how long to allow a write to a client. Note\nthat setting this to a small value when serving large files\nmay negatively affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"WriteTimeout is how long to allow a write to a client. Note\nthat setting this to a small value when serving large files\nmay negatively affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"idle_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"IdleTimeout is the maximum time to wait for the next request\nwhen keep-alives are enabled. If zero, a default timeout of\n5m is applied to help avoid resource exhaustion.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"IdleTimeout is the maximum time to wait for the next request\nwhen keep-alives are enabled. If zero, a default timeout of\n5m is applied to help avoid resource exhaustion.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"keepalive_interval","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"KeepAliveInterval is the interval at which TCP keepalive packets\nare sent to keep the connection alive at the TCP layer when no other\ndata is being transmitted. The default is 15s.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"KeepAliveInterval is the interval at which TCP keepalive packets\nare sent to keep the connection alive at the TCP layer when no other\ndata is being transmitted. The default is 15s.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"max_header_bytes","value":{"type":"int","doc":"MaxHeaderBytes is the maximum size to parse from a client's\nHTTP request headers."},"doc":"MaxHeaderBytes is the maximum size to parse from a client's\nHTTP request headers."},{"key":"enable_full_duplex","value":{"type":"bool","doc":"Enable full-duplex communication for HTTP/1 requests.\nOnly has an effect if Caddy was built with Go 1.21 or later.\n\nFor HTTP/1 requests, the Go HTTP server by default consumes any\nunread portion of the request body before beginning to write the\nresponse, preventing handlers from concurrently reading from the\nrequest and writing the response. Enabling this option disables\nthis behavior and permits handlers to continue to read from the\nrequest while concurrently writing the response.\n\nFor HTTP/2 requests, the Go HTTP server always permits concurrent\nreads and responses, so this option has no effect.\n\nTest thoroughly with your HTTP clients, as some older clients may\nnot support full-duplex HTTP/1 which can cause them to deadlock.\nSee https://github.com/golang/go/issues/57786 for more info.\n\nTODO: This is an EXPERIMENTAL feature. Subject to change or removal."},"doc":"Enable full-duplex communication for HTTP/1 requests.\nOnly has an effect if Caddy was built with Go 1.21 or later.\n\nFor HTTP/1 requests, the Go HTTP server by default consumes any\nunread portion of the request body before beginning to write the\nresponse, preventing handlers from concurrently reading from the\nrequest and writing the response. Enabling this option disables\nthis behavior and permits handlers to continue to read from the\nrequest while concurrently writing the response.\n\nFor HTTP/2 requests, the Go HTTP server always permits concurrent\nreads and responses, so this option has no effect.\n\nTest thoroughly with your HTTP clients, as some older clients may\nnot support full-duplex HTTP/1 which can cause them to deadlock.\nSee https://github.com/golang/go/issues/57786 for more info.\n\nTODO: This is an EXPERIMENTAL feature. Subject to change or removal."},{"key":"routes","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RouteList","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"Routes describes how this server will handle requests.\nRoutes are executed sequentially. First a route's matchers\nare evaluated, then its grouping. If it matches and has\nnot been mutually-excluded by its grouping, then its\nhandlers are executed sequentially. The sequence of invoked\nhandlers comprises a compiled middleware chain that flows\nfrom each matching route and its handlers to the next.\n\nBy default, all unrouted requests receive a 200 OK response\nto indicate the server is working.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},"doc":"RouteList is a list of server routes that can\ncreate a middleware chain.\n"},"doc":"Routes describes how this server will handle requests.\nRoutes are executed sequentially. First a route's matchers\nare evaluated, then its grouping. If it matches and has\nnot been mutually-excluded by its grouping, then its\nhandlers are executed sequentially. The sequence of invoked\nhandlers comprises a compiled middleware chain that flows\nfrom each matching route and its handlers to the next.\n\nBy default, all unrouted requests receive a 200 OK response\nto indicate the server is working.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},{"key":"errors","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.HTTPErrorConfig","struct_fields":[{"key":"routes","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RouteList","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"The routes to evaluate after the primary handler\nchain returns an error. In an error route, extra\nplaceholders are available:\n\nPlaceholder | Description\n------------|---------------\n`{http.error.status_code}` | The recommended HTTP status code\n`{http.error.status_text}` | The status text associated with the recommended status code\n`{http.error.message}`     | The error message\n`{http.error.trace}`       | The origin of the error\n`{http.error.id}`          | An identifier for this occurrence of the error\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},"doc":"RouteList is a list of server routes that can\ncreate a middleware chain.\n"},"doc":"The routes to evaluate after the primary handler\nchain returns an error. In an error route, extra\nplaceholders are available:\n\nPlaceholder | Description\n------------|---------------\n`{http.error.status_code}` | The recommended HTTP status code\n`{http.error.status_text}` | The status text associated with the recommended status code\n`{http.error.message}`     | The error message\n`{http.error.trace}`       | The origin of the error\n`{http.error.id}`          | An identifier for this occurrence of the error\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."}],"doc":"Errors is how this server will handle errors returned from any\nof the handlers in the primary routes. If the primary handler\nchain returns an error, the error along with its recommended\nstatus code are bubbled back up to the HTTP server which\nexecutes a separate error route, specified using this property.\nThe error routes work exactly like the normal routes.\n\n\nHTTPErrorConfig determines how to handle errors\nfrom the HTTP handlers."},"doc":"Errors is how this server will handle errors returned from any\nof the handlers in the primary routes. If the primary handler\nchain returns an error, the error along with its recommended\nstatus code are bubbled back up to the HTTP server which\nexecutes a separate error route, specified using this property.\nThe error routes work exactly like the normal routes.\n\n\nHTTPErrorConfig determines how to handle errors\nfrom the HTTP handlers."},{"key":"named_routes","value":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"NamedRoutes describes a mapping of reusable routes that can be\ninvoked by their name. This can be used to optimize memory usage\nwhen the same route is needed for many subroutes, by having\nthe handlers and matchers be only provisioned once, but used from\nmany places. These routes are not executed unless they are invoked\nfrom another route.\n\nEXPERIMENTAL: Subject to change or removal.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."}},"doc":"NamedRoutes describes a mapping of reusable routes that can be\ninvoked by their name. This can be used to optimize memory usage\nwhen the same route is needed for many subroutes, by having\nthe handlers and matchers be only provisioned once, but used from\nmany places. These routes are not executed unless they are invoked\nfrom another route.\n\nEXPERIMENTAL: Subject to change or removal.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},{"key":"tls_connection_policies","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.ConnectionPolicies","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.ConnectionPolicy","struct_fields":[{"key":"match","value":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"How to match this policy with a TLS ClientHello. If\nthis policy is the first to match, it will be used.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"tls.handshake_match"},"doc":"How to match this policy with a TLS ClientHello. If\nthis policy is the first to match, it will be used.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"certificate_selection","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.CustomCertSelectionPolicy","struct_fields":[{"key":"serial_number","value":{"type":"array","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.bigInt","doc":"The certificate must have one of these serial numbers.\n\n\nbigInt is a big.Int type that interops with JSON encodings as a string."}},"doc":"The certificate must have one of these serial numbers.\n\n\nbigInt is a big.Int type that interops with JSON encodings as a string."},{"key":"subject_organization","value":{"type":"array","elems":{"type":"string","doc":"The certificate must have one of these organization names."}},"doc":"The certificate must have one of these organization names."},{"key":"public_key_algorithm","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.PublicKeyAlgorithm","doc":"The certificate must use this public key algorithm.\n\n\nPublicKeyAlgorithm is a JSON-unmarshalable wrapper type."},"doc":"The certificate must use this public key algorithm.\n\n\nPublicKeyAlgorithm is a JSON-unmarshalable wrapper type."},{"key":"any_tag","value":{"type":"array","elems":{"type":"string","doc":"The certificate must have at least one of the tags in the list."}},"doc":"The certificate must have at least one of the tags in the list."},{"key":"all_tags","value":{"type":"array","elems":{"type":"string","doc":"The certificate must have all of the tags in the list."}},"doc":"The certificate must have all of the tags in the list."}],"doc":"How to choose a certificate if more than one matched\nthe given ServerName (SNI) value.\n\n\nCustomCertSelectionPolicy represents a policy for selecting the certificate\nused to complete a handshake when there may be multiple options. All fields\nspecified must match the candidate certificate for it to be chosen.\nThis was needed to solve https://github.com/caddyserver/caddy/issues/2588."},"doc":"How to choose a certificate if more than one matched\nthe given ServerName (SNI) value.\n\n\nCustomCertSelectionPolicy represents a policy for selecting the certificate\nused to complete a handshake when there may be multiple options. All fields\nspecified must match the candidate certificate for it to be chosen.\nThis was needed to solve https://github.com/caddyserver/caddy/issues/2588."},{"key":"cipher_suites","value":{"type":"array","elems":{"type":"string","doc":"The list of cipher suites to support. Caddy's\ndefaults are modern and secure."}},"doc":"The list of cipher suites to support. Caddy's\ndefaults are modern and secure."},{"key":"curves","value":{"type":"array","elems":{"type":"string","doc":"The list of elliptic curves to support. Caddy's\ndefaults are modern and secure."}},"doc":"The list of elliptic curves to support. Caddy's\ndefaults are modern and secure."},{"key":"alpn","value":{"type":"array","elems":{"type":"string","doc":"Protocols to use for Application-Layer Protocol\nNegotiation (ALPN) during the handshake."}},"doc":"Protocols to use for Application-Layer Protocol\nNegotiation (ALPN) during the handshake."},{"key":"protocol_min","value":{"type":"string","doc":"Minimum TLS protocol version to allow. Default: `tls1.2`"},"doc":"Minimum TLS protocol version to allow. Default: `tls1.2`"},{"key":"protocol_max","value":{"type":"string","doc":"Maximum TLS protocol version to allow. Default: `tls1.3`"},"doc":"Maximum TLS protocol version to allow. Default: `tls1.3`"},{"key":"drop","value":{"type":"bool","doc":"Reject TLS connections. EXPERIMENTAL: May change."},"doc":"Reject TLS connections. EXPERIMENTAL: May change."},{"key":"client_authentication","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.ClientAuthentication","struct_fields":[{"key":"ca","value":{"type":"module","doc":"Certificate authority module which provides the certificate pool of trusted certificates","module_namespace":"tls.ca_pool.source","module_inline_key":"provider"},"doc":"Certificate authority module which provides the certificate pool of trusted certificates"},{"key":"trusted_ca_certs","value":{"type":"array","elems":{"type":"string","doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.inline` module instead.\nA list of base64 DER-encoded CA certificates\nagainst which to validate client certificates.\nClient certs which are not signed by any of\nthese CAs will be rejected."}},"doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.inline` module instead.\nA list of base64 DER-encoded CA certificates\nagainst which to validate client certificates.\nClient certs which are not signed by any of\nthese CAs will be rejected."},{"key":"trusted_ca_certs_pem_files","value":{"type":"array","elems":{"type":"string","doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.file` module instead.\nTrustedCACertPEMFiles is a list of PEM file names\nfrom which to load certificates of trusted CAs.\nClient certificates which are not signed by any of\nthese CA certificates will be rejected."}},"doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.file` module instead.\nTrustedCACertPEMFiles is a list of PEM file names\nfrom which to load certificates of trusted CAs.\nClient certificates which are not signed by any of\nthese CA certificates will be rejected."},{"key":"trusted_leaf_certs","value":{"type":"array","elems":{"type":"string","doc":"Deprecated: This field is deprecated and will be removed in\na future version. Please use the `validators` field instead\nwith the tls.client_auth.verifier.leaf module instead.\n\nA list of base64 DER-encoded client leaf certs\nto accept. If this list is not empty, client certs\nwhich are not in this list will be rejected."}},"doc":"Deprecated: This field is deprecated and will be removed in\na future version. Please use the `validators` field instead\nwith the tls.client_auth.verifier.leaf module instead.\n\nA list of base64 DER-encoded client leaf certs\nto accept. If this list is not empty, client certs\nwhich are not in this list will be rejected."},{"key":"verifiers","value":{"type":"array","elems":{"type":"module","doc":"Client certificate verification modules. These can perform\ncustom client authentication checks, such as ensuring the\ncertificate is not revoked.","module_namespace":"tls.client_auth.verifier","module_inline_key":"verifier"}},"doc":"Client certificate verification modules. These can perform\ncustom client authentication checks, such as ensuring the\ncertificate is not revoked."},{"key":"mode","value":{"type":"string","doc":"The mode for authenticating the client. Allowed values are:\n\nMode | Description\n-----|---------------\n`request` | Ask clients for a certificate, but allow even if there isn't one; do not verify it\n`require` | Require clients to present a certificate, but do not verify it\n`verify_if_given` | Ask clients for a certificate; allow even if there isn't one, but verify it if there is\n`require_and_verify` | Require clients to present a valid certificate that is verified\n\nThe default mode is `require_and_verify` if any\nTrustedCACerts or TrustedCACertPEMFiles or TrustedLeafCerts\nare provided; otherwise, the default mode is `require`."},"doc":"The mode for authenticating the client. Allowed values are:\n\nMode | Description\n-----|---------------\n`request` | Ask clients for a certificate, but allow even if there isn't one; do not verify it\n`require` | Require clients to present a certificate, but do not verify it\n`verify_if_given` | Ask clients for a certificate; allow even if there isn't one, but verify it if there is\n`require_and_verify` | Require clients to present a valid certificate that is verified\n\nThe default mode is `require_and_verify` if any\nTrustedCACerts or TrustedCACertPEMFiles or TrustedLeafCerts\nare provided; otherwise, the default mode is `require`."}],"doc":"Enables and configures TLS client authentication.\n\n\nClientAuthentication configures TLS client auth."},"doc":"Enables and configures TLS client authentication.\n\n\nClientAuthentication configures TLS client auth."},{"key":"default_sni","value":{"type":"string","doc":"DefaultSNI becomes the ServerName in a ClientHello if there\nis no policy configured for the empty SNI value."},"doc":"DefaultSNI becomes the ServerName in a ClientHello if there\nis no policy configured for the empty SNI value."},{"key":"fallback_sni","value":{"type":"string","doc":"FallbackSNI becomes the ServerName in a ClientHello if\nthe original ServerName doesn't match any certificates\nin the cache. The use cases for this are very niche;\ntypically if a client is a CDN and passes through the\nServerName of the downstream handshake but can accept\na certificate with the origin's hostname instead, then\nyou would set this to your origin's hostname. Note that\nCaddy must be managing a certificate for this name.\n\nThis feature is EXPERIMENTAL and subject to change or removal."},"doc":"FallbackSNI becomes the ServerName in a ClientHello if\nthe original ServerName doesn't match any certificates\nin the cache. The use cases for this are very niche;\ntypically if a client is a CDN and passes through the\nServerName of the downstream handshake but can accept\na certificate with the origin's hostname instead, then\nyou would set this to your origin's hostname. Note that\nCaddy must be managing a certificate for this name.\n\nThis feature is EXPERIMENTAL and subject to change or removal."},{"key":"insecure_secrets_log","value":{"type":"string","doc":"Also known as \"SSLKEYLOGFILE\", TLS secrets will be written to\nthis file in NSS key log format which can then be parsed by\nWireshark and other tools. This is INSECURE as it allows other\nprograms or tools to decrypt TLS connections. However, this\ncapability can be useful for debugging and troubleshooting.\n**ENABLING THIS LOG COMPROMISES SECURITY!**\n\nThis feature is EXPERIMENTAL and subject to change or removal."},"doc":"Also known as \"SSLKEYLOGFILE\", TLS secrets will be written to\nthis file in NSS key log format which can then be parsed by\nWireshark and other tools. This is INSECURE as it allows other\nprograms or tools to decrypt TLS connections. However, this\ncapability can be useful for debugging and troubleshooting.\n**ENABLING THIS LOG COMPROMISES SECURITY!**\n\nThis feature is EXPERIMENTAL and subject to change or removal."},{"key":"handshake_context","value":{"type":"module","doc":"A module that can manipulate the context passed into CertMagic's\ncertificate management functions during TLS handshakes.\nEXPERIMENTAL - subject to change or removal.","module_namespace":"tls.context","module_inline_key":"module"},"doc":"A module that can manipulate the context passed into CertMagic's\ncertificate management functions during TLS handshakes.\nEXPERIMENTAL - subject to change or removal."}],"doc":"How to handle TLS connections. At least one policy is\nrequired to enable HTTPS on this server if automatic\nHTTPS is disabled or does not apply.\n\n\nConnectionPolicy specifies the logic for handling a TLS handshake.\nAn empty policy is valid; safe and sensible defaults will be used."},"doc":"ConnectionPolicies govern the establishment of TLS connections. It is\nan ordered group of connection policies; the first matching policy will\nbe used to configure TLS connections at handshake-time.\n"},"doc":"How to handle TLS connections. At least one policy is\nrequired to enable HTTPS on this server if automatic\nHTTPS is disabled or does not apply.\n\n\nConnectionPolicy specifies the logic for handling a TLS handshake.\nAn empty policy is valid; safe and sensible defaults will be used."},{"key":"automatic_https","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.AutoHTTPSConfig","struct_fields":[{"key":"disable","value":{"type":"bool","doc":"If true, automatic HTTPS will be entirely disabled,\nincluding certificate management and redirects."},"doc":"If true, automatic HTTPS will be entirely disabled,\nincluding certificate management and redirects."},{"key":"disable_redirects","value":{"type":"bool","doc":"If true, only automatic HTTP-\u003eHTTPS redirects will\nbe disabled, but other auto-HTTPS features will\nremain enabled."},"doc":"If true, only automatic HTTP-\u003eHTTPS redirects will\nbe disabled, but other auto-HTTPS features will\nremain enabled."},{"key":"disable_certificates","value":{"type":"bool","doc":"If true, automatic certificate management will be\ndisabled, but other auto-HTTPS features will\nremain enabled."},"doc":"If true, automatic certificate management will be\ndisabled, but other auto-HTTPS features will\nremain enabled."},{"key":"skip","value":{"type":"array","elems":{"type":"string","doc":"Hosts/domain names listed here will not be included\nin automatic HTTPS (they will not have certificates\nloaded nor redirects applied)."}},"doc":"Hosts/domain names listed here will not be included\nin automatic HTTPS (they will not have certificates\nloaded nor redirects applied)."},{"key":"skip_certificates","value":{"type":"array","elems":{"type":"string","doc":"Hosts/domain names listed here will still be enabled\nfor automatic HTTPS (unless in the Skip list), except\nthat certificates will not be provisioned and managed\nfor these names."}},"doc":"Hosts/domain names listed here will still be enabled\nfor automatic HTTPS (unless in the Skip list), except\nthat certificates will not be provisioned and managed\nfor these names."},{"key":"ignore_loaded_certificates","value":{"type":"bool","doc":"By default, automatic HTTPS will obtain and renew\ncertificates for qualifying hostnames. However, if\na certificate with a matching SAN is already loaded\ninto the cache, certificate management will not be\nenabled. To force automated certificate management\nregardless of loaded certificates, set this to true."},"doc":"By default, automatic HTTPS will obtain and renew\ncertificates for qualifying hostnames. However, if\na certificate with a matching SAN is already loaded\ninto the cache, certificate management will not be\nenabled. To force automated certificate management\nregardless of loaded certificates, set this to true."},{"key":"prefer_wildcard","value":{"type":"bool","doc":"If true, automatic HTTPS will prefer wildcard names\nand ignore non-wildcard names if both are available.\nThis allows for writing a config with top-level host\nmatchers without having those names produce certificates."},"doc":"If true, automatic HTTPS will prefer wildcard names\nand ignore non-wildcard names if both are available.\nThis allows for writing a config with top-level host\nmatchers without having those names produce certificates."}],"doc":"AutoHTTPS configures or disables automatic HTTPS within this server.\nHTTPS is enabled automatically and by default when qualifying names\nare present in a Host matcher and/or when the server is listening\nonly on the HTTPS port.\n\n\nAutoHTTPSConfig is used to disable automatic HTTPS\nor certain aspects of it for a specific server.\nHTTPS is enabled automatically and by default when\nqualifying hostnames are available from the config."},"doc":"AutoHTTPS configures or disables automatic HTTPS within this server.\nHTTPS is enabled automatically and by default when qualifying names\nare present in a Host matcher and/or when the server is listening\nonly on the HTTPS port.\n\n\nAutoHTTPSConfig is used to disable automatic HTTPS\nor certain aspects of it for a specific server.\nHTTPS is enabled automatically and by default when\nqualifying hostnames are available from the config."},{"key":"strict_sni_host","value":{"type":"bool","doc":"If true, will require that a request's Host header match\nthe value of the ServerName sent by the client's TLS\nClientHello; often a necessary safeguard when using TLS\nclient authentication."},"doc":"If true, will require that a request's Host header match\nthe value of the ServerName sent by the client's TLS\nClientHello; often a necessary safeguard when using TLS\nclient authentication."},{"key":"trusted_proxies","value":{"type":"module","doc":"A module which provides a source of IP ranges, from which\nrequests should be trusted. By default, no proxies are\ntrusted.\n\nOn its own, this configuration will not do anything,\nbut it can be used as a default set of ranges for\nhandlers or matchers in routes to pick up, instead\nof needing to configure each of them. See the\n`reverse_proxy` handler for example, which uses this\nto trust sensitive incoming `X-Forwarded-*` headers.","module_namespace":"http.ip_sources","module_inline_key":"source"},"doc":"A module which provides a source of IP ranges, from which\nrequests should be trusted. By default, no proxies are\ntrusted.\n\nOn its own, this configuration will not do anything,\nbut it can be used as a default set of ranges for\nhandlers or matchers in routes to pick up, instead\nof needing to configure each of them. See the\n`reverse_proxy` handler for example, which uses this\nto trust sensitive incoming `X-Forwarded-*` headers."},{"key":"client_ip_headers","value":{"type":"array","elems":{"type":"string","doc":"The headers from which the client IP address could be\nread from. These will be considered in order, with the\nfirst good value being used as the client IP.\nBy default, only `X-Forwarded-For` is considered.\n\nThis depends on `trusted_proxies` being configured and\nthe request being validated as coming from a trusted\nproxy, otherwise the client IP will be set to the direct\nremote IP address."}},"doc":"The headers from which the client IP address could be\nread from. These will be considered in order, with the\nfirst good value being used as the client IP.\nBy default, only `X-Forwarded-For` is considered.\n\nThis depends on `trusted_proxies` being configured and\nthe request being validated as coming from a trusted\nproxy, otherwise the client IP will be set to the direct\nremote IP address."},{"key":"trusted_proxies_strict","value":{"type":"int","doc":"If greater than zero, enables strict ClientIPHeaders\n(default X-Forwarded-For) parsing. If enabled, the\nClientIPHeaders will be parsed from right to left, and\nthe first value that is both valid and doesn't match the\ntrusted proxy list will be used as client IP. If zero,\nthe ClientIPHeaders will be parsed from left to right,\nand the first value that is a valid IP address will be\nused as client IP.\n\nThis depends on `trusted_proxies` being configured.\nThis option is disabled by default."},"doc":"If greater than zero, enables strict ClientIPHeaders\n(default X-Forwarded-For) parsing. If enabled, the\nClientIPHeaders will be parsed from right to left, and\nthe first value that is both valid and doesn't match the\ntrusted proxy list will be used as client IP. If zero,\nthe ClientIPHeaders will be parsed from left to right,\nand the first value that is a valid IP address will be\nused as client IP.\n\nThis depends on `trusted_proxies` being configured.\nThis option is disabled by default."},{"key":"logs","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.ServerLogConfig","struct_fields":[{"key":"default_logger_name","value":{"type":"string","doc":"The default logger name for all logs emitted by this server for\nhostnames that are not in the logger_names map."},"doc":"The default logger name for all logs emitted by this server for\nhostnames that are not in the logger_names map."},{"key":"logger_names","value":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.StringArray","elems":{"type":"string"},"doc":"LoggerNames maps request hostnames to one or more custom logger\nnames. For example, a mapping of `\"example.com\": [\"example\"]` would\ncause access logs from requests with a Host of example.com to be\nemitted by a logger named \"http.log.access.example\". If there are\nmultiple logger names, then the log will be emitted to all of them.\nIf the logger name is an empty, the default logger is used, i.e.\nthe logger \"http.log.access\".\n\nKeys must be hostnames (without ports), and may contain wildcards\nto match subdomains. The value is an array of logger names.\n\nFor backwards compatibility, if the value is a string, it is treated\nas a single-element array.\n\n\nStringArray is a slices of strings, but also accepts\na single string as a value when JSON unmarshaling,\nconverting it to a slice of one string."}},"doc":"LoggerNames maps request hostnames to one or more custom logger\nnames. For example, a mapping of `\"example.com\": [\"example\"]` would\ncause access logs from requests with a Host of example.com to be\nemitted by a logger named \"http.log.access.example\". If there are\nmultiple logger names, then the log will be emitted to all of them.\nIf the logger name is an empty, the default logger is used, i.e.\nthe logger \"http.log.access\".\n\nKeys must be hostnames (without ports), and may contain wildcards\nto match subdomains. The value is an array of logger names.\n\nFor backwards compatibility, if the value is a string, it is treated\nas a single-element array.\n\n\nStringArray is a slices of strings, but also accepts\na single string as a value when JSON unmarshaling,\nconverting it to a slice of one string."},{"key":"skip_hosts","value":{"type":"array","elems":{"type":"string","doc":"By default, all requests to this server will be logged if\naccess logging is enabled. This field lists the request\nhosts for which access logging should be disabled."}},"doc":"By default, all requests to this server will be logged if\naccess logging is enabled. This field lists the request\nhosts for which access logging should be disabled."},{"key":"skip_unmapped_hosts","value":{"type":"bool","doc":"If true, requests to any host not appearing in the\nlogger_names map will not be logged."},"doc":"If true, requests to any host not appearing in the\nlogger_names map will not be logged."},{"key":"should_log_credentials","value":{"type":"bool","doc":"If true, credentials that are otherwise omitted, will be logged.\nThe definition of credentials is defined by https://fetch.spec.whatwg.org/#credentials,\nand this includes some request and response headers, i.e `Cookie`,\n`Set-Cookie`, `Authorization`, and `Proxy-Authorization`."},"doc":"If true, credentials that are otherwise omitted, will be logged.\nThe definition of credentials is defined by https://fetch.spec.whatwg.org/#credentials,\nand this includes some request and response headers, i.e `Cookie`,\n`Set-Cookie`, `Authorization`, and `Proxy-Authorization`."},{"key":"trace","value":{"type":"bool","doc":"Log each individual handler that is invoked.\nRequires that the log emit at DEBUG level.\n\nNOTE: This may log the configuration of your\nHTTP handler modules; do not enable this in\ninsecure contexts when there is sensitive\ndata in the configuration.\n\nEXPERIMENTAL: Subject to change or removal."},"doc":"Log each individual handler that is invoked.\nRequires that the log emit at DEBUG level.\n\nNOTE: This may log the configuration of your\nHTTP handler modules; do not enable this in\ninsecure contexts when there is sensitive\ndata in the configuration.\n\nEXPERIMENTAL: Subject to change or removal."}],"doc":"Enables access logging and configures how access logs are handled\nin this server. To minimally enable access logs, simply set this\nto a non-null, empty struct.\n\n\nServerLogConfig describes a server's logging configuration. If\nenabled without customization, all requests to this server are\nlogged to the default logger; logger destinations may be\ncustomized per-request-host."},"doc":"Enables access logging and configures how access logs are handled\nin this server. To minimally enable access logs, simply set this\nto a non-null, empty struct.\n\n\nServerLogConfig describes a server's logging configuration. If\nenabled without customization, all requests to this server are\nlogged to the default logger; logger destinations may be\ncustomized per-request-host."},{"key":"protocols","value":{"type":"array","elems":{"type":"string","doc":"Protocols specifies which HTTP protocols to enable.\nSupported values are:\n\n- `h1` (HTTP/1.1)\n- `h2` (HTTP/2)\n- `h2c` (cleartext HTTP/2)\n- `h3` (HTTP/3)\n\nIf enabling `h2` or `h2c`, `h1` must also be enabled;\nthis is due to current limitations in the Go standard\nlibrary.\n\nHTTP/2 operates only over TLS (HTTPS). HTTP/3 opens\na UDP socket to serve QUIC connections.\n\nH2C operates over plain TCP if the client supports it;\nhowever, because this is not implemented by the Go\nstandard library, other server options are not compatible\nand will not be applied to H2C requests. Do not enable this\nonly to achieve maximum client compatibility. In practice,\nvery few clients implement H2C, and even fewer require it.\nEnabling H2C can be useful for serving/proxying gRPC\nif encryption is not possible or desired.\n\nWe recommend for most users to simply let Caddy use the\ndefault settings.\n\nDefault: `[h1 h2 h3]`"}},"doc":"Protocols specifies which HTTP protocols to enable.\nSupported values are:\n\n- `h1` (HTTP/1.1)\n- `h2` (HTTP/2)\n- `h2c` (cleartext HTTP/2)\n- `h3` (HTTP/3)\n\nIf enabling `h2` or `h2c`, `h1` must also be enabled;\nthis is due to current limitations in the Go standard\nlibrary.\n\nHTTP/2 operates only over TLS (HTTPS). HTTP/3 opens\na UDP socket to serve QUIC connections.\n\nH2C operates over plain TCP if the client supports it;\nhowever, because this is not implemented by the Go\nstandard library, other server options are not compatible\nand will not be applied to H2C requests. Do not enable this\nonly to achieve maximum client compatibility. In practice,\nvery few clients implement H2C, and even fewer require it.\nEnabling H2C can be useful for serving/proxying gRPC\nif encryption is not possible or desired.\n\nWe recommend for most users to simply let Caddy use the\ndefault settings.\n\nDefault: `[h1 h2 h3]`"},{"key":"listen_protocols","value":{"type":"array","elems":{"type":"array","elems":{"type":"string"},"doc":"ListenProtocols overrides Protocols for each parallel address in Listen.\nA nil value or element indicates that Protocols will be used instead."}},"doc":"ListenProtocols overrides Protocols for each parallel address in Listen.\nA nil value or element indicates that Protocols will be used instead."},{"key":"metrics","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Metrics","struct_fields":[{"key":"per_host","value":{"type":"bool","doc":"Enable per-host metrics. Enabling this option may\nincur high-memory consumption, depending on the number of hosts\nmanaged by Caddy."},"doc":"Enable per-host metrics. Enabling this option may\nincur high-memory consumption, depending on the number of hosts\nmanaged by Caddy."}],"doc":"If set, metrics observations will be enabled.\nThis setting is EXPERIMENTAL and subject to change.\nDEPRECATED: Use the app-level `metrics` field.\n\n\nMetrics configures metrics observations.\nEXPERIMENTAL and subject to change or removal."},"doc":"If set, metrics observations will be enabled.\nThis setting is EXPERIMENTAL and subject to change.\nDEPRECATED: Use the app-level `metrics` field.\n\n\nMetrics configures metrics observations.\nEXPERIMENTAL and subject to change or removal."}],"doc":"Servers is the list of servers, keyed by arbitrary names chosen\nat your discretion for your own convenience; the keys do not\naffect functionality.\n\n\nServer describes an HTTP server."}},"doc":"Servers is the list of servers, keyed by arbitrary names chosen\nat your discretion for your own convenience; the keys do not\naffect functionality.\n\n\nServer describes an HTTP server."},{"key":"metrics","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Metrics","struct_fields":[{"key":"per_host","value":{"type":"bool","doc":"Enable per-host metrics. Enabling this option may\nincur high-memory consumption, depending on the number of hosts\nmanaged by Caddy."},"doc":"Enable per-host metrics. Enabling this option may\nincur high-memory consumption, depending on the number of hosts\nmanaged by Caddy."}],"doc":"If set, metrics observations will be enabled.\nThis setting is EXPERIMENTAL and subject to change.\n\n\nMetrics configures metrics observations.\nEXPERIMENTAL and subject to change or removal."},"doc":"If set, metrics observations will be enabled.\nThis setting is EXPERIMENTAL and subject to change.\n\n\nMetrics configures metrics observations.\nEXPERIMENTAL and subject to change or removal."}],"doc":"App is a robust, production-ready HTTP server.\n\nHTTPS is enabled by default if host matchers with qualifying names are used\nin any of routes; certificates are automatically provisioned and renewed.\nAdditionally, automatic HTTPS will also enable HTTPS for servers that listen\nonly on the HTTPS port but which do not have any TLS connection policies\ndefined by adding a good, default TLS connection policy.\n\nIn HTTP routes, additional placeholders are available (replace any `*`):\n\nPlaceholder | Description\n------------|---------------\n`{http.request.body}` | The request body (⚠️ inefficient; use only for debugging)\n`{http.request.cookie.*}` | HTTP request cookie\n`{http.request.duration}` | Time up to now spent handling the request (after decoding headers from client)\n`{http.request.duration_ms}` | Same as 'duration', but in milliseconds.\n`{http.request.uuid}` | The request unique identifier\n`{http.request.header.*}` | Specific request header field\n`{http.request.host}` | The host part of the request's Host header\n`{http.request.host.labels.*}` | Request host labels (0-based from right); e.g. for foo.example.com: 0=com, 1=example, 2=foo\n`{http.request.hostport}` | The host and port from the request's Host header\n`{http.request.method}` | The request method\n`{http.request.orig_method}` | The request's original method\n`{http.request.orig_uri}` | The request's original URI\n`{http.request.orig_uri.path}` | The request's original path\n`{http.request.orig_uri.path.*}` | Parts of the original path, split by `/` (0-based from left)\n`{http.request.orig_uri.path.dir}` | The request's original directory\n`{http.request.orig_uri.path.file}` | The request's original filename\n`{http.request.orig_uri.query}` | The request's original query string (without `?`)\n`{http.request.port}` | The port part of the request's Host header\n`{http.request.proto}` | The protocol of the request\n`{http.request.local.host}` | The host (IP) part of the local address the connection arrived on\n`{http.request.local.port}` | The port part of the local address the connection arrived on\n`{http.request.local}` | The local address the connection arrived on\n`{http.request.remote.host}` | The host (IP) part of the remote client's address\n`{http.request.remote.port}` | The port part of the remote client's address\n`{http.request.remote}` | The address of the remote client\n`{http.request.scheme}` | The request scheme, typically `http` or `https`\n`{http.request.tls.version}` | The TLS version name\n`{http.request.tls.cipher_suite}` | The TLS cipher suite\n`{http.request.tls.resumed}` | The TLS connection resumed a previous connection\n`{http.request.tls.proto}` | The negotiated next protocol\n`{http.request.tls.proto_mutual}` | The negotiated next protocol was advertised by the server\n`{http.request.tls.server_name}` | The server name requested by the client, if any\n`{http.request.tls.client.fingerprint}` | The SHA256 checksum of the client certificate\n`{http.request.tls.client.public_key}` | The public key of the client certificate.\n`{http.request.tls.client.public_key_sha256}` | The SHA256 checksum of the client's public key.\n`{http.request.tls.client.certificate_pem}` | The PEM-encoded value of the certificate.\n`{http.request.tls.client.certificate_der_base64}` | The base64-encoded value of the certificate.\n`{http.request.tls.client.issuer}` | The issuer DN of the client certificate\n`{http.request.tls.client.serial}` | The serial number of the client certificate\n`{http.request.tls.client.subject}` | The subject DN of the client certificate\n`{http.request.tls.client.san.dns_names.*}` | SAN DNS names(index optional)\n`{http.request.tls.client.san.emails.*}` | SAN email addresses (index optional)\n`{http.request.tls.client.san.ips.*}` | SAN IP addresses (index optional)\n`{http.request.tls.client.san.uris.*}` | SAN URIs (index optional)\n`{http.request.uri}` | The full request URI\n`{http.request.uri.path}` | The path component of the request URI\n`{http.request.uri.path.*}` | Parts of the path, split by `/` (0-based from left)\n`{http.request.uri.path.dir}` | The directory, excluding leaf filename\n`{http.request.uri.path.file}` | The filename of the path, excluding directory\n`{http.request.uri.query}` | The query string (without `?`)\n`{http.request.uri.query.*}` | Individual query string value\n`{http.response.header.*}` | Specific response header field\n`{http.vars.*}` | Custom variables in the HTTP handler chain\n`{http.shutting_down}` | True if the HTTP app is shutting down\n`{http.time_until_shutdown}` | Time until HTTP server shutdown, if scheduled\n"},"apps/http/servers":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Server","struct_fields":[{"key":"listen","value":{"type":"array","elems":{"type":"string","doc":"Socket addresses to which to bind listeners. Accepts\n[network addresses](/docs/conventions#network-addresses)\nthat may include port ranges. Listener addresses must\nbe unique; they cannot be repeated across all defined\nservers."}},"doc":"Socket addresses to which to bind listeners. Accepts\n[network addresses](/docs/conventions#network-addresses)\nthat may include port ranges. Listener addresses must\nbe unique; they cannot be repeated across all defined\nservers."},{"key":"listener_wrappers","value":{"type":"array","elems":{"type":"module","doc":"A list of listener wrapper modules, which can modify the behavior\nof the base listener. They are applied in the given order.","module_namespace":"caddy.listeners","module_inline_key":"wrapper"}},"doc":"A list of listener wrapper modules, which can modify the behavior\nof the base listener. They are applied in the given order."},{"key":"read_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"How long to allow a read from a client's upload. Setting this\nto a short, non-zero value can mitigate slowloris attacks, but\nmay also affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"How long to allow a read from a client's upload. Setting this\nto a short, non-zero value can mitigate slowloris attacks, but\nmay also affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"read_header_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"ReadHeaderTimeout is like ReadTimeout but for request headers.\nDefault is 1 minute.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"ReadHeaderTimeout is like ReadTimeout but for request headers.\nDefault is 1 minute.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"write_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"WriteTimeout is how long to allow a write to a client. Note\nthat setting this to a small value when serving large files\nmay negatively affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"WriteTimeout is how long to allow a write to a client. Note\nthat setting this to a small value when serving large files\nmay negatively affect legitimately slow clients.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"idle_timeout","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"IdleTimeout is the maximum time to wait for the next request\nwhen keep-alives are enabled. If zero, a default timeout of\n5m is applied to help avoid resource exhaustion.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"IdleTimeout is the maximum time to wait for the next request\nwhen keep-alives are enabled. If zero, a default timeout of\n5m is applied to help avoid resource exhaustion.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"keepalive_interval","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2.Duration","doc":"KeepAliveInterval is the interval at which TCP keepalive packets\nare sent to keep the connection alive at the TCP layer when no other\ndata is being transmitted. The default is 15s.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},"doc":"KeepAliveInterval is the interval at which TCP keepalive packets\nare sent to keep the connection alive at the TCP layer when no other\ndata is being transmitted. The default is 15s.\n\n\nDuration can be an integer or a string. An integer is\ninterpreted as nanoseconds. If a string, it is a Go\ntime.Duration value such as `300ms`, `1.5h`, or `2h45m`;\nvalid units are `ns`, `us`/`µs`, `ms`, `s`, `m`, `h`, and `d`."},{"key":"max_header_bytes","value":{"type":"int","doc":"MaxHeaderBytes is the maximum size to parse from a client's\nHTTP request headers."},"doc":"MaxHeaderBytes is the maximum size to parse from a client's\nHTTP request headers."},{"key":"enable_full_duplex","value":{"type":"bool","doc":"Enable full-duplex communication for HTTP/1 requests.\nOnly has an effect if Caddy was built with Go 1.21 or later.\n\nFor HTTP/1 requests, the Go HTTP server by default consumes any\nunread portion of the request body before beginning to write the\nresponse, preventing handlers from concurrently reading from the\nrequest and writing the response. Enabling this option disables\nthis behavior and permits handlers to continue to read from the\nrequest while concurrently writing the response.\n\nFor HTTP/2 requests, the Go HTTP server always permits concurrent\nreads and responses, so this option has no effect.\n\nTest thoroughly with your HTTP clients, as some older clients may\nnot support full-duplex HTTP/1 which can cause them to deadlock.\nSee https://github.com/golang/go/issues/57786 for more info.\n\nTODO: This is an EXPERIMENTAL feature. Subject to change or removal."},"doc":"Enable full-duplex communication for HTTP/1 requests.\nOnly has an effect if Caddy was built with Go 1.21 or later.\n\nFor HTTP/1 requests, the Go HTTP server by default consumes any\nunread portion of the request body before beginning to write the\nresponse, preventing handlers from concurrently reading from the\nrequest and writing the response. Enabling this option disables\nthis behavior and permits handlers to continue to read from the\nrequest while concurrently writing the response.\n\nFor HTTP/2 requests, the Go HTTP server always permits concurrent\nreads and responses, so this option has no effect.\n\nTest thoroughly with your HTTP clients, as some older clients may\nnot support full-duplex HTTP/1 which can cause them to deadlock.\nSee https://github.com/golang/go/issues/57786 for more info.\n\nTODO: This is an EXPERIMENTAL feature. Subject to change or removal."},{"key":"routes","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RouteList","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"Routes describes how this server will handle requests.\nRoutes are executed sequentially. First a route's matchers\nare evaluated, then its grouping. If it matches and has\nnot been mutually-excluded by its grouping, then its\nhandlers are executed sequentially. The sequence of invoked\nhandlers comprises a compiled middleware chain that flows\nfrom each matching route and its handlers to the next.\n\nBy default, all unrouted requests receive a 200 OK response\nto indicate the server is working.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},"doc":"RouteList is a list of server routes that can\ncreate a middleware chain.\n"},"doc":"Routes describes how this server will handle requests.\nRoutes are executed sequentially. First a route's matchers\nare evaluated, then its grouping. If it matches and has\nnot been mutually-excluded by its grouping, then its\nhandlers are executed sequentially. The sequence of invoked\nhandlers comprises a compiled middleware chain that flows\nfrom each matching route and its handlers to the next.\n\nBy default, all unrouted requests receive a 200 OK response\nto indicate the server is working.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},{"key":"errors","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.HTTPErrorConfig","struct_fields":[{"key":"routes","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RouteList","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"The routes to evaluate after the primary handler\nchain returns an error. In an error route, extra\nplaceholders are available:\n\nPlaceholder | Description\n------------|---------------\n`{http.error.status_code}` | The recommended HTTP status code\n`{http.error.status_text}` | The status text associated with the recommended status code\n`{http.error.message}`     | The error message\n`{http.error.trace}`       | The origin of the error\n`{http.error.id}`          | An identifier for this occurrence of the error\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},"doc":"RouteList is a list of server routes that can\ncreate a middleware chain.\n"},"doc":"The routes to evaluate after the primary handler\nchain returns an error. In an error route, extra\nplaceholders are available:\n\nPlaceholder | Description\n------------|---------------\n`{http.error.status_code}` | The recommended HTTP status code\n`{http.error.status_text}` | The status text associated with the recommended status code\n`{http.error.message}`     | The error message\n`{http.error.trace}`       | The origin of the error\n`{http.error.id}`          | An identifier for this occurrence of the error\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."}],"doc":"Errors is how this server will handle errors returned from any\nof the handlers in the primary routes. If the primary handler\nchain returns an error, the error along with its recommended\nstatus code are bubbled back up to the HTTP server which\nexecutes a separate error route, specified using this property.\nThe error routes work exactly like the normal routes.\n\n\nHTTPErrorConfig determines how to handle errors\nfrom the HTTP handlers."},"doc":"Errors is how this server will handle errors returned from any\nof the handlers in the primary routes. If the primary handler\nchain returns an error, the error along with its recommended\nstatus code are bubbled back up to the HTTP server which\nexecutes a separate error route, specified using this property.\nThe error routes work exactly like the normal routes.\n\n\nHTTPErrorConfig determines how to handle errors\nfrom the HTTP handlers."},{"key":"named_routes","value":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"NamedRoutes describes a mapping of reusable routes that can be\ninvoked by their name. This can be used to optimize memory usage\nwhen the same route is needed for many subroutes, by having\nthe handlers and matchers be only provisioned once, but used from\nmany places. These routes are not executed unless they are invoked\nfrom another route.\n\nEXPERIMENTAL: Subject to change or removal.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."}},"doc":"NamedRoutes describes a mapping of reusable routes that can be\ninvoked by their name. This can be used to optimize memory usage\nwhen the same route is needed for many subroutes, by having\nthe handlers and matchers be only provisioned once, but used from\nmany places. These routes are not executed unless they are invoked\nfrom another route.\n\nEXPERIMENTAL: Subject to change or removal.\n\n\nRoute consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner."},{"key":"tls_connection_policies","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.ConnectionPolicies","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.ConnectionPolicy","struct_fields":[{"key":"match","value":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"How to match this policy with a TLS ClientHello. If\nthis policy is the first to match, it will be used.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"tls.handshake_match"},"doc":"How to match this policy with a TLS ClientHello. If\nthis policy is the first to match, it will be used.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"certificate_selection","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.CustomCertSelectionPolicy","struct_fields":[{"key":"serial_number","value":{"type":"array","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.bigInt","doc":"The certificate must have one of these serial numbers.\n\n\nbigInt is a big.Int type that interops with JSON encodings as a string."}},"doc":"The certificate must have one of these serial numbers.\n\n\nbigInt is a big.Int type that interops with JSON encodings as a string."},{"key":"subject_organization","value":{"type":"array","elems":{"type":"string","doc":"The certificate must have one of these organization names."}},"doc":"The certificate must have one of these organization names."},{"key":"public_key_algorithm","value":{"type":"int","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.PublicKeyAlgorithm","doc":"The certificate must use this public key algorithm.\n\n\nPublicKeyAlgorithm is a JSON-unmarshalable wrapper type."},"doc":"The certificate must use this public key algorithm.\n\n\nPublicKeyAlgorithm is a JSON-unmarshalable wrapper type."},{"key":"any_tag","value":{"type":"array","elems":{"type":"string","doc":"The certificate must have at least one of the tags in the list."}},"doc":"The certificate must have at least one of the tags in the list."},{"key":"all_tags","value":{"type":"array","elems":{"type":"string","doc":"The certificate must have all of the tags in the list."}},"doc":"The certificate must have all of the tags in the list."}],"doc":"How to choose a certificate if more than one matched\nthe given ServerName (SNI) value.\n\n\nCustomCertSelectionPolicy represents a policy for selecting the certificate\nused to complete a handshake when there may be multiple options. All fields\nspecified must match the candidate certificate for it to be chosen.\nThis was needed to solve https://github.com/caddyserver/caddy/issues/2588."},"doc":"How to choose a certificate if more than one matched\nthe given ServerName (SNI) value.\n\n\nCustomCertSelectionPolicy represents a policy for selecting the certificate\nused to complete a handshake when there may be multiple options. All fields\nspecified must match the candidate certificate for it to be chosen.\nThis was needed to solve https://github.com/caddyserver/caddy/issues/2588."},{"key":"cipher_suites","value":{"type":"array","elems":{"type":"string","doc":"The list of cipher suites to support. Caddy's\ndefaults are modern and secure."}},"doc":"The list of cipher suites to support. Caddy's\ndefaults are modern and secure."},{"key":"curves","value":{"type":"array","elems":{"type":"string","doc":"The list of elliptic curves to support. Caddy's\ndefaults are modern and secure."}},"doc":"The list of elliptic curves to support. Caddy's\ndefaults are modern and secure."},{"key":"alpn","value":{"type":"array","elems":{"type":"string","doc":"Protocols to use for Application-Layer Protocol\nNegotiation (ALPN) during the handshake."}},"doc":"Protocols to use for Application-Layer Protocol\nNegotiation (ALPN) during the handshake."},{"key":"protocol_min","value":{"type":"string","doc":"Minimum TLS protocol version to allow. Default: `tls1.2`"},"doc":"Minimum TLS protocol version to allow. Default: `tls1.2`"},{"key":"protocol_max","value":{"type":"string","doc":"Maximum TLS protocol version to allow. Default: `tls1.3`"},"doc":"Maximum TLS protocol version to allow. Default: `tls1.3`"},{"key":"drop","value":{"type":"bool","doc":"Reject TLS connections. EXPERIMENTAL: May change."},"doc":"Reject TLS connections. EXPERIMENTAL: May change."},{"key":"client_authentication","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddytls.ClientAuthentication","struct_fields":[{"key":"ca","value":{"type":"module","doc":"Certificate authority module which provides the certificate pool of trusted certificates","module_namespace":"tls.ca_pool.source","module_inline_key":"provider"},"doc":"Certificate authority module which provides the certificate pool of trusted certificates"},{"key":"trusted_ca_certs","value":{"type":"array","elems":{"type":"string","doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.inline` module instead.\nA list of base64 DER-encoded CA certificates\nagainst which to validate client certificates.\nClient certs which are not signed by any of\nthese CAs will be rejected."}},"doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.inline` module instead.\nA list of base64 DER-encoded CA certificates\nagainst which to validate client certificates.\nClient certs which are not signed by any of\nthese CAs will be rejected."},{"key":"trusted_ca_certs_pem_files","value":{"type":"array","elems":{"type":"string","doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.file` module instead.\nTrustedCACertPEMFiles is a list of PEM file names\nfrom which to load certificates of trusted CAs.\nClient certificates which are not signed by any of\nthese CA certificates will be rejected."}},"doc":"Deprecated: Use the `ca` field with the `tls.ca_pool.source.file` module instead.\nTrustedCACertPEMFiles is a list of PEM file names\nfrom which to load certificates of trusted CAs.\nClient certificates which are not signed by any of\nthese CA certificates will be rejected."},{"key":"trusted_leaf_certs","value":{"type":"array","elems":{"type":"string","doc":"Deprecated: This field is deprecated and will be removed in\na future version. Please use the `validators` field instead\nwith the tls.client_auth.verifier.leaf module instead.\n\nA list of base64 DER-encoded client leaf certs\nto accept. If this list is not empty, client certs\nwhich are not in this list will be rejected."}},"doc":"Deprecated: This field is deprecated and will be removed in\na future version. Please use the `validators` field instead\nwith the tls.client_auth.verifier.leaf module instead.\n\nA list of base64 DER-encoded client leaf certs\nto accept. If this list is not empty, client certs\nwhich are not in this list will be rejected."},{"key":"verifiers","value":{"type":"array","elems":{"type":"module","doc":"Client certificate verification modules. These can perform\ncustom client authentication checks, such as ensuring the\ncertificate is not revoked.","module_namespace":"tls.client_auth.verifier","module_inline_key":"verifier"}},"doc":"Client certificate verification modules. These can perform\ncustom client authentication checks, such as ensuring the\ncertificate is not revoked."},{"key":"mode","value":{"type":"string","doc":"The mode for authenticating the client. Allowed values are:\n\nMode | Description\n-----|---------------\n`request` | Ask clients for a certificate, but allow even if there isn't one; do not verify it\n`require` | Require clients to present a certificate, but do not verify it\n`verify_if_given` | Ask clients for a certificate; allow even if there isn't one, but verify it if there is\n`require_and_verify` | Require clients to present a valid certificate that is verified\n\nThe default mode is `require_and_verify` if any\nTrustedCACerts or TrustedCACertPEMFiles or TrustedLeafCerts\nare provided; otherwise, the default mode is `require`."},"doc":"The mode for authenticating the client. Allowed values are:\n\nMode | Description\n-----|---------------\n`request` | Ask clients for a certificate, but allow even if there isn't one; do not verify it\n`require` | Require clients to present a certificate, but do not verify it\n`verify_if_given` | Ask clients for a certificate; allow even if there isn't one, but verify it if there is\n`require_and_verify` | Require clients to present a valid certificate that is verified\n\nThe default mode is `require_and_verify` if any\nTrustedCACerts or TrustedCACertPEMFiles or TrustedLeafCerts\nare provided; otherwise, the default mode is `require`."}],"doc":"Enables and configures TLS client authentication.\n\n\nClientAuthentication configures TLS client auth."},"doc":"Enables and configures TLS client authentication.\n\n\nClientAuthentication configures TLS client auth."},{"key":"default_sni","value":{"type":"string","doc":"DefaultSNI becomes the ServerName in a ClientHello if there\nis no policy configured for the empty SNI value."},"doc":"DefaultSNI becomes the ServerName in a ClientHello if there\nis no policy configured for the empty SNI value."},{"key":"fallback_sni","value":{"type":"string","doc":"FallbackSNI becomes the ServerName in a ClientHello if\nthe original ServerName doesn't match any certificates\nin the cache. The use cases for this are very niche;\ntypically if a client is a CDN and passes through the\nServerName of the downstream handshake but can accept\na certificate with the origin's hostname instead, then\nyou would set this to your origin's hostname. Note that\nCaddy must be managing a certificate for this name.\n\nThis feature is EXPERIMENTAL and subject to change or removal."},"doc":"FallbackSNI becomes the ServerName in a ClientHello if\nthe original ServerName doesn't match any certificates\nin the cache. The use cases for this are very niche;\ntypically if a client is a CDN and passes through the\nServerName of the downstream handshake but can accept\na certificate with the origin's hostname instead, then\nyou would set this to your origin's hostname. Note that\nCaddy must be managing a certificate for this name.\n\nThis feature is EXPERIMENTAL and subject to change or removal."},{"key":"insecure_secrets_log","value":{"type":"string","doc":"Also known as \"SSLKEYLOGFILE\", TLS secrets will be written to\nthis file in NSS key log format which can then be parsed by\nWireshark and other tools. This is INSECURE as it allows other\nprograms or tools to decrypt TLS connections. However, this\ncapability can be useful for debugging and troubleshooting.\n**ENABLING THIS LOG COMPROMISES SECURITY!**\n\nThis feature is EXPERIMENTAL and subject to change or removal."},"doc":"Also known as \"SSLKEYLOGFILE\", TLS secrets will be written to\nthis file in NSS key log format which can then be parsed by\nWireshark and other tools. This is INSECURE as it allows other\nprograms or tools to decrypt TLS connections. However, this\ncapability can be useful for debugging and troubleshooting.\n**ENABLING THIS LOG COMPROMISES SECURITY!**\n\nThis feature is EXPERIMENTAL and subject to change or removal."},{"key":"handshake_context","value":{"type":"module","doc":"A module that can manipulate the context passed into CertMagic's\ncertificate management functions during TLS handshakes.\nEXPERIMENTAL - subject to change or removal.","module_namespace":"tls.context","module_inline_key":"module"},"doc":"A module that can manipulate the context passed into CertMagic's\ncertificate management functions during TLS handshakes.\nEXPERIMENTAL - subject to change or removal."}],"doc":"How to handle TLS connections. At least one policy is\nrequired to enable HTTPS on this server if automatic\nHTTPS is disabled or does not apply.\n\n\nConnectionPolicy specifies the logic for handling a TLS handshake.\nAn empty policy is valid; safe and sensible defaults will be used."},"doc":"ConnectionPolicies govern the establishment of TLS connections. It is\nan ordered group of connection policies; the first matching policy will\nbe used to configure TLS connections at handshake-time.\n"},"doc":"How to handle TLS connections. At least one policy is\nrequired to enable HTTPS on this server if automatic\nHTTPS is disabled or does not apply.\n\n\nConnectionPolicy specifies the logic for handling a TLS handshake.\nAn empty policy is valid; safe and sensible defaults will be used."},{"key":"automatic_https","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.AutoHTTPSConfig","struct_fields":[{"key":"disable","value":{"type":"bool","doc":"If true, automatic HTTPS will be entirely disabled,\nincluding certificate management and redirects."},"doc":"If true, automatic HTTPS will be entirely disabled,\nincluding certificate management and redirects."},{"key":"disable_redirects","value":{"type":"bool","doc":"If true, only automatic HTTP-\u003eHTTPS redirects will\nbe disabled, but other auto-HTTPS features will\nremain enabled."},"doc":"If true, only automatic HTTP-\u003eHTTPS redirects will\nbe disabled, but other auto-HTTPS features will\nremain enabled."},{"key":"disable_certificates","value":{"type":"bool","doc":"If true, automatic certificate management will be\ndisabled, but other auto-HTTPS features will\nremain enabled."},"doc":"If true, automatic certificate management will be\ndisabled, but other auto-HTTPS features will\nremain enabled."},{"key":"skip","value":{"type":"array","elems":{"type":"string","doc":"Hosts/domain names listed here will not be included\nin automatic HTTPS (they will not have certificates\nloaded nor redirects applied)."}},"doc":"Hosts/domain names listed here will not be included\nin automatic HTTPS (they will not have certificates\nloaded nor redirects applied)."},{"key":"skip_certificates","value":{"type":"array","elems":{"type":"string","doc":"Hosts/domain names listed here will still be enabled\nfor automatic HTTPS (unless in the Skip list), except\nthat certificates will not be provisioned and managed\nfor these names."}},"doc":"Hosts/domain names listed here will still be enabled\nfor automatic HTTPS (unless in the Skip list), except\nthat certificates will not be provisioned and managed\nfor these names."},{"key":"ignore_loaded_certificates","value":{"type":"bool","doc":"By default, automatic HTTPS will obtain and renew\ncertificates for qualifying hostnames. However, if\na certificate with a matching SAN is already loaded\ninto the cache, certificate management will not be\nenabled. To force automated certificate management\nregardless of loaded certificates, set this to true."},"doc":"By default, automatic HTTPS will obtain and renew\ncertificates for qualifying hostnames. However, if\na certificate with a matching SAN is already loaded\ninto the cache, certificate management will not be\nenabled. To force automated certificate management\nregardless of loaded certificates, set this to true."},{"key":"prefer_wildcard","value":{"type":"bool","doc":"If true, automatic HTTPS will prefer wildcard names\nand ignore non-wildcard names if both are available.\nThis allows for writing a config with top-level host\nmatchers without having those names produce certificates."},"doc":"If true, automatic HTTPS will prefer wildcard names\nand ignore non-wildcard names if both are available.\nThis allows for writing a config with top-level host\nmatchers without having those names produce certificates."}],"doc":"AutoHTTPS configures or disables automatic HTTPS within this server.\nHTTPS is enabled automatically and by default when qualifying names\nare present in a Host matcher and/or when the server is listening\nonly on the HTTPS port.\n\n\nAutoHTTPSConfig is used to disable automatic HTTPS\nor certain aspects of it for a specific server.\nHTTPS is enabled automatically and by default when\nqualifying hostnames are available from the config."},"doc":"AutoHTTPS configures or disables automatic HTTPS within this server.\nHTTPS is enabled automatically and by default when qualifying names\nare present in a Host matcher and/or when the server is listening\nonly on the HTTPS port.\n\n\nAutoHTTPSConfig is used to disable automatic HTTPS\nor certain aspects of it for a specific server.\nHTTPS is enabled automatically and by default when\nqualifying hostnames are available from the config."},{"key":"strict_sni_host","value":{"type":"bool","doc":"If true, will require that a request's Host header match\nthe value of the ServerName sent by the client's TLS\nClientHello; often a necessary safeguard when using TLS\nclient authentication."},"doc":"If true, will require that a request's Host header match\nthe value of the ServerName sent by the client's TLS\nClientHello; often a necessary safeguard when using TLS\nclient authentication."},{"key":"trusted_proxies","value":{"type":"module","doc":"A module which provides a source of IP ranges, from which\nrequests should be trusted. By default, no proxies are\ntrusted.\n\nOn its own, this configuration will not do anything,\nbut it can be used as a default set of ranges for\nhandlers or matchers in routes to pick up, instead\nof needing to configure each of them. See the\n`reverse_proxy` handler for example, which uses this\nto trust sensitive incoming `X-Forwarded-*` headers.","module_namespace":"http.ip_sources","module_inline_key":"source"},"doc":"A module which provides a source of IP ranges, from which\nrequests should be trusted. By default, no proxies are\ntrusted.\n\nOn its own, this configuration will not do anything,\nbut it can be used as a default set of ranges for\nhandlers or matchers in routes to pick up, instead\nof needing to configure each of them. See the\n`reverse_proxy` handler for example, which uses this\nto trust sensitive incoming `X-Forwarded-*` headers."},{"key":"client_ip_headers","value":{"type":"array","elems":{"type":"string","doc":"The headers from which the client IP address could be\nread from. These will be considered in order, with the\nfirst good value being used as the client IP.\nBy default, only `X-Forwarded-For` is considered.\n\nThis depends on `trusted_proxies` being configured and\nthe request being validated as coming from a trusted\nproxy, otherwise the client IP will be set to the direct\nremote IP address."}},"doc":"The headers from which the client IP address could be\nread from. These will be considered in order, with the\nfirst good value being used as the client IP.\nBy default, only `X-Forwarded-For` is considered.\n\nThis depends on `trusted_proxies` being configured and\nthe request being validated as coming from a trusted\nproxy, otherwise the client IP will be set to the direct\nremote IP address."},{"key":"trusted_proxies_strict","value":{"type":"int","doc":"If greater than zero, enables strict ClientIPHeaders\n(default X-Forwarded-For) parsing. If enabled, the\nClientIPHeaders will be parsed from right to left, and\nthe first value that is both valid and doesn't match the\ntrusted proxy list will be used as client IP. If zero,\nthe ClientIPHeaders will be parsed from left to right,\nand the first value that is a valid IP address will be\nused as client IP.\n\nThis depends on `trusted_proxies` being configured.\nThis option is disabled by default."},"doc":"If greater than zero, enables strict ClientIPHeaders\n(default X-Forwarded-For) parsing. If enabled, the\nClientIPHeaders will be parsed from right to left, and\nthe first value that is both valid and doesn't match the\ntrusted proxy list will be used as client IP. If zero,\nthe ClientIPHeaders will be parsed from left to right,\nand the first value that is a valid IP address will be\nused as client IP.\n\nThis depends on `trusted_proxies` being configured.\nThis option is disabled by default."},{"key":"logs","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.ServerLogConfig","struct_fields":[{"key":"default_logger_name","value":{"type":"string","doc":"The default logger name for all logs emitted by this server for\nhostnames that are not in the logger_names map."},"doc":"The default logger name for all logs emitted by this server for\nhostnames that are not in the logger_names map."},{"key":"logger_names","value":{"type":"map","map_keys":{"type":"string"},"elems":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.StringArray","elems":{"type":"string"},"doc":"LoggerNames maps request hostnames to one or more custom logger\nnames. For example, a mapping of `\"example.com\": [\"example\"]` would\ncause access logs from requests with a Host of example.com to be\nemitted by a logger named \"http.log.access.example\". If there are\nmultiple logger names, then the log will be emitted to all of them.\nIf the logger name is an empty, the default logger is used, i.e.\nthe logger \"http.log.access\".\n\nKeys must be hostnames (without ports), and may contain wildcards\nto match subdomains. The value is an array of logger names.\n\nFor backwards compatibility, if the value is a string, it is treated\nas a single-element array.\n\n\nStringArray is a slices of strings, but also accepts\na single string as a value when JSON unmarshaling,\nconverting it to a slice of one string."}},"doc":"LoggerNames maps request hostnames to one or more custom logger\nnames. For example, a mapping of `\"example.com\": [\"example\"]` would\ncause access logs from requests with a Host of example.com to be\nemitted by a logger named \"http.log.access.example\". If there are\nmultiple logger names, then the log will be emitted to all of them.\nIf the logger name is an empty, the default logger is used, i.e.\nthe logger \"http.log.access\".\n\nKeys must be hostnames (without ports), and may contain wildcards\nto match subdomains. The value is an array of logger names.\n\nFor backwards compatibility, if the value is a string, it is treated\nas a single-element array.\n\n\nStringArray is a slices of strings, but also accepts\na single string as a value when JSON unmarshaling,\nconverting it to a slice of one string."},{"key":"skip_hosts","value":{"type":"array","elems":{"type":"string","doc":"By default, all requests to this server will be logged if\naccess logging is enabled. This field lists the request\nhosts for which access logging should be disabled."}},"doc":"By default, all requests to this server will be logged if\naccess logging is enabled. This field lists the request\nhosts for which access logging should be disabled."},{"key":"skip_unmapped_hosts","value":{"type":"bool","doc":"If true, requests to any host not appearing in the\nlogger_names map will not be logged."},"doc":"If true, requests to any host not appearing in the\nlogger_names map will not be logged."},{"key":"should_log_credentials","value":{"type":"bool","doc":"If true, credentials that are otherwise omitted, will be logged.\nThe definition of credentials is defined by https://fetch.spec.whatwg.org/#credentials,\nand this includes some request and response headers, i.e `Cookie`,\n`Set-Cookie`, `Authorization`, and `Proxy-Authorization`."},"doc":"If true, credentials that are otherwise omitted, will be logged.\nThe definition of credentials is defined by https://fetch.spec.whatwg.org/#credentials,\nand this includes some request and response headers, i.e `Cookie`,\n`Set-Cookie`, `Authorization`, and `Proxy-Authorization`."},{"key":"trace","value":{"type":"bool","doc":"Log each individual handler that is invoked.\nRequires that the log emit at DEBUG level.\n\nNOTE: This may log the configuration of your\nHTTP handler modules; do not enable this in\ninsecure contexts when there is sensitive\ndata in the configuration.\n\nEXPERIMENTAL: Subject to change or removal."},"doc":"Log each individual handler that is invoked.\nRequires that the log emit at DEBUG level.\n\nNOTE: This may log the configuration of your\nHTTP handler modules; do not enable this in\ninsecure contexts when there is sensitive\ndata in the configuration.\n\nEXPERIMENTAL: Subject to change or removal."}],"doc":"Enables access logging and configures how access logs are handled\nin this server. To minimally enable access logs, simply set this\nto a non-null, empty struct.\n\n\nServerLogConfig describes a server's logging configuration. If\nenabled without customization, all requests to this server are\nlogged to the default logger; logger destinations may be\ncustomized per-request-host."},"doc":"Enables access logging and configures how access logs are handled\nin this server. To minimally enable access logs, simply set this\nto a non-null, empty struct.\n\n\nServerLogConfig describes a server's logging configuration. If\nenabled without customization, all requests to this server are\nlogged to the default logger; logger destinations may be\ncustomized per-request-host."},{"key":"protocols","value":{"type":"array","elems":{"type":"string","doc":"Protocols specifies which HTTP protocols to enable.\nSupported values are:\n\n- `h1` (HTTP/1.1)\n- `h2` (HTTP/2)\n- `h2c` (cleartext HTTP/2)\n- `h3` (HTTP/3)\n\nIf enabling `h2` or `h2c`, `h1` must also be enabled;\nthis is due to current limitations in the Go standard\nlibrary.\n\nHTTP/2 operates only over TLS (HTTPS). HTTP/3 opens\na UDP socket to serve QUIC connections.\n\nH2C operates over plain TCP if the client supports it;\nhowever, because this is not implemented by the Go\nstandard library, other server options are not compatible\nand will not be applied to H2C requests. Do not enable this\nonly to achieve maximum client compatibility. In practice,\nvery few clients implement H2C, and even fewer require it.\nEnabling H2C can be useful for serving/proxying gRPC\nif encryption is not possible or desired.\n\nWe recommend for most users to simply let Caddy use the\ndefault settings.\n\nDefault: `[h1 h2 h3]`"}},"doc":"Protocols specifies which HTTP protocols to enable.\nSupported values are:\n\n- `h1` (HTTP/1.1)\n- `h2` (HTTP/2)\n- `h2c` (cleartext HTTP/2)\n- `h3` (HTTP/3)\n\nIf enabling `h2` or `h2c`, `h1` must also be enabled;\nthis is due to current limitations in the Go standard\nlibrary.\n\nHTTP/2 operates only over TLS (HTTPS). HTTP/3 opens\na UDP socket to serve QUIC connections.\n\nH2C operates over plain TCP if the client supports it;\nhowever, because this is not implemented by the Go\nstandard library, other server options are not compatible\nand will not be applied to H2C requests. Do not enable this\nonly to achieve maximum client compatibility. In practice,\nvery few clients implement H2C, and even fewer require it.\nEnabling H2C can be useful for serving/proxying gRPC\nif encryption is not possible or desired.\n\nWe recommend for most users to simply let Caddy use the\ndefault settings.\n\nDefault: `[h1 h2 h3]`"},{"key":"listen_protocols","value":{"type":"array","elems":{"type":"array","elems":{"type":"string"},"doc":"ListenProtocols overrides Protocols for each parallel address in Listen.\nA nil value or element indicates that Protocols will be used instead."}},"doc":"ListenProtocols overrides Protocols for each parallel address in Listen.\nA nil value or element indicates that Protocols will be used instead."},{"key":"metrics","value":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Metrics","struct_fields":[{"key":"per_host","value":{"type":"bool","doc":"Enable per-host metrics. Enabling this option may\nincur high-memory consumption, depending on the number of hosts\nmanaged by Caddy."},"doc":"Enable per-host metrics. Enabling this option may\nincur high-memory consumption, depending on the number of hosts\nmanaged by Caddy."}],"doc":"If set, metrics observations will be enabled.\nThis setting is EXPERIMENTAL and subject to change.\nDEPRECATED: Use the app-level `metrics` field.\n\n\nMetrics configures metrics observations.\nEXPERIMENTAL and subject to change or removal."},"doc":"If set, metrics observations will be enabled.\nThis setting is EXPERIMENTAL and subject to change.\nDEPRECATED: Use the app-level `metrics` field.\n\n\nMetrics configures metrics observations.\nEXPERIMENTAL and subject to change or removal."}],"doc":"Server describes an HTTP server.\n"},"doc":"Servers is the list of servers, keyed by arbitrary names chosen\nat your discretion for your own convenience; the keys do not\naffect functionality.\n"},"apps/http/servers/routes":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RouteList","elems":{"type":"struct","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.Route","struct_fields":[{"key":"group","value":{"type":"string","doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},"doc":"Group is an optional name for a group to which this\nroute belongs. Grouping a route makes it mutually\nexclusive with others in its group; if a route belongs\nto a group, only the first matching route in that group\nwill be executed."},{"key":"match","value":{"type":"array","type_name":"github.com/caddyserver/caddy/v2/modules/caddyhttp.RawMatcherSets","elems":{"type":"module_map","type_name":"github.com/caddyserver/caddy/v2.ModuleMap","doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage.","module_namespace":"http.matchers"},"doc":"RawMatcherSets is a group of matcher sets\nin their raw, JSON form.\n"},"doc":"The matcher sets which will be used to qualify this\nroute for a request (essentially the \"if\" statement\nof this route). Each matcher set is OR'ed, but matchers\nwithin a set are AND'ed together.\n\n\nModuleMap is a map that can contain multiple modules,\nwhere the map key is the module's name. (The namespace\nis usually read from an associated field's struct tag.)\nBecause the module's name is given as the key in a\nmodule map, the name does not have to be given in the\njson.RawMessage."},{"key":"handle","value":{"type":"array","elems":{"type":"module","doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.","module_namespace":"http.handlers","module_inline_key":"handler"}},"doc":"The list of handlers for this route. Upon matching a request, they are chained\ntogether in a middleware fashion: requests flow from the first handler to the last\n(top of the list to the bottom), with the possibility that any handler could stop\nthe chain and/or return an error. Responses flow back through the chain (bottom of\nthe list to the top) as they are written out to the client.\n\nNot all handlers call the next handler in the chain. For example, the reverse_proxy\nhandler always sends a request upstream or returns an error. Thus, configuring\nhandlers after reverse_proxy in the same route is illogical, since they would never\nbe executed. You will want to put handlers which originate the response at the very\nend of your route(s). The documentation for a module should state whether it invokes\nthe next handler, but sometimes it is common sense.\n\nSome handlers manipulate the response. Remember that requests flow down the list, and\nresponses flow up the list.\n\nFor example, if you wanted to use both `templates` and `encode` handlers, you would\nneed to put `templates` after `encode` in your route, because responses flow up.\nThus, `templates` will be able to parse and execute the plain-text response as a\ntemplate, and then return it up to the `encode` handler which will then compress it\ninto a binary format.\n\nIf `templates` came before `encode`, then `encode` would write a compressed,\nbinary-encoded response to `templates` which would not be able to parse the response\nproperly.\n\nThe correct order, then, is this:\n\n    [\n        {\"handler\": \"encode\"},\n        {\"handler\": \"templates\"},\n        {\"handler\": \"file_server\"}\n    ]\n\nThe request flows ⬇️ DOWN (`encode` -\u003e `templates` -\u003e `file_server`).\n\n1. First, `encode` will choose how to `encode` the response and wrap the response.\n2. Then, `templates` will wrap the response with a buffer.\n3. Finally, `file_server` will originate the content from a file.\n\nThe response flows ⬆️ UP (`file_server` -\u003e `templates` -\u003e `encode`):\n\n1. First, `file_server` will write the file to the response.\n2. That write will be buffered and then executed by `templates`.\n3. Lastly, the write from `templates` will flow into `encode` which will compress the stream.\n\nIf you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes."},{"key":"terminal","value":{"type":"bool","doc":"If true, no more routes will be executed after this one."},"doc":"If true, no more routes will be executed after this one."}],"doc":"Route consists of a set of rules for matching HTTP requests,\na list of handlers to execute, and optional flow control\nparameters which customize the handling of HTTP requests\nin a highly flexible and performant manner.\n"},"doc":"Routes describes how this server will handle requests.\nRoutes are executed sequentially. First a route's matchers\nare evaluated, then its grouping. If it matches and has\nnot been mutually-excluded by its grouping, then its\nhandlers are executed sequentially. The sequence of invoked\nhandlers comprises a compiled middleware chain that flows\nfrom each matching route and its handlers to the next.\n\nBy default, all unrouted requests receive a 200 OK response\nto indicate the server is working.\n\n\nRouteList is a list of server routes that can\ncreate a middleware chain.\n"}},"repo":"https://github.com/caddyserver/caddy"}}