mirror of
https://github.com/caddyserver/caddy.git
synced 2025-07-31 15:08:42 -04:00
Update for flattened handler structure
parent
c42d220afc
commit
152f709c7e
@ -46,17 +46,21 @@ Features which are available in Caddy Enterprise are indicated with 🏢
|
|||||||
- [http.matchers.not](#httpmatchersnot)
|
- [http.matchers.not](#httpmatchersnot)
|
||||||
- [http.matchers.remote_ip](#httpmatchersremote_ip)
|
- [http.matchers.remote_ip](#httpmatchersremote_ip)
|
||||||
- [http.matchers.starlark_expr](#httpmatchersstarlark_expr)
|
- [http.matchers.starlark_expr](#httpmatchersstarlark_expr)
|
||||||
- [http/servers/apply](#httpserversapply)
|
- [http.matchers.file](#httpmatchersfile)
|
||||||
- [http.middleware.headers](#httpmiddlewareheaders)
|
- [http/servers/handle](#httpserversapply)
|
||||||
- [http.middleware.rewrite](#httpmiddlewarerewrite)
|
- Middleware (non-terminal handlers):
|
||||||
- [http.middleware.markdown](#httpmiddlewaremarkdown)
|
- [http.handlers.headers](#httphandlersheaders)
|
||||||
- [http.middleware.request_body](#httpmiddlewarerequest_body)
|
- [http.handlers.rewrite](#httphandlersrewrite)
|
||||||
- [http.middleware.encode](#httpmiddlewareencode)
|
- [http.handlers.markdown](#httphandlersmarkdown)
|
||||||
- [http.middleware.templates](#httpmiddlewaretemplates)
|
- [http.handlers.request_body](#httphandlersrequest_body)
|
||||||
- [http/servers/respond](#httpserversrespond)
|
- [http.handlers.encode](#httphandlersencode)
|
||||||
- [http.responders.static](#httprespondersstatic)
|
- [http.handlers.templates](#httphandlerstemplates)
|
||||||
- [http.responders.file_server](#httprespondersfile_server)
|
- Terminal handlers:
|
||||||
- [http.responders.reverse_proxy](#httprespondersreverse_proxy)
|
- [http.handlers.static_response](#httphandlersstaticresponse)
|
||||||
|
- [http.handlers.file_server](#httphandlersfile_server)
|
||||||
|
- [http.handlers.reverse_proxy](#httphandlersreverse_proxy)
|
||||||
|
- [http.handlers.subroute](#httphandlerssubroute)
|
||||||
|
- [http.handlers.error](#httphandlerserror)
|
||||||
- [http/servers/errors](#httpserverserrors)
|
- [http/servers/errors](#httpserverserrors)
|
||||||
- [http/servers/tls_conn_policies](#httpserverstls_conn_policies)
|
- [http/servers/tls_conn_policies](#httpserverstls_conn_policies)
|
||||||
- [tls.certificate_selection.enterprise](#tlscertificate_selectionenterprise)
|
- [tls.certificate_selection.enterprise](#tlscertificate_selectionenterprise)
|
||||||
@ -167,7 +171,7 @@ Exports Caddy's current configuration. Returns a JSON body. Any path appended to
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ curl "http://localhost:2019/config/"
|
$ curl "http://localhost:2019/config/"
|
||||||
{"apps":{"http":{"servers":{"myserver":{"listen":[":443"],"routes":[{"match":[{"host":["example.com"]}],"respond":{"responder":"file_server"}}]}}}}}
|
{"apps":{"http":{"servers":{"myserver":{"listen":[":443"],"routes":[{"match":[{"host":["example.com"]}],"handle":[{"handler":"file_server"}]}]}}}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -431,17 +435,18 @@ For example:
|
|||||||
|
|
||||||
#### http/servers/routes
|
#### http/servers/routes
|
||||||
|
|
||||||
Routes are not your typical notion of routes (i.e. "GET /foo/bar" -> someFunc). Routes in Caddy 2 are much more powerful. They are given in an ordered list, and each route has three (optional) parts:
|
Routes are not your typical notion of routes (i.e. "GET /foo/bar" -> someFunc). Routes in Caddy 2 are much more powerful and dynamic. They are given in an ordered list, and each route has two parts:
|
||||||
|
|
||||||
1. match
|
1. match (optional)
|
||||||
2. apply
|
2. handle
|
||||||
3. respond
|
|
||||||
|
|
||||||
For each request, routes are evaluated in the order they are given in the list. Each route that matches the request is compiled into the _composite route_, which ends up becoming the HTTP handler for the request. (Don't worry, this process is normally quite speedy.)
|
You can think of "match-handle" like "if-then" if that helps (but Caddy config is not really imperative or procedural).
|
||||||
|
|
||||||
Unlike Caddy 1, middleware in Caddy 2 are chained in the order you specify, rather than a hard-coded order. (So be careful!) A responder, if defined, is what actually originates the response. **A good rule of thumb for building routes: keep middleware that deal with the request near the beginning, and middleware that deal with the response near the end.** Generally, this will help ensure you put things in the right order (e.g. the `encode` middleware must wrap the response writer, but you wouldn't want to execute templates on a compressed bitstream, so you'd put a `templates` middleware later in the chain).
|
For each request, route matchers are evaluated in the order they are given in the list. Each route that matches the request is compiled into the _composite route_, which ends up becoming the HTTP handler for the request. All matchers in the routes list are evaluated before the request is sent down the handler chain.
|
||||||
|
|
||||||
In some cases, a request can be _rehandled_, meaning that it is virtually processed through the top-level handler again. This is useful if changes were made to a request (such as rewriting part of it) and you want to process it as if it originally came in like that. Other web servers call this an internal redirect.
|
In Caddy 1, HTTP handlers were chained in a hard-coded order you had no control over. Unlike Caddy 1, handlers in Caddy 2 are chained in the order you specify in the routes. So, the order of routes matters.
|
||||||
|
|
||||||
|
In some cases, a request can be _rehandled_, meaning that it is virtually processed through the top-level handler again. This is useful if changes were made to a request (such as rewriting part of it) and you want to process it as if it originally came in like that. Other web servers call this an internal redirect. Upon rehandling, a new composite route will be compiled and the request will be processed again.
|
||||||
|
|
||||||
The structure for a route is:
|
The structure for a route is:
|
||||||
|
|
||||||
@ -449,16 +454,14 @@ The structure for a route is:
|
|||||||
{
|
{
|
||||||
"group": "",
|
"group": "",
|
||||||
"match": [],
|
"match": [],
|
||||||
"apply": [],
|
"handle": [],
|
||||||
"respond": {},
|
|
||||||
"terminal": false
|
"terminal": false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `group`: If this route belongs to a group, specify its name here. Groups are used for mutual exclusion. Only the first matching route from a group is compiled into the composite route. Think like radio buttons on an HTML form.
|
- `group`: If this route belongs to a group, specify its name here. Groups are used for mutual exclusion. Only the first matching route from a group is compiled into the composite route. (Think like radio buttons on an HTML form.) Groups can be used to implement "else" and "else-if" logic with matchers.
|
||||||
- `match`: The "if" statement of the route. This specifies an ordered list of matcher sets.
|
- `match`: The "if" statement of the route. This specifies an ordered list of matcher sets.
|
||||||
- `apply`: The middleware modules to apply, in the order they are listed. All matching middleware are applied before the matched responder, even if the middleware appear in routes after the responder.
|
- `handle`: The "then" statement of the route. This specifies an ordered list of handlers to chain together. Handlers are chained from first to last, so requests flow from the first handler to the last.
|
||||||
- `respond`: The responder module to use to reply to the request. The responder is the origin of the content. Only the first matching responder will be used; any more will be ignored. The matched responder is always invoked after all the middleware are applied, even if matching middleware appear in later routes.
|
|
||||||
- `terminal`: If true, no additional routes will be considered.
|
- `terminal`: If true, no additional routes will be considered.
|
||||||
|
|
||||||
|
|
||||||
@ -500,18 +503,17 @@ Within an HTTP route, you can use additional placeholders:
|
|||||||
|
|
||||||
If you are using regexp matchers, capture groups (both named and numeric) are available as well:
|
If you are using regexp matchers, capture groups (both named and numeric) are available as well:
|
||||||
|
|
||||||
{http.matchers.path_regexp.PATTERN_NAME.CAPTURE_GROUP_NAME}
|
{http.matchers.PATH_REGEXP.PATTERN_NAME.CAPTURE_GROUP_NAME}
|
||||||
|
|
||||||
Replacing:
|
Replacing:
|
||||||
|
|
||||||
- path_regexp with the name of the matcher that has the regular expression
|
- PATH_REGEXP with the name of the matcher that has the regular expression.
|
||||||
- PATTERN_NAME with the lower-cased name you gave the pattern
|
- PATTERN_NAME with the lower-cased name you gave the pattern.
|
||||||
- CAPTURE_GROUP_NAME with the name or index number of the capture group in the regular expression.
|
- CAPTURE_GROUP_NAME with the name or index number of the capture group in the regular expression.
|
||||||
|
|
||||||
This will allow you to access capture groups from anywhere in your HTTP route.
|
This will allow you to access capture groups from anywhere in your HTTP route.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### http/servers/routes/match
|
#### http/servers/routes/match
|
||||||
|
|
||||||
Each route takes a list of matcher sets. A matcher set is comprised of matchers of various types. A matcher may be comprised of multiple values.
|
Each route takes a list of matcher sets. A matcher set is comprised of matchers of various types. A matcher may be comprised of multiple values.
|
||||||
@ -549,7 +551,9 @@ The expressions in parentheses are matcher sets. This expression has 2 matcher s
|
|||||||
|
|
||||||
Even more advanced logic can be expressed through the Starlark expression matcher at virtually no loss in performance.
|
Even more advanced logic can be expressed through the Starlark expression matcher at virtually no loss in performance.
|
||||||
|
|
||||||
Omit matchers entirely to match all requests.
|
A route may omit matchers entirely to match all requests.
|
||||||
|
|
||||||
|
All matchers within the same route list are evaluated before the requst is handled and do not modify the request, so all the matchers will see the same version of the request.
|
||||||
|
|
||||||
##### http.matchers.host
|
##### http.matchers.host
|
||||||
|
|
||||||
@ -682,12 +686,71 @@ Matches requests by evaluating a Starlark expression. This provides a great deal
|
|||||||
The value should be a Starlark expression. (TODO: examples and docs)
|
The value should be a Starlark expression. (TODO: examples and docs)
|
||||||
|
|
||||||
|
|
||||||
|
##### http.matchers.file
|
||||||
|
|
||||||
#### http/servers/apply
|
Matches requests based on files on disk.
|
||||||
|
|
||||||
The list of middleware to apply to the request.
|
```json
|
||||||
|
"file": {
|
||||||
|
"root": "",
|
||||||
|
"try_files": [],
|
||||||
|
"try_policy": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
##### http.middleware.headers
|
- `root`: The base path with which relative paths will be rooted. Default is current working directory.
|
||||||
|
- `try_files`: A list of root-relative file paths to "try" matching (similar to nginx's try_files). A file will be selected based on try_policy.
|
||||||
|
- `try_policy`: When trying files listed in `try_files`, use this policy to choose one.
|
||||||
|
- `first_exist` (default): Choose the first file that exists.
|
||||||
|
- `smallest_size`: Choose the file with the smallest size.
|
||||||
|
- `largest_size`: Choose the file with the largest size.
|
||||||
|
- `most_recent_modified`: Choose the file that was most recently modified.
|
||||||
|
|
||||||
|
If a file is matched, two new placeholders will be made available:
|
||||||
|
|
||||||
|
- `{http.matchers.file.relative}`: The root-relative path of the file. This is often useful when rewriting requests.
|
||||||
|
- `{http.matchers.file.absolute}`: The absolute path of the file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### http/servers/handle
|
||||||
|
|
||||||
|
Handlers are modules which handle HTTP requests. They are chained together in a middleware fashion: requests flow from the first handler to the last (top of the config to the bottom), with the possibility that any handler could abort the chain and/or return an error. Responses flow back up the chain as they are written out to the client.
|
||||||
|
|
||||||
|
Not all handlers call the next handler in the chain. For example, the `file_server` handler always serves a file from disk or returns an error. Thus, configuring handlers after `file_server` in your route is illogical, since they would never be executed. You will want to put handlers which originate the response at the very end of your route(s). The documentation for a module should state whether it invokes the next handler, but sometimes it is common sense.
|
||||||
|
|
||||||
|
Some handlers manipulate the response. Remember that **requests flow down, and responses flow up**. For example, if you wanted to use both `templates` and `encode` handlers, you would need to put `templates` _after_ `encode` in your route, because responses flow up. Thus, `templates` will be able to parse and execute the plain-text response as a template, and then return it up to the `encode` handler which will then compress it into a binary format:
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"handler": "encode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"handler": "templates"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"handler": "file_server"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
The request flows ⬇️ **DOWN** (`encode` -> `templates` -> `file_server`).
|
||||||
|
|
||||||
|
1. First, `encode` will choose how to encode the response and wrap the response.
|
||||||
|
2. Then, `templates` will wrap the response with a buffer.
|
||||||
|
3. Finally, `file_server` will originate the content from a file.
|
||||||
|
|
||||||
|
The response flows ⬆️ **UP** (`file_server` -> `templates` -> `encode`):
|
||||||
|
|
||||||
|
1. First, `file_server` will write the file to the response.
|
||||||
|
2. That write will be buffered and then executed by `templates`.
|
||||||
|
3. Lastly, the write from templates will flow into `encode` which will compress the stream.
|
||||||
|
|
||||||
|
If you think of routes in this way, it will be easy and even fun to solve the puzzle of writing correct routes.
|
||||||
|
|
||||||
|
|
||||||
|
##### http.handlers.headers
|
||||||
|
|
||||||
Modifies request or response headers.
|
Modifies request or response headers.
|
||||||
|
|
||||||
@ -699,7 +762,7 @@ Response header operations can be conditioned upon response status code and/or o
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"middleware": "headers",
|
"handler": "headers",
|
||||||
"request": {
|
"request": {
|
||||||
"set": {
|
"set": {
|
||||||
"Field": ["overwrites"]
|
"Field": ["overwrites"]
|
||||||
@ -736,7 +799,7 @@ Response header operations can be conditioned upon response status code and/or o
|
|||||||
- `response.require.headers`: Apply response header changes if the given response headers have the given value(s).
|
- `response.require.headers`: Apply response header changes if the given response headers have the given value(s).
|
||||||
|
|
||||||
|
|
||||||
##### http.middleware.rewrite
|
##### http.handlers.rewrite
|
||||||
|
|
||||||
Changes the request's URI or method.
|
Changes the request's URI or method.
|
||||||
|
|
||||||
@ -744,7 +807,7 @@ Properties in this module accept placeholders.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"middleware": "rewrite",
|
"handler": "rewrite",
|
||||||
"method": "FOO",
|
"method": "FOO",
|
||||||
"uri": "/new/path?param=val",
|
"uri": "/new/path?param=val",
|
||||||
"rehandle": false
|
"rehandle": false
|
||||||
@ -756,26 +819,25 @@ Properties in this module accept placeholders.
|
|||||||
- `rehandle`: If true, the request will sent for rehandling after rewriting.
|
- `rehandle`: If true, the request will sent for rehandling after rewriting.
|
||||||
|
|
||||||
|
|
||||||
##### http.middleware.markdown
|
##### http.handlers.markdown
|
||||||
|
|
||||||
Currently, does almost nothing: very plain/simple markdown rendering
|
Currently, does almost nothing: very plain/simple markdown rendering using Blackfriday. Will be configurable. But unlike Caddy 1, this already allows rendering *any* response body as Markdown, whether it be from a proxied upstream or a static file server. This needs a lot more testing and development.
|
||||||
using Blackfriday. Will be configurable. But unlike Caddy 1, this already allows rendering *any* response body as Markdown, whether it be from a proxied upstream or a static file server. This needs a lot more testing and development.
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"middleware": "markdown"
|
"handler": "markdown"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
##### http.middleware.request_body
|
##### http.handlers.request_body
|
||||||
|
|
||||||
Change or limit the request body.
|
Change or limit the request body.
|
||||||
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"middleware": "request_body",
|
"handler": "request_body",
|
||||||
"max_size": 0
|
"max_size": 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -783,13 +845,13 @@ Change or limit the request body.
|
|||||||
- `max_size`: The maximum number of bytes to allow reading from the body by a later handler.
|
- `max_size`: The maximum number of bytes to allow reading from the body by a later handler.
|
||||||
|
|
||||||
|
|
||||||
##### http.middleware.encode
|
##### http.handlers.encode
|
||||||
|
|
||||||
Compresses responses on-the-fly.
|
Compresses responses on-the-fly.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"middleware": "encode",
|
"handler": "encode",
|
||||||
"encodings": {
|
"encodings": {
|
||||||
"gzip": {"level": 5},
|
"gzip": {"level": 5},
|
||||||
"zstd": {},
|
"zstd": {},
|
||||||
@ -805,41 +867,34 @@ Compresses responses on-the-fly.
|
|||||||
- `minimum_length`: Only encode responses that are at least this many bytes long.
|
- `minimum_length`: Only encode responses that are at least this many bytes long.
|
||||||
|
|
||||||
|
|
||||||
##### http.middleware.templates
|
##### http.handlers.templates
|
||||||
|
|
||||||
Interprets the response as a template body, then executes the template and writes the response to the client. Template functions will be documented soon. There are functions to include other files,
|
Interprets the response as a template body, then executes the template and writes the response to the client. Template functions will be documented soon. There are functions to include other files, make sub-requests (virtual HTTP requests), render Markdown, manipulate headers, access the request fields, manipulate strings, do math, work with data structures, and more.
|
||||||
make sub-requests (virtual HTTP requests), render Markdown, manipulate headers, access the request fields, manipulate strings, do math, work with data structures, and more.
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"middleware": "templates",
|
"handler": "templates",
|
||||||
"file_root": "",
|
"include_root": "",
|
||||||
"mime_types": ["text/html", "text/plain", "text/markdown"],
|
"mime_types": ["text/html", "text/plain", "text/markdown"],
|
||||||
"delimiters": ["{{", "}}"]
|
"delimiters": ["{{", "}}"]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `file_root`: The root path from which to load files. Required if template functions accessing the file system are used (such as .Include).
|
- `include_root`: The root path from which to load files. Required if template functions accessing the file system are used (such as .Include).
|
||||||
- `mime_types`: The MIME types for which to render templates. It is important to use this if the route matchers do not exclude images or other binary files...
|
- `mime_types`: The MIME types for which to render templates. It is important to use this if the route matchers do not exclude images or other binary files.
|
||||||
- `delimiters`: The template action delimiters.
|
- `delimiters`: The template action delimiters.
|
||||||
|
|
||||||
#### http/servers/respond
|
|
||||||
|
|
||||||
The responder to use to reply to the request. The responder is the origin of the content or essense of the response. Each composite route will only have one responder.
|
##### http.handlers.static_response
|
||||||
|
|
||||||
|
Responds to the request with a static (hard-coded) response. Does not call the next handler in the chain.
|
||||||
|
|
||||||
##### http.responders.static
|
This is a great way to do HTTP redirects.
|
||||||
|
|
||||||
Responds to the request with a static (hard-coded) response.
|
|
||||||
|
|
||||||
For instance, this is a great way to do HTTP redirects.
|
|
||||||
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"responder": "static",
|
"handler": "static_response",
|
||||||
"status_code": 307,
|
"status_code": 307,
|
||||||
"status_code_str": "{http.error.status_code}",
|
|
||||||
"headers": {
|
"headers": {
|
||||||
"Location": ["https://example.com/foo"]
|
"Location": ["https://example.com/foo"]
|
||||||
},
|
},
|
||||||
@ -848,31 +903,26 @@ For instance, this is a great way to do HTTP redirects.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `status_code`: The numeric HTTP status code to respond with.
|
- `status_code`: The HTTP status code to respond with. Can be an integer or, if needing to use a placeholder, a string.
|
||||||
- `status_code_str`: A string form of the status code to respond with, allowing use of placeholders. TODO: We might just consolidate these two fields and make it only a string.
|
|
||||||
- `headers`: Header fields to set on the response.
|
- `headers`: Header fields to set on the response.
|
||||||
- `body`: The response body.
|
- `body`: The response body.
|
||||||
- `close`: If true, the client's connection will be closed after writing the response.
|
- `close`: If true, the server will close the client's connection after writing the response.
|
||||||
|
|
||||||
|
|
||||||
##### http.responders.file_server
|
##### http.handlers.file_server
|
||||||
|
|
||||||
A powerful, flexible static file server.
|
A powerful, flexible static file server.
|
||||||
|
|
||||||
In general, the request URI's path will be joined to the file server's root to get the file path to serve.
|
In general, the request URI's path will be joined to the file server's root to get the file path to serve.
|
||||||
|
|
||||||
This module executes placeholders in most of its properties.
|
This module executes placeholders in most of its properties. It does not call the next handler in the chain.
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"responder": "file_server",
|
"handler": "file_server",
|
||||||
"root": "",
|
"root": "",
|
||||||
"hide": [],
|
"hide": [],
|
||||||
"index_names": [],
|
"index_names": [],
|
||||||
"files": [],
|
|
||||||
"selection_policy": "first_existing",
|
|
||||||
"rehandle": false,
|
|
||||||
"fallback": [],
|
|
||||||
"browse": {
|
"browse": {
|
||||||
"template_file": ""
|
"template_file": ""
|
||||||
}
|
}
|
||||||
@ -882,28 +932,20 @@ This module executes placeholders in most of its properties.
|
|||||||
- `root`: The path to the root of the site.
|
- `root`: The path to the root of the site.
|
||||||
- `hide`: A list of files or folders to hide; the file server will pretend as if they don't exist. Accepts globular patterns like "\*.hidden" or "/foo/*/bar".
|
- `hide`: A list of files or folders to hide; the file server will pretend as if they don't exist. Accepts globular patterns like "\*.hidden" or "/foo/*/bar".
|
||||||
- `index_names`: The names of files to try as index files if a folder is requested.
|
- `index_names`: The names of files to try as index files if a folder is requested.
|
||||||
- `files`: A list of files or file paths to try, similar to NGINX's try_files (TODO: Might rename to try or try_files).
|
|
||||||
- `selection_policy`: When trying files listed in `files`, use this policy to choose one.
|
|
||||||
- `first_existing` (default): Use the first file that exists.
|
|
||||||
- `smallest_size`: Choose the file with the smallest size.
|
|
||||||
- `largest_size`: Choose the file with the largest size.
|
|
||||||
- `most_recently_modified`: Choose the file that was most recently modified.
|
|
||||||
- `rehandle`: If true, and if the request was mapped to a different file than the URI path originally pointed to, the request will be sent for rehandling. This includes if an index file is chosen when a directory was requested.
|
|
||||||
- `fallback`: If no files were found or chosen to satisfy the request, the routes in this list will be compiled and executed instead. It's like an "else" clause.
|
|
||||||
- `browse`: Enables browsing if a directory was requested.
|
- `browse`: Enables browsing if a directory was requested.
|
||||||
- `browse.template_file`: Use this template file instead of the default browse template.
|
- `browse.template_file`: Use this template file instead of the default browse template.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### http.responders.reverse_proxy
|
##### http.handlers.reverse_proxy
|
||||||
|
|
||||||
Reverse proxy. Still a WIP.
|
Reverse proxy. Still a WIP. Does not call the next handler in the chain.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"responder": "reverse_proxy",
|
"handler": "reverse_proxy",
|
||||||
"try_interval": "20s",
|
"try_interval": "20s",
|
||||||
"load_balance_type": "round_robin",
|
"load_balance_type": "round_robin",
|
||||||
"upstreams": [
|
"upstreams": [
|
||||||
@ -932,6 +974,38 @@ Example:
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
##### http.handlers.subroute
|
||||||
|
|
||||||
|
Creates a group of routes that are compiled and executed when this handler is invoked. This is useful if the evaluation of matchers needs to be deferred, like if they depend on placeholders created by other matchers that need to be evaluated first.
|
||||||
|
|
||||||
|
This handler does not invoke the next handler in the chain. Instead, it compiles and executes the chain defined in `routes`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"handler": "subroute",
|
||||||
|
"routes": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `routes`: The list of routes to compile and execute.
|
||||||
|
|
||||||
|
|
||||||
|
##### http.handlers.error
|
||||||
|
|
||||||
|
This handler returns an error value, but does not write a response. This is useful when you want the server to act as if an error occurred; for example, to invoke your custom error handling logic.
|
||||||
|
|
||||||
|
Since this handler does not write a response, the error information is for use by the server or other handlers to know how to handle the error.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"handler": "error",
|
||||||
|
"status_code": 404,
|
||||||
|
"error": ""
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `status_code`: The recommended HTTP status code. Can be either an integer or a string if placeholders are needed. Optional. Default is 500.
|
||||||
|
- `error`: The error message. Optional. Default is no error message.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -939,7 +1013,7 @@ Example:
|
|||||||
|
|
||||||
Specifies how to handle errors returned from the HTTP handlers.
|
Specifies how to handle errors returned from the HTTP handlers.
|
||||||
|
|
||||||
If a handler returns an error, the error along with its recommended status code are bubbled back to the HTTP server which executes a separate error route, specified using this property. The error routes work exactly like the normal routes.
|
If a [handler](#httpservershandle) chain returns an error, the error along with its recommended status code are bubbled back to the HTTP server which executes a separate error route, specified using this property. The error routes work exactly like the normal routes.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user