docs: Unify matcher reference docs

This commit is contained in:
Matthew Holt 2020-03-22 17:23:50 -06:00
parent 7aea0e2606
commit 1aaff7aeb4
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5
6 changed files with 114 additions and 101 deletions

View file

@ -207,7 +207,7 @@ There; now the reverse proxy will be prioritized for all requests starting with
The `/api/*` token we just added is called a **matcher token**. You can tell it's a matcher token because it starts with a forward slash `/` and it appears right after the directive (but you can always look it up in the [directive's docs](/docs/caddyfile/directives) to be sure).
Matchers are actually really powerful. You can name matchers and use them like `@name` to match on more than just the request path! Take a moment to [learn more about matchers](/docs/caddyfile/concepts#matchers) before continuing!
Matchers are actually really powerful. You can name matchers and use them like `@name` to match on more than just the request path! Take a moment to [learn more about matchers](/docs/caddyfile/matchers) before continuing!
<aside class="complete">✅ Matchers</aside>

View file

@ -161,98 +161,19 @@ An address must be unique; you cannot specify the same address more than once.
By default, a directive that injects an HTTP handler applies to all requests (unless otherwise documented).
**Request matchers** can be used to classify requests by a given criteria. This concept originates in the [underlying JSON](/docs/json/apps/http/servers/routes/match/) structure, and it's important to know how to use them in the Caddyfile. With matchers, you can specify exactly which requests a directive applies to.
Request matchers can be used to classify requests by a given criteria. This concept originates in the [underlying JSON](/docs/json/apps/http/servers/routes/match/) structure, and it's important to know how to use them in the Caddyfile. With matchers, you can specify exactly which requests a certain directive applies to.
To limit a directive's scope, use a **matcher token** immediately following the directive, [if the directive supports matchers](/docs/caddyfile/directives#matchers). The matcher token can be one of these forms:
1. **`*`** to match all requests (wildcard; default).
2. **`/path`** start with a forward slash to match a request path.
3. **`@name`** to specify a _named matcher_.
Matcher tokens are usually optional. If a matcher token is omitted, it is the same as a wildcard matcher (`*`).
### Wildcard matcher
The wildcard matcher `*` matches all requests, and is only needed if a matcher token is required. For example, if the first argument you want to give a directive also happens to be a path, it would look exactly like a path matcher! So you can use a wildcard matcher to disambiguate, for example:
For directives that support matchers, the first argument after the directive is the **matcher token**. Here are some examples:
```
root * /home/www/mysite
root * /var/www # matcher token: *
root /index.html /var/www # matcher token: /index.html
root @post /var/www # matcher token: @post
```
Otherwise, this matcher is not often used. It is convenient to omit it when possible; just a matter of preference.
Matcher tokens can be omitted entirely to match all requests; for example, `*` or `/` do not need to be given.
### Path matcher
Because matching by path is so common, a single path matcher can be inlined, like so:
```
redir /old-article.html /new-article.html
```
Path matcher tokens must start with a forward slash `/`.
[Path matching](/docs/caddyfile/matchers#path) is an exact match by default; you must append a `*` for a fast prefix match. Note that `/foo*` will match `/foo` and `/foo/` as well as `/foobar`; if this is unintended, you might actually want `/foo/*` instead.
### Named matcher
Defining a matcher with a unique name gives you more flexibility, allowing you to combine [any available matchers](/docs/caddyfile/matchers):
```
@name {
...
}
```
Then you can use the matcher like so: `@name`
For example:
```
@websockets {
header Connection *Upgrade*
header Upgrade websocket
}
reverse_proxy @websockets localhost:6001
```
This proxies only the requests that have a header field named "Connection" containing the word "Upgrade", and another header named "Upgrade" with a value of "websocket".
Like directives, named matcher definitions must go inside the site blocks that use them.
**[View full list of standard request matchers.](/docs/caddyfile/matchers)**
### Matcher examples
This directive applies to all HTTP requests:
```
reverse_proxy localhost:9000
```
And this is the same:
```
reverse_proxy * localhost:9000
```
But this directive applies only to requests having a path starting with `/api/`:
```
reverse_proxy /api/* localhost:9000
```
To match on anything other than a path, define a **named matcher** and refer to it using `@name`:
```
@post {
method POST
}
reverse_proxy @post localhost:9000
```
**[Read the page about request matchers](/docs/caddyfile/matchers) to learn more.**

View file

@ -50,7 +50,7 @@ Subdirectives are always optional unless documented otherwise, even though they
### Matchers
Most---but not all---directives accept [matcher tokens](/docs/caddyfile/concepts#matchers), which let you filter requests. Matcher tokens are usually optional. If you see this in a directive's syntax:
Most---but not all---directives accept [matcher tokens](/docs/caddyfile/matchers#syntax), which let you filter requests. Matcher tokens are usually optional. If you see this in a directive's syntax:
```
[<matcher>]
@ -58,7 +58,7 @@ Most---but not all---directives accept [matcher tokens](/docs/caddyfile/concepts
then the directive accepts a matcher token, letting you filter which requests the directive applies to.
Because matcher tokens all work the same, the various possibilities for the matcher token will not be described on every page, to reduce duplication. Instead, refer to the centralized [matcher documentation](/docs/caddyfile/concepts#matchers).
Because matcher tokens all work the same, the various possibilities for the matcher token will not be described on every page, to reduce duplication. Instead, refer to the centralized [matcher documentation](/docs/caddyfile/matchers).
## Directive order

View file

@ -27,7 +27,7 @@ Set the site root to `/home/user/public_html` for all requests:
root * /home/user/public_html
```
(A [wildcard matcher](/docs/caddyfile/concepts#wildcard-matcher) is required in this case because the first argument is ambiguous with a [path matcher](/docs/caddyfile/concepts#path-matcher).)
(A [wildcard matcher](/docs/caddyfile/matchers#wildcard-matchers) is required in this case because the first argument is ambiguous with a [path matcher](/docs/caddyfile/matchers#path-matchers).)
Set the site root to `public_html` (relative to current working directory) for all requests:

View file

@ -4,27 +4,119 @@ title: Request matchers (Caddyfile)
# Request Matchers
Matchers are used to filter requests.
**Request matchers** can be used to filter (or classify) requests by specific criteria.
There are many dimensions across which requests can be matched! This page describes the various ways you can match (i.e. filter or select) requests.
### Menu
**If you don't know what a matcher is or how to use it, first [visit the "Concepts" page to learn more](/docs/caddyfile/concepts#matchers)**.
- [Syntax](#syntax)
- [Examples](#examples)
- [Wildcard matchers](#wildcard-matchers)
- [Path matchers](#path-matchers)
- [Named matchers](#named-matchers)
- [Standard matchers](#standard-matchers)
## Syntax
The matchers documented below should be used within the definition of [named matchers](/docs/caddyfile/concepts#named-matcher), in other words, within:
In the Caddyfile, a **matcher token** immediately following the directive can limit that directive's scope. The matcher token can be one of these forms:
1. **`*`** to match all requests (wildcard; default).
2. **`/path`** start with a forward slash to match a request path.
3. **`@name`** to specify a _named matcher_.
Matcher tokens are [usually optional](/docs/caddyfile/directives#matchers). If a matcher token is omitted, it is the same as a wildcard matcher (`*`).
#### Examples
This directive applies to [all](#wildcard-matchers) HTTP requests:
```
reverse_proxy localhost:9000
```
And this is the same:
```
reverse_proxy * localhost:9000
```
But this directive applies only to requests having a [path](#path-matchers) starting with `/api/`:
```
reverse_proxy /api/* localhost:9000
```
To match on anything other than a path, define a [named matcher](#named-matchers) and refer to it using `@name`:
```
@post {
method POST
}
reverse_proxy @post localhost:9000
```
### Wildcard matchers
The wildcard matcher `*` matches all requests, and is only needed if a matcher token is required. For example, if the first argument you want to give a directive also happens to be a path, it would look exactly like a path matcher! So you can use a wildcard matcher to disambiguate, for example:
```
root * /home/www/mysite
```
Otherwise, this matcher is not often used. It is convenient to omit it when possible; just a matter of preference.
### Path matchers
Because matching by path is so common, a single path matcher can be inlined, like so:
```
redir /old.html /new.html
```
Path matcher tokens must start with a forward slash `/`.
[Path matching](/docs/caddyfile/matchers#path) is an exact match by default; you must append a `*` for a fast prefix match. Note that `/foo*` will match `/foo` and `/foo/` as well as `/foobar`; you might actually want `/foo/*` instead.
### Named matchers
Defining a matcher with a unique name gives you more flexibility, allowing you to combine [any available matchers](#standard-matchers) into a set:
```
@name {
# here
...
}
```
A matcher definition constitutes a _matcher set_. Matchers in a set are AND'ed together; i.e. all must match. For example, if you have both a `header` and `path` matcher in the set, both must match.
Then you can use the matcher like so: `@name`
For example:
```
@websockets {
header Connection *Upgrade*
header Upgrade websocket
}
reverse_proxy @websockets localhost:6001
```
This proxies only the requests that have a header field named "Connection" containing the word "Upgrade", and another field named "Upgrade" with a value of "websocket".
Like directives, named matcher definitions must go inside the site blocks that use them.
A named matcher definition constitutes a _matcher set_. Matchers in a set are AND'ed together; i.e. all must match. For example, if you have both a `header` and `path` matcher in the set, both must match.
For most matchers that accept multiple values, those values are OR'ed; i.e. one must match in order for the matcher to match.
## Standard matchers
Full matcher documentation can be found [in each respective matcher module's docs](/docs/json/apps/http/servers/routes/match/).

View file

@ -99,9 +99,9 @@ The [v2 Caddyfile](/docs/caddyfile/concepts) is very similar to what you're alre
- If you are serving static files, you will need to add a [`file_server` directive](/docs/caddyfile/directives/file_server), since Caddy 2 does not assume this by default.
- In v1, you could only filter (or "match") directives by request path. In v2, [request matching](/docs/caddyfile/concepts#matchers) is much more powerful. Any v2 directives which add a middleware to the HTTP handler chain or which manipulate the HTTP request/response in any way take advantage of this new matching functionality. [Read more about v2 request matchers.](/docs/caddyfile/concepts#matchers) You'll need to know about them to make sense of the v2 Caddyfile.
- In v1, you could only filter (or "match") directives by request path. In v2, [request matching](/docs/caddyfile/matchers) is much more powerful. Any v2 directives which add a middleware to the HTTP handler chain or which manipulate the HTTP request/response in any way take advantage of this new matching functionality. [Read more about v2 request matchers.](/docs/caddyfile/matchers) You'll need to know about them to make sense of the v2 Caddyfile.
- Although many [placeholders](/docs/conventions#placeholders) are the same, many have changed, and there are now [many new ones](/docs/modules/http).
- Although many [placeholders](/docs/conventions#placeholders) are the same, many have changed, and there are now [many new ones](/docs/modules/http), including [shorthands for the Caddyfile](/docs/caddyfile/concepts#placeholders).
- Caddy 2 logs are all structured, and the default format is JSON. All log levels can simply go to the same log to be processed (but you can customize this if needed).
@ -213,16 +213,16 @@ rewrite {
rewrite @mobile /mobile{uri}
```
Notice how we simply use Caddy 2's usual [matcher tokens](/docs/caddyfile/concepts#matchers); it's no longer a special case for this directive.
Notice how we simply use Caddy 2's usual [matcher tokens](/docs/caddyfile/matchers); it's no longer a special case for this directive.
Start by removing all rewrite hacks; turn them into [named matchers](/docs/caddyfile/concepts#named-matcher) instead. Evaluate each v1 `rewrite` to see if it's really needed in v2. Hint: A v1 Caddyfile that uses `rewrite` to add a path prefix and then `proxy` with `without` to remove that same prefix is a rewrite hack, and can be eliminated.
Start by removing all rewrite hacks; turn them into [named matchers](/docs/caddyfile/concepts#named-matchers) instead. Evaluate each v1 `rewrite` to see if it's really needed in v2. Hint: A v1 Caddyfile that uses `rewrite` to add a path prefix and then `proxy` with `without` to remove that same prefix is a rewrite hack, and can be eliminated.
You may find the new [`route`](/docs/caddyfile/directives/route) and [`handle`](/docs/caddyfile/directives/handle) directives useful for having greater control over advanced routing logic.
### root
[Unchanged](/docs/caddyfile/directives/root), but if your root path starts with `/`, you'll need to add a `*` matcher token to distinguish it from a [path matcher](/docs/caddyfile/concepts#path-matcher).
[Unchanged](/docs/caddyfile/directives/root), but if your root path starts with `/`, you'll need to add a `*` matcher token to distinguish it from a [path matcher](/docs/caddyfile/concepts#path-matchers).
- **v1:** `root /var/www`
- **v2:** `root * /var/www`