Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
Improve godocs all around
These will be used in the new automated documentation system
Matthew Holt committed
Dec 23, 2019 at 12:45 UTC
95ed603de79c66ff76bfe7e42986a2fc8c7a1fa4
26 files changed
+388
-99
modules/caddyhttp/caddyauth/basicauth.go
+15
-4
@@ -28,9 +28,14 @@ func init() {
28
29
// HTTPBasicAuth facilitates HTTP basic authentication.
30
type HTTPBasicAuth struct {
31
- HashRaw json.RawMessage `json:"hash,omitempty" caddy:"namespace=http.authentication.hashes inline_key=algorithm"`
32
- AccountList []Account `json:"accounts,omitempty"`
33
- Realm string `json:"realm,omitempty"`
31
+ // The algorithm with which the passwords are hashed. Default: bcrypt
32
+ HashRaw json.RawMessage `json:"hash,omitempty" caddy:"namespace=http.authentication.hashes inline_key=algorithm"`
33
+
34
+ // The list of accounts to authenticate.
35
+ AccountList []Account `json:"accounts,omitempty"`
36
+
37
+ // The name of the realm. Default: restricted
38
+ Realm string `json:"realm,omitempty"`
39
40
Accounts map[string]Account `json:"-"`
41
Hash Comparer `json:"-"`
@@ -125,9 +130,15 @@ type Comparer interface {
130
131
// Account contains a username, password, and salt (if applicable).
132
type Account struct {
133
+ // A user's username.
134
Username string `json:"username"`
135
+
136
+ // The user's hashed password, base64-encoded.
137
Password []byte `json:"password"`
130
- Salt []byte `json:"salt,omitempty"` // for algorithms where external salt is needed
138
+
139
+ // The user's password salt, base64-encoded; for
140
+ // algorithms where external salt is needed.
141
+ Salt []byte `json:"salt,omitempty"`
142
}
143
144
// Interface guards
modules/caddyhttp/caddyauth/caddyauth.go
+3
@@ -28,7 +28,10 @@ func init() {
28
}
29
30
// Authentication is a middleware which provides user authentication.
31
+// Rejects requests with HTTP 401 if the request is not authenticated.
32
type Authentication struct {
33
+ // A set of authentication providers. If none are specified,
34
+ // all requests will always be unauthenticated.
35
ProvidersRaw caddy.ModuleMap `json:"providers,omitempty" caddy:"namespace=http.authentication.providers"`
36
37
Providers map[string]Authenticator `json:"-"`
modules/caddyhttp/caddyauth/hashes.go
+11
-3
@@ -52,9 +52,17 @@ func (BcryptHash) Compare(hashed, plaintext, _ []byte) (bool, error) {
52
53
// ScryptHash implements the scrypt KDF as a hash.
54
type ScryptHash struct {
55
- N int `json:"N,omitempty"`
56
- R int `json:"r,omitempty"`
57
- P int `json:"p,omitempty"`
55
+ // scrypt's N parameter. If unset or 0, a safe default is used.
56
+ N int `json:"N,omitempty"`
57
+
58
+ // scrypt's r parameter. If unset or 0, a safe default is used.
59
+ R int `json:"r,omitempty"`
60
+
61
+ // scrypt's p parameter. If unset or 0, a safe default is used.
62
+ P int `json:"p,omitempty"`
63
+
64
+ // scrypt's key length parameter (in bytes). If unset or 0, a
65
+ // safe default is used.
66
KeyLength int `json:"key_length,omitempty"`
67
}
68
modules/caddyhttp/encode/brotli/brotli.go
+3
-1
@@ -29,7 +29,9 @@ func init() {
29
}
30
31
// Brotli can create brotli encoders. Note that brotli
32
-// is not known for great encoding performance.
32
+// is not known for great encoding performance, and
33
+// its use during requests is discouraged; instead,
34
+// pre-compress the content instead.
35
type Brotli struct {
36
Quality *int `json:"quality,omitempty"`
37
}
modules/caddyhttp/encode/encode.go
+8
-4
@@ -39,9 +39,15 @@ func init() {
39
40
// Encode is a middleware which can encode responses.
41
type Encode struct {
42
+ // Selection of compression algorithms to choose from. The best one
43
+ // will be chosen based on the client's Accept-Encoding header.
44
EncodingsRaw caddy.ModuleMap `json:"encodings,omitempty" caddy:"namespace=http.encoders"`
43
- Prefer []string `json:"prefer,omitempty"`
44
- MinLength int `json:"minimum_length,omitempty"`
45
+
46
+ // If the client has no strong preference, choose this encoding. TODO: Not yet implemented
47
+ // Prefer []string `json:"prefer,omitempty"`
48
+
49
+ // Only encode responses that are at least this many bytes long.
50
+ MinLength int `json:"minimum_length,omitempty"`
51
52
writerPools map[string]*sync.Pool // TODO: these pools do not get reused through config reloads...
53
}
@@ -66,11 +72,9 @@ func (enc *Encode) Provision(ctx caddy.Context) error {
72
return fmt.Errorf("adding encoding %s: %v", modName, err)
73
}
74
}
69
-
75
if enc.MinLength == 0 {
76
enc.MinLength = defaultMinLength
77
}
73
-
78
return nil
79
}
80
modules/caddyhttp/fileserver/browse.go
+1
@@ -29,6 +29,7 @@ import (
29
30
// Browse configures directory browsing.
31
type Browse struct {
32
+ // Use this template file instead of the default browse template.
33
TemplateFile string `json:"template_file,omitempty"`
34
35
template *template.Template
modules/caddyhttp/fileserver/matcher.go
+14
-8
@@ -46,7 +46,13 @@ type MatchFile struct {
46
// placeholders.
47
TryFiles []string `json:"try_files,omitempty"`
48
49
- // How to choose a file in TryFiles.
49
+ // How to choose a file in TryFiles. Can be:
50
+ //
51
+ // - first_exist
52
+ // - smallest_size
53
+ // - largest_size
54
+ // - most_recently_modified
55
+ //
56
// Default is first_exist.
57
TryPolicy string `json:"try_policy,omitempty"`
58
}
@@ -64,7 +70,7 @@ func (MatchFile) CaddyModule() caddy.ModuleInfo {
70
// file {
71
// root <path>
72
// try_files <files...>
67
-// try_policy first_exist|smallest_size|largest_size|most_recent_modified
73
+// try_policy first_exist|smallest_size|largest_size|most_recently_modified
74
// }
75
//
76
func (m *MatchFile) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
@@ -107,7 +113,7 @@ func (m MatchFile) Validate() error {
113
tryPolicyFirstExist,
114
tryPolicyLargestSize,
115
tryPolicySmallestSize,
110
- tryPolicyMostRecentMod:
116
+ tryPolicyMostRecentlyMod:
117
default:
118
return fmt.Errorf("unknown try policy %s", m.TryPolicy)
119
}
@@ -187,7 +193,7 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
193
}
194
return smallestSuffix, smallestFilename, true
195
190
- case tryPolicyMostRecentMod:
196
+ case tryPolicyMostRecentlyMod:
197
var recentDate time.Time
198
var recentFilename string
199
var recentSuffix string
@@ -238,10 +244,10 @@ func strictFileExists(file string) bool {
244
}
245
246
const (
241
- tryPolicyFirstExist = "first_exist"
242
- tryPolicyLargestSize = "largest_size"
243
- tryPolicySmallestSize = "smallest_size"
244
- tryPolicyMostRecentMod = "most_recent_modified"
247
+ tryPolicyFirstExist = "first_exist"
248
+ tryPolicyLargestSize = "largest_size"
249
+ tryPolicySmallestSize = "smallest_size"
250
+ tryPolicyMostRecentlyMod = "most_recently_modified"
251
)
252
253
// Interface guards
modules/caddyhttp/fileserver/staticfiles.go
+23
-6
@@ -42,12 +42,29 @@ func init() {
42
43
// FileServer implements a static file server responder for Caddy.
44
type FileServer struct {
45
- Root string `json:"root,omitempty"` // default is current directory
46
- Hide []string `json:"hide,omitempty"`
47
- IndexNames []string `json:"index_names,omitempty"`
48
- Browse *Browse `json:"browse,omitempty"`
49
- CanonicalURIs *bool `json:"canonical_uris,omitempty"`
50
- PassThru bool `json:"pass_thru,omitempty"` // if 404, call next handler instead
45
+ // The path to the root of the site. Default is `{http.vars.root}` if set,
46
+ // or current working directory otherwise.
47
+ Root string `json:"root,omitempty"`
48
+
49
+ // A list of files or folders to hide; the file server will pretend as if
50
+ // they don't exist. Accepts globular patterns like "*.hidden" or "/foo/*/bar".
51
+ Hide []string `json:"hide,omitempty"`
52
+
53
+ // The names of files to try as index files if a folder is requested.
54
+ IndexNames []string `json:"index_names,omitempty"`
55
+
56
+ // Enables file listings if a directory was requested and no index
57
+ // file is present.
58
+ Browse *Browse `json:"browse,omitempty"`
59
+
60
+ // Use redirects to enforce trailing slashes for directories, or to
61
+ // remove trailing slash from URIs for files. Default is true.
62
+ CanonicalURIs *bool `json:"canonical_uris,omitempty"`
63
+
64
+ // If pass-thru mode is enabled and a requested file is not found,
65
+ // it will invoke the next handler in the chain instead of returning
66
+ // a 404 error. By default, this is false (disabled).
67
+ PassThru bool `json:"pass_thru,omitempty"`
68
}
69
70
// CaddyModule returns the Caddy module information.
modules/caddyhttp/headers/headers.go
+41
-13
@@ -28,7 +28,18 @@ func init() {
28
caddy.RegisterModule(Handler{})
29
}
30
31
-// Handler is a middleware which can mutate HTTP headers.
31
+// Handler is a middleware which modifies request and response headers.
32
+//
33
+// Changes to headers are applied immediately, except for the response
34
+// headers when Deferred is true or when Required is set. In those cases,
35
+// the changes are applied when the headers are written to the response.
36
+// Note that deferred changes do not take effect if an error occurs later
37
+// in the middleware chain.
38
+//
39
+// Properties in this module accept placeholders.
40
+//
41
+// Response header operations can be conditioned upon response status code
42
+// and/or other header values.
43
type Handler struct {
44
Request *HeaderOps `json:"request,omitempty"`
45
Response *RespHeaderOps `json:"response,omitempty"`
@@ -99,12 +110,18 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
110
return next.ServeHTTP(w, r)
111
}
112
102
-// HeaderOps defines some operations to
103
-// perform on HTTP headers.
113
+// HeaderOps defines manipulations for HTTP headers.
114
type HeaderOps struct {
105
- Add http.Header `json:"add,omitempty"`
106
- Set http.Header `json:"set,omitempty"`
107
- Delete []string `json:"delete,omitempty"`
115
+ // Adds HTTP headers; does not replace any existing header fields.
116
+ Add http.Header `json:"add,omitempty"`
117
+
118
+ // Sets HTTP headers; replaces existing header fields.
119
+ Set http.Header `json:"set,omitempty"`
120
+
121
+ // Names of HTTP header fields to delete.
122
+ Delete []string `json:"delete,omitempty"`
123
+
124
+ // Performs substring replacements of HTTP headers in-situ.
125
Replace map[string][]Replacement `json:"replace,omitempty"`
126
}
127
@@ -135,22 +152,33 @@ func (ops HeaderOps) validate() error {
152
}
153
154
// Replacement describes a string replacement,
138
-// either a simple and fast sugbstring search
155
+// either a simple and fast substring search
156
// or a slower but more powerful regex search.
157
type Replacement struct {
141
- Search string `json:"search,omitempty"`
158
+ // The substring to search for.
159
+ Search string `json:"search,omitempty"`
160
+
161
+ // The regular expression to search with.
162
SearchRegexp string `json:"search_regexp,omitempty"`
143
- Replace string `json:"replace,omitempty"`
163
+
164
+ // The string with which to replace matches.
165
+ Replace string `json:"replace,omitempty"`
166
167
re *regexp.Regexp
168
}
169
148
-// RespHeaderOps is like HeaderOps, but
149
-// optionally deferred until response time.
170
+// RespHeaderOps defines manipulations for response headers.
171
type RespHeaderOps struct {
172
*HeaderOps
152
- Require *caddyhttp.ResponseMatcher `json:"require,omitempty"`
153
- Deferred bool `json:"deferred,omitempty"`
173
+
174
+ // If set, header operations will be deferred until
175
+ // they are written out and only performed if the
176
+ // response matches these criteria.
177
+ Require *caddyhttp.ResponseMatcher `json:"require,omitempty"`
178
+
179
+ // If true, header operations will be deferred until
180
+ // they are written out. Superceded if Require is set.
181
+ Deferred bool `json:"deferred,omitempty"`
182
}
183
184
// ApplyTo applies ops to hdr using repl.
modules/caddyhttp/httpcache/httpcache.go
+26
-4
@@ -33,11 +33,33 @@ func init() {
33
}
34
35
// Cache implements a simple distributed cache.
36
+//
37
+// NOTE: This module is a work-in-progress. It is
38
+// not finished and is NOT ready for production use.
39
+// [We need your help to finish it! Please volunteer
40
+// in this issue.](https://github.com/caddyserver/caddy/issues/2820)
41
+// Until it is finished, this module is subject to
42
+// breaking changes.
43
+//
44
+// Caches only GET and HEAD requests. Honors the Cache-Control: no-cache header.
45
+//
46
+// Still TODO:
47
+//
48
+// - Eviction policies and API
49
+// - Use single cache per-process
50
+// - Preserve cache through config reloads
51
+// - More control over what gets cached
52
type Cache struct {
37
- Self string `json:"self,omitempty"`
38
- Peers []string `json:"peers,omitempty"`
39
- MaxSize int64 `json:"max_size,omitempty"`
40
- group *groupcache.Group
53
+ // The network address of this cache instance; required.
54
+ Self string `json:"self,omitempty"`
55
+
56
+ // A list of network addresses of cache instances in the group.
57
+ Peers []string `json:"peers,omitempty"`
58
+
59
+ // Maximum size of the cache, in bytes. Default is 512 MB.
60
+ MaxSize int64 `json:"max_size,omitempty"`
61
+
62
+ group *groupcache.Group
63
}
64
65
// CaddyModule returns the Caddy module information.
modules/caddyhttp/matchers.go
+2
-2
@@ -695,8 +695,8 @@ func (mre *MatchRegexp) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
695
return nil
696
}
697
698
-// ResponseMatcher is a type which can determine if a given response
699
-// status code and its headers match some criteria.
698
+// ResponseMatcher is a type which can determine if an
699
+// HTTP response matches some criteria.
700
type ResponseMatcher struct {
701
// If set, one of these status codes would be required.
702
// A one-digit status can be used to represent all codes
modules/caddyhttp/requestbody/requestbody.go
+1
@@ -27,6 +27,7 @@ func init() {
27
28
// RequestBody is a middleware for manipulating the request body.
29
type RequestBody struct {
30
+ // The maximum number of bytes to allow reading from the body by a later handler.
31
MaxSize int64 `json:"max_size,omitempty"`
32
}
33
modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
+1
-1
@@ -57,7 +57,7 @@ type Transport struct {
57
// that 404's if the fastcgi path info is not found.
58
SplitPath string `json:"split_path,omitempty"`
59
60
- // Extra environment variables
60
+ // Extra environment variables.
61
EnvVars map[string]string `json:"env,omitempty"`
62
63
// The duration used to set a deadline when connecting to an upstream.
modules/caddyhttp/reverseproxy/healthchecks.go
+57
-15
@@ -31,9 +31,16 @@ import (
31
"go.uber.org/zap"
32
)
33
34
-// HealthChecks holds configuration related to health checking.
34
+// HealthChecks configures active and passive health checks.
35
type HealthChecks struct {
36
- Active *ActiveHealthChecks `json:"active,omitempty"`
36
+ // Active health checks run in the background on a timer. To
37
+ // minimally enable active health checks, set either path or
38
+ // port (or both).
39
+ Active *ActiveHealthChecks `json:"active,omitempty"`
40
+
41
+ // Passive health checks monitor proxied requests for errors or timeouts.
42
+ // To minimally enable passive health checks, specify at least an empty
43
+ // config object.
44
Passive *PassiveHealthChecks `json:"passive,omitempty"`
45
}
46
@@ -41,14 +48,33 @@ type HealthChecks struct {
48
// health checks (that is, health checks which occur in a
49
// background goroutine independently).
50
type ActiveHealthChecks struct {
44
- Path string `json:"path,omitempty"`
45
- Port int `json:"port,omitempty"`
46
- Headers http.Header `json:"headers,omitempty"`
47
- Interval caddy.Duration `json:"interval,omitempty"`
48
- Timeout caddy.Duration `json:"timeout,omitempty"`
49
- MaxSize int64 `json:"max_size,omitempty"`
50
- ExpectStatus int `json:"expect_status,omitempty"`
51
- ExpectBody string `json:"expect_body,omitempty"`
51
+ // The URI path to use for health checks.
52
+ Path string `json:"path,omitempty"`
53
+
54
+ // The port to use (if different from the upstream's dial
55
+ // address) for health checks.
56
+ Port int `json:"port,omitempty"`
57
+
58
+ // HTTP headers to set on health check requests.
59
+ Headers http.Header `json:"headers,omitempty"`
60
+
61
+ // How frequently to perform active health checks (default 30s).
62
+ Interval caddy.Duration `json:"interval,omitempty"`
63
+
64
+ // How long to wait for a response from a backend before
65
+ // considering it unhealthy (default 5s).
66
+ Timeout caddy.Duration `json:"timeout,omitempty"`
67
+
68
+ // The maximum response body to download from the backend
69
+ // during a health check.
70
+ MaxSize int64 `json:"max_size,omitempty"`
71
+
72
+ // The HTTP status code to expect from a healthy backend.
73
+ ExpectStatus int `json:"expect_status,omitempty"`
74
+
75
+ // A regular expression against which to match the response
76
+ // body of a healthy backend.
77
+ ExpectBody string `json:"expect_body,omitempty"`
78
79
stopChan chan struct{}
80
httpClient *http.Client
@@ -60,11 +86,27 @@ type ActiveHealthChecks struct {
86
// health checks (that is, health checks which occur during
87
// the normal flow of request proxying).
88
type PassiveHealthChecks struct {
63
- MaxFails int `json:"max_fails,omitempty"`
64
- FailDuration caddy.Duration `json:"fail_duration,omitempty"`
65
- UnhealthyRequestCount int `json:"unhealthy_request_count,omitempty"`
66
- UnhealthyStatus []int `json:"unhealthy_status,omitempty"`
67
- UnhealthyLatency caddy.Duration `json:"unhealthy_latency,omitempty"`
89
+ // How long to remember a failed request to a backend. A duration > 0
90
+ // enables passive health checking. Default is 0.
91
+ FailDuration caddy.Duration `json:"fail_duration,omitempty"`
92
+
93
+ // The number of failed requests within the FailDuration window to
94
+ // consider a backend as "down". Must be >= 1; default is 1. Requires
95
+ // that FailDuration be > 0.
96
+ MaxFails int `json:"max_fails,omitempty"`
97
+
98
+ // Limits the number of simultaneous requests to a backend by
99
+ // marking the backend as "down" if it has this many concurrent
100
+ // requests or more.
101
+ UnhealthyRequestCount int `json:"unhealthy_request_count,omitempty"`
102
+
103
+ // Count the request as failed if the response comes back with
104
+ // one of these status codes.
105
+ UnhealthyStatus []int `json:"unhealthy_status,omitempty"`
106
+
107
+ // Count the request as failed if the response takes at least this
108
+ // long to receive.
109
+ UnhealthyLatency caddy.Duration `json:"unhealthy_latency,omitempty"`
110
111
logger *zap.Logger
112
}
modules/caddyhttp/reverseproxy/hosts.go
+16
-2
@@ -61,8 +61,22 @@ type UpstreamPool []*Upstream
61
type Upstream struct {
62
Host `json:"-"`
63
64
- Dial string `json:"dial,omitempty"`
65
- MaxRequests int `json:"max_requests,omitempty"`
64
+ // The [network address](/docs/json/apps/http/#servers/listen)
65
+ // to dial to connect to the upstream. Must represent precisely
66
+ // one socket (i.e. no port ranges). A valid network address
67
+ // either has a host and port, or is a unix socket address.
68
+ //
69
+ // Placeholders may be used to make the upstream dynamic, but be
70
+ // aware of the health check implications of this: a single
71
+ // upstream that represents numerous (perhaps arbitrary) backends
72
+ // can be considered down if one or enough of the arbitrary
73
+ // backends is down. Also be aware of open proxy vulnerabilities.
74
+ Dial string `json:"dial,omitempty"`
75
+
76
+ // The maximum number of simultaneous requests to allow to
77
+ // this upstream. If set, overrides the global passive health
78
+ // check UnhealthyRequestCount value.
79
+ MaxRequests int `json:"max_requests,omitempty"`
80
81
// TODO: This could be really useful, to bind requests
82
// with certain properties to specific backends
modules/caddyhttp/reverseproxy/ntlm.go
+4
@@ -46,6 +46,10 @@ func init() {
46
//
47
// This transport also forces HTTP/1.1 and Keep-Alives in order
48
// for NTLM to succeed.
49
+//
50
+// It is basically the same thing as
51
+// [nginx's paid ntlm directive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ntlm)
52
+// (but is free in Caddy!).
53
type NTLMTransport struct {
54
*HTTPTransport
55
modules/caddyhttp/reverseproxy/reverseproxy.go
+74
-13
@@ -41,15 +41,56 @@ func init() {
41
}
42
43
// Handler implements a highly configurable and production-ready reverse proxy.
44
+// Upon proxying, this module sets the following placeholders (which can be used
45
+// both within and after this handler):
46
+//
47
+// {http.reverse_proxy.upstream.address}
48
+// The full address to the upstream as given in the config
49
+// {http.reverse_proxy.upstream.hostport}
50
+// The host:port of the upstream
51
+// {http.reverse_proxy.upstream.host}
52
+// The host of the upstream
53
+// {http.reverse_proxy.upstream.port}
54
+// The port of the upstream
55
+// {http.reverse_proxy.upstream.requests}
56
+// The approximate current number of requests to the upstream
57
+// {http.reverse_proxy.upstream.max_requests}
58
+// The maximum approximate number of requests allowed to the upstream
59
+// {http.reverse_proxy.upstream.fails}
60
+// The number of recent failed requests to the upstream
61
+//
62
type Handler struct {
45
- TransportRaw json.RawMessage `json:"transport,omitempty" caddy:"namespace=http.reverse_proxy.transport inline_key=protocol"`
46
- CBRaw json.RawMessage `json:"circuit_breaker,omitempty" caddy:"namespace=http.reverse_proxy.circuit_breakers inline_key=type"`
47
- LoadBalancing *LoadBalancing `json:"load_balancing,omitempty"`
48
- HealthChecks *HealthChecks `json:"health_checks,omitempty"`
49
- Upstreams UpstreamPool `json:"upstreams,omitempty"`
50
- FlushInterval caddy.Duration `json:"flush_interval,omitempty"`
51
- Headers *headers.Handler `json:"headers,omitempty"`
52
- BufferRequests bool `json:"buffer_requests,omitempty"`
63
+ // Configures the method of transport for the proxy. A transport
64
+ // is what performs the actual "round trip" to the backend.
65
+ // The default transport is plaintext HTTP.
66
+ TransportRaw json.RawMessage `json:"transport,omitempty" caddy:"namespace=http.reverse_proxy.transport inline_key=protocol"`
67
+
68
+ // A circuit breaker may be used to relieve pressure on a backend
69
+ // that is beginning to exhibit symptoms of stress or latency.
70
+ // By default, there is no circuit breaker.
71
+ CBRaw json.RawMessage `json:"circuit_breaker,omitempty" caddy:"namespace=http.reverse_proxy.circuit_breakers inline_key=type"`
72
+
73
+ // Load balancing distributes load/requests between backends.
74
+ LoadBalancing *LoadBalancing `json:"load_balancing,omitempty"`
75
+
76
+ // Health checks update the status of backends, whether they are
77
+ // up or down. Down backends will not be proxied to.
78
+ HealthChecks *HealthChecks `json:"health_checks,omitempty"`
79
+
80
+ // Upstreams is the list of backends to proxy to.
81
+ Upstreams UpstreamPool `json:"upstreams,omitempty"`
82
+
83
+ // TODO: figure out good defaults and write docs for this
84
+ // (see https://github.com/caddyserver/caddy/issues/1460)
85
+ FlushInterval caddy.Duration `json:"flush_interval,omitempty"`
86
+
87
+ // Headers manipulates headers between Caddy and the backend.
88
+ Headers *headers.Handler `json:"headers,omitempty"`
89
+
90
+ // If true, the entire request body will be read and buffered
91
+ // in memory before being proxied to the backend. This should
92
+ // be avoided if at all possible for performance reasons.
93
+ BufferRequests bool `json:"buffer_requests,omitempty"`
94
95
Transport http.RoundTripper `json:"-"`
96
CB CircuitBreaker `json:"-"`
@@ -140,7 +181,7 @@ func (h *Handler) Provision(ctx caddy.Context) error {
181
182
timeout := time.Duration(h.HealthChecks.Active.Timeout)
183
if timeout == 0 {
143
- timeout = 10 * time.Second
184
+ timeout = 5 * time.Second
185
}
186
187
h.HealthChecks.Active.stopChan = make(chan struct{})
@@ -649,10 +690,30 @@ func removeConnectionHeaders(h http.Header) {
690
691
// LoadBalancing has parameters related to load balancing.
692
type LoadBalancing struct {
652
- SelectionPolicyRaw json.RawMessage `json:"selection_policy,omitempty" caddy:"namespace=http.reverse_proxy.selection_policies inline_key=policy"`
653
- TryDuration caddy.Duration `json:"try_duration,omitempty"`
654
- TryInterval caddy.Duration `json:"try_interval,omitempty"`
655
- RetryMatchRaw caddyhttp.RawMatcherSets `json:"retry_match,omitempty" caddy:"namespace=http.matchers"`
693
+ // A selection policy is how to choose an available backend.
694
+ // The default policy is random selection.
695
+ SelectionPolicyRaw json.RawMessage `json:"selection_policy,omitempty" caddy:"namespace=http.reverse_proxy.selection_policies inline_key=policy"`
696
+
697
+ // How long to try selecting available backends for each request
698
+ // if the next available host is down. By default, this retry is
699
+ // disabled. Clients will wait for up to this long while the load
700
+ // balancer tries to find an available upstream host.
701
+ TryDuration caddy.Duration `json:"try_duration,omitempty"`
702
+
703
+ // How long to wait between selecting the next host from the pool. Default
704
+ // is 250ms. Only relevant when a request to an upstream host fails. Be
705
+ // aware that setting this to 0 with a non-zero try_duration can cause the
706
+ // CPU to spin if all backends are down and latency is very low.
707
+ TryInterval caddy.Duration `json:"try_interval,omitempty"`
708
+
709
+ // A list of matcher sets that restricts with which requests retries are
710
+ // allowed. A request must match any of the given matcher sets in order
711
+ // to be retried if the connection to the upstream succeeded but the
712
+ // subsequent round-trip failed. If the connection to the upstream failed,
713
+ // a retry is always allowed. If unspecified, only GET requests will be
714
+ // allowed to be retried. Note that a retry is done with the next available
715
+ // host according to the load balancing policy.
716
+ RetryMatchRaw caddyhttp.RawMatcherSets `json:"retry_match,omitempty" caddy:"namespace=http.matchers"`
717
718
SelectionPolicy Selector `json:"-"`
719
RetryMatch caddyhttp.MatcherSets `json:"-"`
modules/caddyhttp/rewrite/rewrite.go
+28
-5
@@ -31,16 +31,39 @@ func init() {
31
}
32
33
// Rewrite is a middleware which can rewrite HTTP requests.
34
+//
35
+// The Rehandle and HTTPRedirect properties are mutually exclusive
36
+// (you cannot both rehandle and issue a redirect).
37
+//
38
+// These rewrite properties are applied to a request in this order:
39
+// Method, URI, StripPathPrefix, StripPathSuffix, URISubstring.
40
+//
41
+// TODO: This module is still a WIP and may experience breaking changes.
42
type Rewrite struct {
43
+ // Changes the request's HTTP verb.
44
Method string `json:"method,omitempty"`
36
- URI string `json:"uri,omitempty"`
45
38
- StripPathPrefix string `json:"strip_path_prefix,omitempty"`
39
- StripPathSuffix string `json:"strip_path_suffix,omitempty"`
40
- URISubstring []replacer `json:"uri_substring,omitempty"`
46
+ // Changes the request's URI (path, query string, and fragment if present).
47
+ // Only components of the URI that are specified will be changed.
48
+ URI string `json:"uri,omitempty"`
49
+
50
+ // Strips the given prefix from the beginning of the URI path.
51
+ StripPathPrefix string `json:"strip_path_prefix,omitempty"`
52
53
+ // Strips the given suffix from the end of the URI path.
54
+ StripPathSuffix string `json:"strip_path_suffix,omitempty"`
55
+
56
+ // Performs substring replacements on the URI.
57
+ URISubstring []replacer `json:"uri_substring,omitempty"`
58
+
59
+ // If set to a 3xx HTTP status code and if the URI was rewritten (changed),
60
+ // the handler will issue a simple HTTP redirect to the new URI using the
61
+ // given status code.
62
HTTPRedirect caddyhttp.WeakString `json:"http_redirect,omitempty"`
43
- Rehandle bool `json:"rehandle,omitempty"`
63
+
64
+ // If true, the request will sent for rehandling after rewriting
65
+ // only if anything about the request was changed.
66
+ Rehandle bool `json:"rehandle,omitempty"`
67
68
logger *zap.Logger
69
}
modules/caddyhttp/server.go
+20
-2
@@ -97,8 +97,12 @@ type Server struct {
97
// in which they appear in the list.
98
Routes RouteList `json:"routes,omitempty"`
99
100
- // Errors is how this server will handle errors returned from
101
- // any of the handlers in the primary routes.
100
+ // Errors is how this server will handle errors returned from any
101
+ // of the handlers in the primary routes. If the primary handler
102
+ // chain returns an error, the error along with its recommended
103
+ // status code are bubbled back up to the HTTP server which
104
+ // executes a separate error route, specified using this property.
105
+ // The error routes work exactly like the normal routes.
106
Errors *HTTPErrorConfig `json:"errors,omitempty"`
107
108
// How to handle TLS connections.
@@ -418,6 +422,20 @@ func (ahc AutoHTTPSConfig) Skipped(name string, skipSlice []string) bool {
422
// HTTPErrorConfig determines how to handle errors
423
// from the HTTP handlers.
424
type HTTPErrorConfig struct {
425
+ // The routes to evaluate after the primary handler
426
+ // chain returns an error. In an error route, extra
427
+ // placeholders are available:
428
+ //
429
+ // {http.error.status_code}
430
+ // The recommended HTTP status code
431
+ // {http.error.status_text}
432
+ // The status text associated with the recommended status code
433
+ // {http.error.message}
434
+ // The error message
435
+ // {http.error.trace}
436
+ // The origin of the error
437
+ // {http.error.id}
438
+ // A short, human-conveyable ID for the error
439
Routes RouteList `json:"routes,omitempty"`
440
}
441
modules/caddyhttp/starlarkmw/example/caddy.json
+1
-1
@@ -8,7 +8,7 @@
8
{
9
"handle": {
10
"handler": "starlark",
11
- "script": "def setup(r):\n\t# create some middlewares specific to this request\n\ttemplates = loadModule('http.handlers.templates', {'include_root': './includes'})\n\tmidChain = execute([templates])\n\ndef serveHTTP (rw, r):\n\trw.Write('Hello world, from Starlark!')\n"
11
+ "script": "def setup(r):\n\t# create some middlewares specific to this request\n\ttemplates = loadModule('http.handlers.templates', {'file_root': './includes'})\n\tmidChain = execute([templates])\n\ndef serveHTTP (rw, r):\n\trw.Write('Hello world, from Starlark!')\n"
12
}
13
}
14
]
modules/caddyhttp/staticerror.go
+11
-1
@@ -27,8 +27,18 @@ func init() {
27
}
28
29
// StaticError implements a simple handler that returns an error.
30
+// This handler returns an error value, but does not write a response.
31
+// This is useful when you want the server to act as if an error
32
+// occurred; for example, to invoke your custom error handling logic.
33
+//
34
+// Since this handler does not write a response, the error information
35
+// is for use by the server to know how to handle the error.
36
type StaticError struct {
31
- Error string `json:"error,omitempty"`
37
+ // The recommended HTTP status code. Can be either an integer or a
38
+ // string if placeholders are needed. Optional. Default is 500.
39
+ Error string `json:"error,omitempty"`
40
+
41
+ // The error message. Optional. Default is no error message.
42
StatusCode WeakString `json:"status_code,omitempty"`
43
}
44
modules/caddyhttp/staticresp.go
+13
-4
@@ -29,10 +29,19 @@ func init() {
29
30
// StaticResponse implements a simple responder for static responses.
31
type StaticResponse struct {
32
- StatusCode WeakString `json:"status_code,omitempty"`
33
- Headers http.Header `json:"headers,omitempty"`
34
- Body string `json:"body,omitempty"`
35
- Close bool `json:"close,omitempty"`
32
+ // The HTTP status code to respond with. Can be an integer or,
33
+ // if needing to use a placeholder, a string.
34
+ StatusCode WeakString `json:"status_code,omitempty"`
35
+
36
+ // Header fields to set on the response.
37
+ Headers http.Header `json:"headers,omitempty"`
38
+
39
+ // The response body.
40
+ Body string `json:"body,omitempty"`
41
+
42
+ // If true, the server will close the client's connection
43
+ // after writing the response.
44
+ Close bool `json:"close,omitempty"`
45
}
46
47
// CaddyModule returns the Caddy module information.
modules/caddyhttp/subroute.go
+5
-1
@@ -37,7 +37,11 @@ func init() {
37
// is only returned to the entry point at the server if there is an
38
// additional error returned from the errors routes.
39
type Subroute struct {
40
- Routes RouteList `json:"routes,omitempty"`
40
+ // The primary list of routes to compile and execute.
41
+ Routes RouteList `json:"routes,omitempty"`
42
+
43
+ // If the primary routes return an error, error handling
44
+ // can be promoted to this configuration instead.
45
Errors *HTTPErrorConfig `json:"errors,omitempty"`
46
}
47
modules/caddyhttp/templates/caddyfile.go
+1
-1
@@ -47,7 +47,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
47
return nil, h.ArgErr()
48
}
49
case "root":
50
- if !h.Args(&t.IncludeRoot) {
50
+ if !h.Args(&t.FileRoot) {
51
return nil, h.ArgErr()
52
}
53
}
modules/caddyhttp/vars.go
+2
-1
@@ -26,7 +26,8 @@ func init() {
26
}
27
28
// VarsMiddleware is an HTTP middleware which sets variables
29
-// in the context, mainly for use by placeholders.
29
+// in the context, mainly for use by placeholders. The
30
+// placeholders have the form: `{http.vars.variable_name}`
31
type VarsMiddleware map[string]string
32
33
// CaddyModule returns the Caddy module information.
modules/logging/encoders.go
+7
-7
@@ -36,7 +36,7 @@ func init() {
36
37
// ConsoleEncoder encodes log entries that are mostly human-readable.
38
type ConsoleEncoder struct {
39
- zapcore.Encoder
39
+ zapcore.Encoder `json:"-"`
40
LogEncoderConfig
41
}
42
@@ -56,8 +56,8 @@ func (ce *ConsoleEncoder) Provision(_ caddy.Context) error {
56
57
// JSONEncoder encodes entries as JSON.
58
type JSONEncoder struct {
59
- zapcore.Encoder
60
- *LogEncoderConfig
59
+ zapcore.Encoder `json:"-"`
60
+ LogEncoderConfig
61
}
62
63
// CaddyModule returns the Caddy module information.
@@ -77,7 +77,7 @@ func (je *JSONEncoder) Provision(_ caddy.Context) error {
77
// LogfmtEncoder encodes log entries as logfmt:
78
// https://www.brandur.org/logfmt
79
type LogfmtEncoder struct {
80
- zapcore.Encoder
80
+ zapcore.Encoder `json:"-"`
81
LogEncoderConfig
82
}
83
@@ -100,9 +100,9 @@ func (lfe *LogfmtEncoder) Provision(_ caddy.Context) error {
100
// for custom, self-encoded log entries that consist of a
101
// single field in the structured log entry.
102
type StringEncoder struct {
103
- zapcore.Encoder
104
- FieldName string `json:"field,omitempty"`
105
- FallbackRaw json.RawMessage `json:"fallback,omitempty" caddy:"namespace=caddy.logging.encoders inline_key=format"`
103
+ zapcore.Encoder `json:"-"`
104
+ FieldName string `json:"field,omitempty"`
105
+ FallbackRaw json.RawMessage `json:"fallback,omitempty" caddy:"namespace=caddy.logging.encoders inline_key=format"`
106
}
107
108
// CaddyModule returns the Caddy module information.