diff --git a/src/docs/markdown/caddyfile/directives/encode.md b/src/docs/markdown/caddyfile/directives/encode.md index 29d283f3..d5edbfbd 100644 --- a/src/docs/markdown/caddyfile/directives/encode.md +++ b/src/docs/markdown/caddyfile/directives/encode.md @@ -29,10 +29,7 @@ encode [] { minimum_length - match { - status - header [] - } + match } ``` diff --git a/src/docs/markdown/caddyfile/directives/header.md b/src/docs/markdown/caddyfile/directives/header.md index 0ea09425..b1d10dc4 100644 --- a/src/docs/markdown/caddyfile/directives/header.md +++ b/src/docs/markdown/caddyfile/directives/header.md @@ -37,6 +37,8 @@ header [] [[+|-|?|>] [|] []] { ? [defer] + + match } ``` @@ -44,7 +46,7 @@ header [] [[+|-|?|>] [|] []] { With no prefix, the field is set (overwritten). - Prefix with `+` to add the field instead of overwriting (setting) the field if it already exists; header fields can appear more than once in a request. + Prefix with `+` to add the field instead of overwriting (setting) the field if it already exists; header fields can appear more than once in a response. Prefix with `-` to delete the field. The field may use prefix or suffix `*` wildcards to delete all matching fields. @@ -58,7 +60,13 @@ header [] [[+|-|?|>] [|] []] { - **<replace>** is the replacement value; required if performing a search-and-replace. Use `$1` or `$2` and so on to reference capture groups from the search pattern. If the replacement value is `""`, then the matching text is removed from the value. See the [Go documentation](https://golang.org/pkg/regexp/#Regexp.Expand) for details. -- **defer** will force the header operations to be deferred until the response is being written out to the client. This is automatically enabled if any of the header fields are being deleted with `-`, when setting a default value with `?`, or when having used the `>` prefix. +- **defer** defers the execution of header operations until the response is being sent to the client. This option is automatically enabled under the following conditions: + - When any header fields are deleted using `-`. + - When setting a default value with `?`. + - When using the `>` prefix on a set or replace operation. + - When one or more `match` conditions are present. + +- **match** is an inline [response matcher](/docs/caddyfile/response-matchers). Header operations are applied only to responses that satisfy the specified conditions. For multiple header manipulations, you can open a block and specify one manipulation per line in the same way. @@ -67,7 +75,7 @@ When using the `?` prefix to set a default header value, it is automatically sep ## Examples -Set a custom header field on all requests: +Set a custom header field on all responses: ```caddy-d header Custom-Header "My value" @@ -119,10 +127,61 @@ header ?Cache-Control "max-age=3600" reverse_proxy upstream:443 ``` +Mark all successful responses to GET requests as cacheable for upto an hour: + +```caddy-d +@GET { + method GET +} +header @GET Cache-Control "max-age=3600" { + match status 2xx +} +reverse_proxy upstream:443 +``` + +Prevent caching of error responses in the event of an exception in the upstream server: + +```caddy-d +header { + -Cache-Control + -CDN-Cache-Control + match status 500 +} +reverse_proxy upstream:443 +``` + +Mark light mode responses as separately cacheable from dark mode responses if the upstream server supports client hints: +```caddy-d +header { + Cache-Control "max-age=3600" + Vary "Sec-CH-Prefers-Color-Scheme" + match { + header Accept-CH "*Sec-CH-Prefers-Color-Scheme*" + header Critical-CH "Sec-CH-Prefers-Color-Scheme" + } +} +reverse_proxy upstream:443 +``` + +Prevent overly-permissive CORS headers by replacing wildcard values with a specific domain: +```caddy-d +header >Access-Control-Allow-Origin "\*" "allowed-partner.com" +reverse_proxy upstream:443 +``` +**Note**: In replacement operations, the `` value is interpreted as a regular expression. To match the `*` character, it must be escaped with a backslash as shown in the above example. + +Alternatively, you may use a [response matcher](/docs/caddyfile/response-matchers) to match a header value verbatim: +```caddy-d +header Access-Control-Allow-Origin "allowed-partner.com" { + match header Access-Control-Allow-Origin * +} +reverse_proxy upstream:443 +``` + To override the cache expiration that a proxy upstream had set for paths starting with `/no-cache`; enabling `defer` is necessary to ensure the header is set _after_ the proxy writes its headers: ```caddy-d -header /no-cache* >Cache-Control nocache +header /no-cache* >Cache-Control no-cache reverse_proxy upstream:443 ``` diff --git a/src/docs/markdown/caddyfile/directives/intercept.md b/src/docs/markdown/caddyfile/directives/intercept.md index f472bfc3..a7765f2d 100644 --- a/src/docs/markdown/caddyfile/directives/intercept.md +++ b/src/docs/markdown/caddyfile/directives/intercept.md @@ -18,10 +18,6 @@ window.$(function() { window.$('pre.chroma .nd:contains("@name")').first().slice(0, 3) .wrapAll('').parent() .html('@name') - window.$('pre.chroma .k:contains("replace_status")').first().next() - .html('[<matcher>]') - window.$('pre.chroma .k:contains("handle_response")').first().next() - .html('[<matcher>]') window.$('pre.chroma .k') .filter((i, el) => el.innerText === 'status') .html('status') @@ -49,19 +45,19 @@ intercept [] { header [] } - replace_status [] + replace_status [] - handle_response [] { + handle_response [] { } } ``` -- **@name** is the name of a [response matcher](/docs/caddyfile/response-matchers). As long as each response matcher has a unique name, multiple matchers can be defined. A response can be matched on the status code and presence or value of a response header. +- **@name** is a named [response matcher](/docs/caddyfile/response-matchers) block. As long as each response matcher has a unique name, multiple matchers can be defined. A response can be matched on the status code and presence or value of a response header. - **replace_status** simply changes the status code of response when matched by the given matcher. -- **handle_response** defines the route to execute when matched by the given matcher (or, if a matcher is omitted, all responses). The first matching block will be applied. Inside a `handle_response` block, any other [directives](/docs/caddyfile/directives) can be used. +- **handle_response** defines the route to execute when the original response is matched by the given response matcher. If a matcher is omitted, all responses are intercepted. When multiple `handle_response` blocks are defined, the first matching block will be applied. Inside the block, all other [directives](/docs/caddyfile/directives) can be used. Within `handle_response` routes, the following placeholders are available to pull information from the original response: diff --git a/src/docs/markdown/caddyfile/response-matchers.md b/src/docs/markdown/caddyfile/response-matchers.md index be9e11fd..d47d2bcd 100644 --- a/src/docs/markdown/caddyfile/response-matchers.md +++ b/src/docs/markdown/caddyfile/response-matchers.md @@ -35,14 +35,39 @@ These typically only appear as config inside of certain other directives, to mak ## Syntax +If a directive accepts response matchers, the usage is represented as either `[]` or `[]` in the syntax documentation. + +- The **** token can be the name of a previously declared named response matcher. For example: `@name`. +- The **** token can be the response criteria itself, without requiring prior declaration. For example: `status 200`. + +### Named + ```caddy-d @name { status header [] } ``` +If only one aspect of the response is relevant to the directive, you can put the name and the criteria on the same line: +```caddy-d +@name status +``` +### Inline + +```caddy-d +{ + status + header [] +} +``` +```caddy-d +status +``` +```caddy-d +header [] +``` ## Matchers diff --git a/src/old/resources/js/docs.js b/src/old/resources/js/docs.js index 0e6a7d1d..7e7de3a4 100644 --- a/src/old/resources/js/docs.js +++ b/src/old/resources/js/docs.js @@ -55,6 +55,19 @@ $(function() { let text = item.innerText.replace(//g,'>'); $(item).html('' + text + ''); }); + // Add links to [] or named matcher tokens in code blocks. + // The matcher text includes <> characters which are parsed as HTML, + // so we must use text() to change the link text. + $('pre.chroma .s:contains("")') + .add('pre.chroma .s:contains("")') + .map(function(k, /** @type { HTMLElement } */ item) { + const anchor = document.createElement("a"); + anchor.href = "/docs/caddyfile/response-matchers#syntax"; + anchor.style.color = "inherit"; + anchor.title = "Response matcher token"; + item.replaceWith(anchor); + anchor.appendChild(item); + }); // Wrap all tables in a div so we can apply overflow-x: scroll $('table').wrap('
');