@marcel91200 / caddy Mirror · read-only / commits / 95ed603d
Fork 0

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.