Skip to content

Commit

Permalink
Finish documenting Caddy 2.8.0 features (#419)
Browse files Browse the repository at this point in the history
  • Loading branch information
francislavoie authored Sep 29, 2024
1 parent 6ac5539 commit af347e9
Show file tree
Hide file tree
Showing 17 changed files with 481 additions and 113 deletions.
4 changes: 3 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{md,css,js,html}]
indent_style = tab
indent_size = 4
indent_size = 4
1 change: 1 addition & 0 deletions src/docs/markdown/caddyfile/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ You can use any [Caddy placeholders](/docs/conventions#placeholders) in the Cadd
| `{remote_port}` | `{http.request.remote.port}` |
| `{remote}` | `{http.request.remote}` |
| `{rp.*}` | `{http.reverse_proxy.*}` |
| `{resp.*}` | `{http.intercept.*}` |
| `{scheme}` | `{http.request.scheme}` |
| `{tls_cipher}` | `{http.request.tls.cipher_suite}` |
| `{tls_client_certificate_der_base64}` | `{http.request.tls.client.certificate_der_base64}` |
Expand Down
4 changes: 4 additions & 0 deletions src/docs/markdown/caddyfile/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ Directive | Description
**[handle_path](/docs/caddyfile/directives/handle_path)** | Like handle, but strips path prefix
**[header](/docs/caddyfile/directives/header)** | Sets or removes response headers
**[import](/docs/caddyfile/directives/import)** | Include snippets or files
**[intercept](/docs/caddyfile/directives/intercept)** | Intercept responses written by other handlers
**[invoke](/docs/caddyfile/directives/invoke)** | Invoke a named route
**[log](/docs/caddyfile/directives/log)** | Enables access/request logging
**[log_append](/docs/caddyfile/directives/log_append)** | Append a field to the access log
**[log_skip](/docs/caddyfile/directives/log_skip)** | Skip access logging for matched requests
**[log_name](/docs/caddyfile/directives/log_name)** | Override the logger name(s) to write to
**[map](/docs/caddyfile/directives/map)** | Maps an input value to one or more outputs
**[method](/docs/caddyfile/directives/method)** | Change the HTTP method internally
**[metrics](/docs/caddyfile/directives/metrics)** | Configures the Prometheus metrics exposition endpoint
Expand Down Expand Up @@ -126,6 +128,7 @@ fs
root
log_append
log_skip
log_name
header
copy_response_headers # only in reverse_proxy's handle_response block
Expand All @@ -145,6 +148,7 @@ forward_auth
request_header
encode
push
intercept
templates
# special routing & dispatching directives
Expand Down
32 changes: 7 additions & 25 deletions src/docs/markdown/caddyfile/directives/encode.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ title: encode (Caddyfile directive)
window.$(function() {
// We'll add links to all the subdirectives if a matching anchor tag is found on the page.
addLinksToSubdirectives();

// Response matchers
window.$('pre.chroma .k:contains("status")')
.html('<a href="/docs/caddyfile/response-matchers#status" style="color: inherit;" title="Response matcher">status</a>')
window.$('pre.chroma .k:contains("header")')
.html('<a href="/docs/caddyfile/response-matchers#header" style="color: inherit;" title="Response matcher">header</a>')
});
</script>

Expand All @@ -23,9 +29,6 @@ encode [<matcher>] <formats...> {
minimum_length <length>
# response matcher single line syntax
match [header <field> [<value>]] | [status <code...>]
# or response matcher block for multiple conditions
match {
status <code...>
header <field> [<value>]
Expand All @@ -41,7 +44,7 @@ encode [<matcher>] <formats...> {

- **minimum_length** <span id="minimum_length"/> the minimum number of bytes a response should have to be encoded (default: 512).

- **match** <span id="match"/> is a [response matcher](#response-matcher). Only matching responses are encoded. The default looks like this:
- **match** <span id="match"/> is a [response matcher](/docs/caddyfile/response-matchers). Only matching responses are encoded. The default looks like this:

```caddy-d
match {
Expand Down Expand Up @@ -82,27 +85,6 @@ encode [<matcher>] <formats...> {
```


## Response matcher

**Response matchers** can be used to filter (or classify) responses by specific criteria.


### status

```caddy-d
status <code...>
```

By HTTP status code.

- **&lt;code...&gt;** is a list of HTTP status codes. Special cases are `2xx`, `3xx`, ... which match against all status codes in the range of 200-299, 300-399, ... respectively


### header

See the [header](/docs/caddyfile/matchers#header) request matcher for the supported syntax.


## Examples

Enable Gzip compression:
Expand Down
2 changes: 2 additions & 0 deletions src/docs/markdown/caddyfile/directives/file_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Most often, the `file_server` directive is paired with the [`root`](root) direct

When errors occur (e.g. file not found `404`, permission denied `403`), the error routes will be invoked. Use the [`handle_errors`](handle_errors) directive to define error routes, and display custom error pages.

When using `browse`, the default output is produced by the the HTML template. Clients may request the directory listing as either JSON or plaintext, by using the `Accept: application/json` or `Accept: text/plain` headers respectively. The JSON output can be useful for scripting, and the plaintext output can be useful for human terminal usage.


## Syntax

Expand Down
4 changes: 2 additions & 2 deletions src/docs/markdown/caddyfile/directives/header.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ header [<matcher>] [[+|-|?|>]<field> [<value>|<find>] [<replace>]] {

- **&lt;find&gt;** is the substring or regular expression to search for.

- **&lt;replace&gt;** is the replacement value; required if performing a search-and-replace.
- **&lt;replace&gt;** 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.

For multiple header manipulations, you can open a block and specify one manipulation per line in the same way.

When using the `?` prefix to set a default header value, it is automatically separated into its own `header` handler, if it was in a `header` block with multiple header operations. [Under the hood](/docs/modules/http.handlers.headers#response/require), using `?` configures a response matcher which applies to the directive's entire handler, which only applies the header operations (like `defer`), but only if the field is not yet set.
When using the `?` prefix to set a default header value, it is automatically separated into its own `header` handler, if it was in a `header` block with multiple header operations. [Under the hood](/docs/modules/http.handlers.headers#response/require), using `?` configures a [response matcher](/docs/caddyfile/response-matchers) which applies to the directive's entire handler, which only applies the header operations (like `defer`), but only if the field is not yet set.


## Examples
Expand Down
93 changes: 93 additions & 0 deletions src/docs/markdown/caddyfile/directives/intercept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: intercept (Caddyfile directive)
---

<script>
window.$(function() {
// Fix response matchers to render with the right color,
// and link to response matchers section
window.$('pre.chroma .k:contains("@")')
.map(function(k, item) {
let text = item.innerText.replace(/</g,'&lt;').replace(/>/g,'&gt;');
let url = '#' + item.innerText.replace(/_/g, "-");
window.$(item).addClass('nd').removeClass('k')
window.$(item).html(`<a href="#response-matcher" style="color: inherit;" title="Response matcher">${text}</a>`);
});

// Response matchers
window.$('pre.chroma .nd:contains("@name")').first().slice(0, 3)
.wrapAll('<span class="nd">').parent()
.html('<a href="/docs/caddyfile/response-matchers" style="color: inherit;">@name</a>')
window.$('pre.chroma .k:contains("replace_status")').first().next()
.html('<a href="/docs/caddyfile/response-matchers" style="color: inherit;" title="Response matcher">[&lt;matcher&gt;]</a>')
window.$('pre.chroma .k:contains("handle_response")').first().next()
.html('<a href="/docs/caddyfile/response-matchers" style="color: inherit;" title="Response matcher">[&lt;matcher&gt;]</a>')
window.$('pre.chroma .k')
.filter((i, el) => el.innerText === 'status')
.html('<a href="/docs/caddyfile/response-matchers#status" style="color: inherit;">status</a>')
window.$('pre.chroma .k:contains("header")').first()
.html('<a href="/docs/caddyfile/response-matchers#header" style="color: inherit;">header</a>')

// We'll add links to all the subdirectives if a matching anchor tag is found on the page.
addLinksToSubdirectives();
});
</script>

# intercept

A generalized abstraction of the [response interception](reverse_proxy#intercepting-responses) feature from the [`reverse_proxy` directive](reverse_proxy). This may be used with any handler that produces responses, including those from plugins like [FrankenPHP](https://frankenphp.dev/)'s `php_server`.

This directive allows you to [match responses](/docs/caddyfile/response-matchers), and the first matching `handle_response` route or `replace_status` will be invoked. When invoked, the original response body is held back, giving the opportunity to that route to write a different response body, with a new status code or with any necessary response header manipulations. If the route does _not_ write a new response body, then original response body is written instead.


## Syntax

```caddy-d
intercept [<matcher>] {
@name {
status <code...>
header <field> [<value>]
}
replace_status [<matcher>] <code>
handle_response [<matcher>] {
<directives...>
}
}
```

- **@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.

- **replace_status** <span id="replace_status"/> simply changes the status code of response when matched by the given matcher.

- **handle_response** <span id="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.

Within `handle_response` routes, the following placeholders are available to pull information from the original response:

- `{resp.status_code}` The status code of the original response.

- `{resp.header.*}` The headers from the original response.


## Examples

When using [FrankenPHP](https://frankenphp.dev/)'s `php_server`, you can use `intercept` to implement `X-Accel-Redirect` support, serving static files as requested by the PHP app:

```caddy
localhost {
root * /srv
intercept {
@accel header X-Accel-Redirect *
handle_response @accel {
root * /path/to/private/files
rewrite {resp.header.X-Accel-Redirect}
method GET
file_server
}
}
php_server
}
```
22 changes: 14 additions & 8 deletions src/docs/markdown/caddyfile/directives/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,37 +59,42 @@ To add custom fields to the log entries, use the [`log_append` directive](log_ap
- [append](#append)
- [Examples](#examples)

Since Caddy v2.5, by default, headers with potentially sensitive information (`Cookie`, `Set-Cookie`, `Authorization` and `Proxy-Authorization`) will be logged with empty values. This behaviour can be disabled with the [`log_credentials`](/docs/caddyfile/options#log-credentials) global server option.
By default, headers with potentially sensitive information (`Cookie`, `Set-Cookie`, `Authorization` and `Proxy-Authorization`) will be logged as `REDACTED` in access logs. This behaviour can be disabled with the [`log_credentials`](/docs/caddyfile/options#log-credentials) global server option.


## Syntax

```caddy-d
log [<logger_name>] {
hostnames <hostnames...>
no_hostname
output <writer_module> ...
format <encoder_module> ...
level <level>
}
```

- **logger_name** is an optional override of the logger name for this site.
- **logger_name** <span id="logger_name"/> is an optional override of the logger name for this site.

By default, a logger name is generated automatically, e.g. `log0`, `log1`, and so on depending on the order of the sites in the Caddyfile. This is only useful if you wish to reliably refer to the output of this logger from another logger defined in global options. See [an example](#multiple-outputs) below.

- **hostnames** is an optional override of the hostnames that this logger applies to.
- **hostnames** <span id="hostnames"/> is an optional override of the hostnames that this logger applies to.

By default, the logger applies to the hostnames of the site block it appears in, i.e. the site addresses. This is useful if you wish to define different loggers per subdomain in a [wildcard site block](/docs/caddyfile/patterns#wildcard-certificates). See [an example](#wildcard-logs) below.

- **output** configures where to write the logs. See [`output` modules](#output-modules) below.
- **no_hostname** <span id="no_hostname"/> prevents the logger from being associated with any of the site block's hostnames. By default, the logger is associated with the [site address](/docs/caddyfile/concepts#addresses) that the `log` directive appears in.

This is useful when you want to log requests to different files based on some condition, such as the request path or method, using the [`log_name` directive](/docs/caddyfile/directives/log_name).

- **output** <span id="output"/> configures where to write the logs. See [`output` modules](#output-modules) below.

Default: `stderr`.

- **format** describes how to encode, or format, the logs. See [`format` modules](#format-modules) below.
- **format** <span id="format"/> describes how to encode, or format, the logs. See [`format` modules](#format-modules) below.

Default: `console` if `stderr` is detected to be a terminal, `json` otherwise.

- **level** is the minimum entry level to log. Default: `INFO`.
- **level** <span id="level"/> is the minimum entry level to log. Default: `INFO`.

Note that access logs currently only emit `INFO` and `ERROR` level logs.

Expand Down Expand Up @@ -251,8 +256,9 @@ format <encoder_module> {
Default: `seconds`.

May be one of:
- `seconds` Floating-point number of seconds elapsed.
- `nano` Integer number of nanoseconds elapsed.
- `s`, `second` or `seconds` Floating-point number of seconds elapsed.
- `ms`, `milli` or `millis` Floating-point number of milliseconds elapsed.
- `ns`, `nano` or `nanos` Integer number of nanoseconds elapsed.
- `string` Using Go's built-in string format, for example `1m32.05s` or `6.31ms`.

- **level_format** The format for levels.
Expand Down
49 changes: 49 additions & 0 deletions src/docs/markdown/caddyfile/directives/log_name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: log_name (Caddyfile directive)
---

# log_name

Overrides the logger name to use for a request when writing access logs with the [`log` directive](log).

This directive is useful when you want to log requests to different files based on some condition, such as the request path or method.

More than one logger name can be specified, such that the request's log gets pushed to more than one matching logger.

This is often paired with the `log` directive's [`no_hostname`](log#no_hostname) option, which prevents the logger from being associated with any of the site block's hostnames, so that only requests that set `log_name` will push logs to that logger.


## Syntax

```caddy-d
log_name [<matcher>] <names...>
```


## Examples

You may want to log requests to different files, for example you might want to log health checks to a separate file from the main access logs.

Using `no_hostname` in a `log` prevents the logger from being associated with any of the site block's hostnames (i.e. `localhost` here), so that only requests that have `log_name` set to that logger's name will receive logs.

```caddy
localhost {
log {
output file ./caddy.access.log
}
log health_check_log {
output file ./caddy.access.health.log
no_hostname
}
handle /healthz* {
log_name health_check_log
respond "Healthy"
}
handle {
respond "Hello World"
}
}
```
Loading

0 comments on commit af347e9

Please sign in to comment.