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
Export types and fields necessary to build configs (for config adapters)
Also flag most fields with 'omitempty' for JSON marshaling
Matthew Holt committed
May 22, 2019 at 12:32 UTC
bc00d840e845d42145954839b88f1e836cd51bfd
11 files changed
+133
-131
caddy.go
+2
-2
@@ -136,10 +136,10 @@ type App interface {
136
137
// Config represents a Caddy configuration.
138
type Config struct {
139
- StorageRaw json.RawMessage `json:"storage"`
139
+ StorageRaw json.RawMessage `json:"storage,omitempty"`
140
storage certmagic.Storage
141
142
- AppsRaw map[string]json.RawMessage `json:"apps"`
142
+ AppsRaw map[string]json.RawMessage `json:"apps,omitempty"`
143
144
// apps stores the decoded Apps values,
145
// keyed by module name.
modules/caddyhttp/caddyhttp.go
+7
-7
@@ -32,10 +32,10 @@ func init() {
32
33
// App is the HTTP app for Caddy.
34
type App struct {
35
- HTTPPort int `json:"http_port"`
36
- HTTPSPort int `json:"https_port"`
37
- GracePeriod caddy2.Duration `json:"grace_period"`
38
- Servers map[string]*Server `json:"servers"`
35
+ HTTPPort int `json:"http_port,omitempty"`
36
+ HTTPSPort int `json:"https_port,omitempty"`
37
+ GracePeriod caddy2.Duration `json:"grace_period,omitempty"`
38
+ Servers map[string]*Server `json:"servers,omitempty"`
39
40
servers []*http.Server
41
@@ -188,7 +188,7 @@ func (app *App) automaticHTTPS() error {
188
domainSet := make(map[string]struct{})
189
for _, route := range srv.Routes {
190
for _, m := range route.matchers {
191
- if hm, ok := m.(*matchHost); ok {
191
+ if hm, ok := m.(*MatchHost); ok {
192
for _, d := range *hm {
193
if !certmagic.HostQualifies(d) {
194
continue
@@ -246,8 +246,8 @@ func (app *App) automaticHTTPS() error {
246
247
redirRoutes = append(redirRoutes, ServerRoute{
248
matchers: []RequestMatcher{
249
- matchProtocol("http"),
250
- matchHost(domains),
249
+ MatchProtocol("http"),
250
+ MatchHost(domains),
251
},
252
responder: Static{
253
StatusCode: http.StatusTemporaryRedirect, // TODO: use permanent redirect instead
modules/caddyhttp/fileserver/browse.go
+1
-1
@@ -15,7 +15,7 @@ import (
15
16
// Browse configures directory browsing.
17
type Browse struct {
18
- TemplateFile string `json:"template_file"`
18
+ TemplateFile string `json:"template_file,omitempty"`
19
20
template *template.Template
21
}
modules/caddyhttp/fileserver/staticfiles.go
+8
-8
@@ -27,14 +27,14 @@ func init() {
27
28
// FileServer implements a static file server responder for Caddy.
29
type FileServer struct {
30
- Root string `json:"root"` // default is current directory
31
- Hide []string `json:"hide"`
32
- IndexNames []string `json:"index_names"`
33
- Files []string `json:"files"` // all relative to the root; default is request URI path
34
- SelectionPolicy string `json:"selection_policy"`
35
- Rehandle bool `json:"rehandle"` // issue a rehandle (internal redirect) if request is rewritten
36
- Fallback caddyhttp.RouteList `json:"fallback"`
37
- Browse *Browse `json:"browse"`
30
+ Root string `json:"root,omitempty"` // default is current directory
31
+ Hide []string `json:"hide,omitempty"`
32
+ IndexNames []string `json:"index_names,omitempty"`
33
+ Files []string `json:"files,omitempty"` // all relative to the root; default is request URI path
34
+ SelectionPolicy string `json:"selection_policy,omitempty"`
35
+ Rehandle bool `json:"rehandle,omitempty"` // issue a rehandle (internal redirect) if request is rewritten
36
+ Fallback caddyhttp.RouteList `json:"fallback,omitempty"`
37
+ Browse *Browse `json:"browse,omitempty"`
38
// TODO: Etag
39
// TODO: Content negotiation
40
}
modules/caddyhttp/headers/headers.go
+8
-8
@@ -17,22 +17,22 @@ func init() {
17
18
// Headers is a middleware which can mutate HTTP headers.
19
type Headers struct {
20
- Request HeaderOps `json:"request"`
21
- Response RespHeaderOps `json:"response"`
20
+ Request *HeaderOps `json:"request,omitempty"`
21
+ Response *RespHeaderOps `json:"response,omitempty"`
22
}
23
24
// HeaderOps defines some operations to
25
// perform on HTTP headers.
26
type HeaderOps struct {
27
- Add http.Header `json:"add"`
28
- Set http.Header `json:"set"`
29
- Delete []string `json:"delete"`
27
+ Add http.Header `json:"add,omitempty"`
28
+ Set http.Header `json:"set,omitempty"`
29
+ Delete []string `json:"delete,omitempty"`
30
}
31
32
// RespHeaderOps is like HeaderOps, but
33
// optionally deferred until response time.
34
type RespHeaderOps struct {
35
- HeaderOps
35
+ *HeaderOps
36
Deferred bool `json:"deferred"`
37
}
38
@@ -51,7 +51,7 @@ func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt
51
return next.ServeHTTP(w, r)
52
}
53
54
-func apply(ops HeaderOps, hdr http.Header, repl caddy2.Replacer) {
54
+func apply(ops *HeaderOps, hdr http.Header, repl caddy2.Replacer) {
55
for fieldName, vals := range ops.Add {
56
fieldName = repl.ReplaceAll(fieldName, "")
57
for _, v := range vals {
@@ -75,7 +75,7 @@ func apply(ops HeaderOps, hdr http.Header, repl caddy2.Replacer) {
75
type responseWriterWrapper struct {
76
*caddyhttp.ResponseWriterWrapper
77
replacer caddy2.Replacer
78
- headerOps HeaderOps
78
+ headerOps *HeaderOps
79
wroteHeader bool
80
}
81
modules/caddyhttp/matchers.go
+39
-39
@@ -17,58 +17,58 @@ import (
17
)
18
19
type (
20
- matchHost []string
21
- matchPath []string
22
- matchPathRE struct{ matchRegexp }
23
- matchMethod []string
24
- matchQuery url.Values
25
- matchHeader http.Header
26
- matchHeaderRE map[string]*matchRegexp
27
- matchProtocol string
28
- matchStarlarkExpr string
29
- matchTable string // TODO: finish implementing
20
+ MatchHost []string
21
+ MatchPath []string
22
+ MatchPathRE struct{ matchRegexp }
23
+ MatchMethod []string
24
+ MatchQuery url.Values
25
+ MatchHeader http.Header
26
+ MatchHeaderRE map[string]*matchRegexp
27
+ MatchProtocol string
28
+ MatchStarlarkExpr string
29
+ MatchTable string // TODO: finish implementing
30
)
31
32
func init() {
33
caddy2.RegisterModule(caddy2.Module{
34
Name: "http.matchers.host",
35
- New: func() interface{} { return matchHost{} },
35
+ New: func() interface{} { return MatchHost{} },
36
})
37
caddy2.RegisterModule(caddy2.Module{
38
Name: "http.matchers.path",
39
- New: func() interface{} { return matchPath{} },
39
+ New: func() interface{} { return MatchPath{} },
40
})
41
caddy2.RegisterModule(caddy2.Module{
42
Name: "http.matchers.path_regexp",
43
- New: func() interface{} { return new(matchPathRE) },
43
+ New: func() interface{} { return new(MatchPathRE) },
44
})
45
caddy2.RegisterModule(caddy2.Module{
46
Name: "http.matchers.method",
47
- New: func() interface{} { return matchMethod{} },
47
+ New: func() interface{} { return MatchMethod{} },
48
})
49
caddy2.RegisterModule(caddy2.Module{
50
Name: "http.matchers.query",
51
- New: func() interface{} { return matchQuery{} },
51
+ New: func() interface{} { return MatchQuery{} },
52
})
53
caddy2.RegisterModule(caddy2.Module{
54
Name: "http.matchers.header",
55
- New: func() interface{} { return matchHeader{} },
55
+ New: func() interface{} { return MatchHeader{} },
56
})
57
caddy2.RegisterModule(caddy2.Module{
58
Name: "http.matchers.header_regexp",
59
- New: func() interface{} { return matchHeaderRE{} },
59
+ New: func() interface{} { return MatchHeaderRE{} },
60
})
61
caddy2.RegisterModule(caddy2.Module{
62
Name: "http.matchers.protocol",
63
- New: func() interface{} { return new(matchProtocol) },
63
+ New: func() interface{} { return new(MatchProtocol) },
64
})
65
caddy2.RegisterModule(caddy2.Module{
66
Name: "http.matchers.starlark_expr",
67
- New: func() interface{} { return new(matchStarlarkExpr) },
67
+ New: func() interface{} { return new(MatchStarlarkExpr) },
68
})
69
}
70
71
-func (m matchHost) Match(r *http.Request) bool {
71
+func (m MatchHost) Match(r *http.Request) bool {
72
outer:
73
for _, host := range m {
74
if strings.Contains(host, "*") {
@@ -93,7 +93,7 @@ outer:
93
return false
94
}
95
96
-func (m matchPath) Match(r *http.Request) bool {
96
+func (m MatchPath) Match(r *http.Request) bool {
97
for _, matchPath := range m {
98
compare := r.URL.Path
99
if strings.HasPrefix(matchPath, "*") {
@@ -111,12 +111,12 @@ func (m matchPath) Match(r *http.Request) bool {
111
return false
112
}
113
114
-func (m matchPathRE) Match(r *http.Request) bool {
114
+func (m MatchPathRE) Match(r *http.Request) bool {
115
repl := r.Context().Value(caddy2.ReplacerCtxKey).(caddy2.Replacer)
116
return m.match(r.URL.Path, repl, "path_regexp")
117
}
118
119
-func (m matchMethod) Match(r *http.Request) bool {
119
+func (m MatchMethod) Match(r *http.Request) bool {
120
for _, method := range m {
121
if r.Method == method {
122
return true
@@ -125,7 +125,7 @@ func (m matchMethod) Match(r *http.Request) bool {
125
return false
126
}
127
128
-func (m matchQuery) Match(r *http.Request) bool {
128
+func (m MatchQuery) Match(r *http.Request) bool {
129
for param, vals := range m {
130
paramVal := r.URL.Query().Get(param)
131
for _, v := range vals {
@@ -137,7 +137,7 @@ func (m matchQuery) Match(r *http.Request) bool {
137
return false
138
}
139
140
-func (m matchHeader) Match(r *http.Request) bool {
140
+func (m MatchHeader) Match(r *http.Request) bool {
141
for field, allowedFieldVals := range m {
142
var match bool
143
actualFieldVals := r.Header[textproto.CanonicalMIMEHeaderKey(field)]
@@ -157,7 +157,7 @@ func (m matchHeader) Match(r *http.Request) bool {
157
return true
158
}
159
160
-func (m matchHeaderRE) Match(r *http.Request) bool {
160
+func (m MatchHeaderRE) Match(r *http.Request) bool {
161
for field, rm := range m {
162
repl := r.Context().Value(caddy2.ReplacerCtxKey).(caddy2.Replacer)
163
match := rm.match(r.Header.Get(field), repl, "header_regexp")
@@ -168,7 +168,7 @@ func (m matchHeaderRE) Match(r *http.Request) bool {
168
return true
169
}
170
171
-func (m matchHeaderRE) Provision() error {
171
+func (m MatchHeaderRE) Provision() error {
172
for _, rm := range m {
173
err := rm.Provision()
174
if err != nil {
@@ -178,7 +178,7 @@ func (m matchHeaderRE) Provision() error {
178
return nil
179
}
180
181
-func (m matchHeaderRE) Validate() error {
181
+func (m MatchHeaderRE) Validate() error {
182
for _, rm := range m {
183
err := rm.Validate()
184
if err != nil {
@@ -188,7 +188,7 @@ func (m matchHeaderRE) Validate() error {
188
return nil
189
}
190
191
-func (m matchProtocol) Match(r *http.Request) bool {
191
+func (m MatchProtocol) Match(r *http.Request) bool {
192
switch string(m) {
193
case "grpc":
194
return r.Header.Get("content-type") == "application/grpc"
@@ -200,7 +200,7 @@ func (m matchProtocol) Match(r *http.Request) bool {
200
return false
201
}
202
203
-func (m matchStarlarkExpr) Match(r *http.Request) bool {
203
+func (m MatchStarlarkExpr) Match(r *http.Request) bool {
204
input := string(m)
205
thread := new(starlark.Thread)
206
env := caddyscript.MatcherEnv(r)
@@ -264,13 +264,13 @@ var wordRE = regexp.MustCompile(`\w+`)
264
265
// Interface guards
266
var (
267
- _ RequestMatcher = (*matchHost)(nil)
268
- _ RequestMatcher = (*matchPath)(nil)
269
- _ RequestMatcher = (*matchPathRE)(nil)
270
- _ RequestMatcher = (*matchMethod)(nil)
271
- _ RequestMatcher = (*matchQuery)(nil)
272
- _ RequestMatcher = (*matchHeader)(nil)
273
- _ RequestMatcher = (*matchHeaderRE)(nil)
274
- _ RequestMatcher = (*matchProtocol)(nil)
275
- _ RequestMatcher = (*matchStarlarkExpr)(nil)
267
+ _ RequestMatcher = (*MatchHost)(nil)
268
+ _ RequestMatcher = (*MatchPath)(nil)
269
+ _ RequestMatcher = (*MatchPathRE)(nil)
270
+ _ RequestMatcher = (*MatchMethod)(nil)
271
+ _ RequestMatcher = (*MatchQuery)(nil)
272
+ _ RequestMatcher = (*MatchHeader)(nil)
273
+ _ RequestMatcher = (*MatchHeaderRE)(nil)
274
+ _ RequestMatcher = (*MatchProtocol)(nil)
275
+ _ RequestMatcher = (*MatchStarlarkExpr)(nil)
276
)
modules/caddyhttp/matchers_test.go
+48
-48
@@ -13,77 +13,77 @@ import (
13
14
func TestHostMatcher(t *testing.T) {
15
for i, tc := range []struct {
16
- match matchHost
16
+ match MatchHost
17
input string
18
expect bool
19
}{
20
{
21
- match: matchHost{},
21
+ match: MatchHost{},
22
input: "example.com",
23
expect: false,
24
},
25
{
26
- match: matchHost{"example.com"},
26
+ match: MatchHost{"example.com"},
27
input: "example.com",
28
expect: true,
29
},
30
{
31
- match: matchHost{"example.com"},
31
+ match: MatchHost{"example.com"},
32
input: "foo.example.com",
33
expect: false,
34
},
35
{
36
- match: matchHost{"example.com"},
36
+ match: MatchHost{"example.com"},
37
input: "EXAMPLE.COM",
38
expect: true,
39
},
40
{
41
- match: matchHost{"foo.example.com"},
41
+ match: MatchHost{"foo.example.com"},
42
input: "foo.example.com",
43
expect: true,
44
},
45
{
46
- match: matchHost{"foo.example.com"},
46
+ match: MatchHost{"foo.example.com"},
47
input: "bar.example.com",
48
expect: false,
49
},
50
{
51
- match: matchHost{"*.example.com"},
51
+ match: MatchHost{"*.example.com"},
52
input: "example.com",
53
expect: false,
54
},
55
{
56
- match: matchHost{"*.example.com"},
56
+ match: MatchHost{"*.example.com"},
57
input: "foo.example.com",
58
expect: true,
59
},
60
{
61
- match: matchHost{"*.example.com"},
61
+ match: MatchHost{"*.example.com"},
62
input: "foo.bar.example.com",
63
expect: false,
64
},
65
{
66
- match: matchHost{"*.example.com", "example.net"},
66
+ match: MatchHost{"*.example.com", "example.net"},
67
input: "example.net",
68
expect: true,
69
},
70
{
71
- match: matchHost{"example.net", "*.example.com"},
71
+ match: MatchHost{"example.net", "*.example.com"},
72
input: "foo.example.com",
73
expect: true,
74
},
75
{
76
- match: matchHost{"*.example.net", "*.*.example.com"},
76
+ match: MatchHost{"*.example.net", "*.*.example.com"},
77
input: "foo.bar.example.com",
78
expect: true,
79
},
80
{
81
- match: matchHost{"*.example.net", "sub.*.example.com"},
81
+ match: MatchHost{"*.example.net", "sub.*.example.com"},
82
input: "sub.foo.example.com",
83
expect: true,
84
},
85
{
86
- match: matchHost{"*.example.net", "sub.*.example.com"},
86
+ match: MatchHost{"*.example.net", "sub.*.example.com"},
87
input: "sub.foo.example.net",
88
expect: false,
89
},
@@ -99,57 +99,57 @@ func TestHostMatcher(t *testing.T) {
99
100
func TestPathMatcher(t *testing.T) {
101
for i, tc := range []struct {
102
- match matchPath
102
+ match MatchPath
103
input string
104
expect bool
105
}{
106
{
107
- match: matchPath{},
107
+ match: MatchPath{},
108
input: "/",
109
expect: false,
110
},
111
{
112
- match: matchPath{"/"},
112
+ match: MatchPath{"/"},
113
input: "/",
114
expect: true,
115
},
116
{
117
- match: matchPath{"/foo/bar"},
117
+ match: MatchPath{"/foo/bar"},
118
input: "/",
119
expect: false,
120
},
121
{
122
- match: matchPath{"/foo/bar"},
122
+ match: MatchPath{"/foo/bar"},
123
input: "/foo/bar",
124
expect: true,
125
},
126
{
127
- match: matchPath{"/foo/bar/"},
127
+ match: MatchPath{"/foo/bar/"},
128
input: "/foo/bar",
129
expect: false,
130
},
131
{
132
- match: matchPath{"/foo/bar/", "/other"},
132
+ match: MatchPath{"/foo/bar/", "/other"},
133
input: "/other/",
134
expect: true,
135
},
136
{
137
- match: matchPath{"*.ext"},
137
+ match: MatchPath{"*.ext"},
138
input: "foo.ext",
139
expect: true,
140
},
141
{
142
- match: matchPath{"*.ext"},
142
+ match: MatchPath{"*.ext"},
143
input: "/foo/bar.ext",
144
expect: true,
145
},
146
{
147
- match: matchPath{"/foo/*/baz"},
147
+ match: MatchPath{"/foo/*/baz"},
148
input: "/foo/bar/baz",
149
expect: true,
150
},
151
{
152
- match: matchPath{"/foo/*/baz/bam"},
152
+ match: MatchPath{"/foo/*/baz/bam"},
153
input: "/foo/bar/bam",
154
expect: false,
155
},
@@ -165,49 +165,49 @@ func TestPathMatcher(t *testing.T) {
165
166
func TestPathREMatcher(t *testing.T) {
167
for i, tc := range []struct {
168
- match matchPathRE
168
+ match MatchPathRE
169
input string
170
expect bool
171
expectRepl map[string]string
172
}{
173
{
174
- match: matchPathRE{},
174
+ match: MatchPathRE{},
175
input: "/",
176
expect: true,
177
},
178
{
179
- match: matchPathRE{matchRegexp{Pattern: "/"}},
179
+ match: MatchPathRE{matchRegexp{Pattern: "/"}},
180
input: "/",
181
expect: true,
182
},
183
{
184
- match: matchPathRE{matchRegexp{Pattern: "/foo"}},
184
+ match: MatchPathRE{matchRegexp{Pattern: "/foo"}},
185
input: "/foo",
186
expect: true,
187
},
188
{
189
- match: matchPathRE{matchRegexp{Pattern: "/foo"}},
189
+ match: MatchPathRE{matchRegexp{Pattern: "/foo"}},
190
input: "/foo/",
191
expect: true,
192
},
193
{
194
- match: matchPathRE{matchRegexp{Pattern: "/bar"}},
194
+ match: MatchPathRE{matchRegexp{Pattern: "/bar"}},
195
input: "/foo/",
196
expect: false,
197
},
198
{
199
- match: matchPathRE{matchRegexp{Pattern: "^/bar"}},
199
+ match: MatchPathRE{matchRegexp{Pattern: "^/bar"}},
200
input: "/foo/bar",
201
expect: false,
202
},
203
{
204
- match: matchPathRE{matchRegexp{Pattern: "^/foo/(.*)/baz$", Name: "name"}},
204
+ match: MatchPathRE{matchRegexp{Pattern: "^/foo/(.*)/baz$", Name: "name"}},
205
input: "/foo/bar/baz",
206
expect: true,
207
expectRepl: map[string]string{"name.1": "bar"},
208
},
209
{
210
- match: matchPathRE{matchRegexp{Pattern: "^/foo/(?P<myparam>.*)/baz$", Name: "name"}},
210
+ match: MatchPathRE{matchRegexp{Pattern: "^/foo/(?P<myparam>.*)/baz$", Name: "name"}},
211
input: "/foo/bar/baz",
212
expect: true,
213
expectRepl: map[string]string{"name.myparam": "bar"},
@@ -253,47 +253,47 @@ func TestPathREMatcher(t *testing.T) {
253
254
func TestHeaderMatcher(t *testing.T) {
255
for i, tc := range []struct {
256
- match matchHeader
256
+ match MatchHeader
257
input http.Header // make sure these are canonical cased (std lib will do that in a real request)
258
expect bool
259
}{
260
{
261
- match: matchHeader{"Field": []string{"foo"}},
261
+ match: MatchHeader{"Field": []string{"foo"}},
262
input: http.Header{"Field": []string{"foo"}},
263
expect: true,
264
},
265
{
266
- match: matchHeader{"Field": []string{"foo", "bar"}},
266
+ match: MatchHeader{"Field": []string{"foo", "bar"}},
267
input: http.Header{"Field": []string{"bar"}},
268
expect: true,
269
},
270
{
271
- match: matchHeader{"Field": []string{"foo", "bar"}},
271
+ match: MatchHeader{"Field": []string{"foo", "bar"}},
272
input: http.Header{"Alakazam": []string{"kapow"}},
273
expect: false,
274
},
275
{
276
- match: matchHeader{"Field": []string{"foo", "bar"}},
276
+ match: MatchHeader{"Field": []string{"foo", "bar"}},
277
input: http.Header{"Field": []string{"kapow"}},
278
expect: false,
279
},
280
{
281
- match: matchHeader{"Field": []string{"foo", "bar"}},
281
+ match: MatchHeader{"Field": []string{"foo", "bar"}},
282
input: http.Header{"Field": []string{"kapow", "foo"}},
283
expect: true,
284
},
285
{
286
- match: matchHeader{"Field1": []string{"foo"}, "Field2": []string{"bar"}},
286
+ match: MatchHeader{"Field1": []string{"foo"}, "Field2": []string{"bar"}},
287
input: http.Header{"Field1": []string{"foo"}, "Field2": []string{"bar"}},
288
expect: true,
289
},
290
{
291
- match: matchHeader{"field1": []string{"foo"}, "field2": []string{"bar"}},
291
+ match: MatchHeader{"field1": []string{"foo"}, "field2": []string{"bar"}},
292
input: http.Header{"Field1": []string{"foo"}, "Field2": []string{"bar"}},
293
expect: true,
294
},
295
{
296
- match: matchHeader{"field1": []string{"foo"}, "field2": []string{"bar"}},
296
+ match: MatchHeader{"field1": []string{"foo"}, "field2": []string{"bar"}},
297
input: http.Header{"Field1": []string{"foo"}, "Field2": []string{"kapow"}},
298
expect: false,
299
},
@@ -309,23 +309,23 @@ func TestHeaderMatcher(t *testing.T) {
309
310
func TestHeaderREMatcher(t *testing.T) {
311
for i, tc := range []struct {
312
- match matchHeaderRE
312
+ match MatchHeaderRE
313
input http.Header // make sure these are canonical cased (std lib will do that in a real request)
314
expect bool
315
expectRepl map[string]string
316
}{
317
{
318
- match: matchHeaderRE{"Field": &matchRegexp{Pattern: "foo"}},
318
+ match: MatchHeaderRE{"Field": &matchRegexp{Pattern: "foo"}},
319
input: http.Header{"Field": []string{"foo"}},
320
expect: true,
321
},
322
{
323
- match: matchHeaderRE{"Field": &matchRegexp{Pattern: "$foo^"}},
323
+ match: MatchHeaderRE{"Field": &matchRegexp{Pattern: "$foo^"}},
324
input: http.Header{"Field": []string{"foobar"}},
325
expect: false,
326
},
327
{
328
- match: matchHeaderRE{"Field": &matchRegexp{Pattern: "^foo(.*)$", Name: "name"}},
328
+ match: MatchHeaderRE{"Field": &matchRegexp{Pattern: "^foo(.*)$", Name: "name"}},
329
input: http.Header{"Field": []string{"foobar"}},
330
expect: true,
331
expectRepl: map[string]string{"name.1": "bar"},
modules/caddyhttp/reverseproxy/upstream.go
+2
@@ -37,6 +37,8 @@ const (
37
// TypeBalanceRandom represents the value to use for configuring a load balanced reverse proxy to use random load balancing.
38
TypeBalanceRandom
39
40
+ // TODO: add random with two choices
41
+
42
// msgNoHealthyUpstreams is returned if there are no upstreams that are healthy to proxy a request to
43
msgNoHealthyUpstreams = "No healthy upstreams."
44
modules/caddyhttp/rewrite/rewrite.go
+3
-3
@@ -18,9 +18,9 @@ func init() {
18
19
// Rewrite is a middleware which can rewrite HTTP requests.
20
type Rewrite struct {
21
- Method string `json:"method"`
22
- URI string `json:"uri"`
23
- Rehandle bool `json:"rehandle"`
21
+ Method string `json:"method,omitempty"`
22
+ URI string `json:"uri,omitempty"`
23
+ Rehandle bool `json:"rehandle,omitempty"`
24
}
25
26
func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
modules/caddyhttp/routes.go
+5
-5
@@ -12,12 +12,12 @@ import (
12
// middlewares, and a responder for handling HTTP
13
// requests.
14
type ServerRoute struct {
15
- Group string `json:"group"`
16
- Matchers map[string]json.RawMessage `json:"match"`
17
- Apply []json.RawMessage `json:"apply"`
18
- Respond json.RawMessage `json:"respond"`
15
+ Group string `json:"group,omitempty"`
16
+ Matchers map[string]json.RawMessage `json:"match,omitempty"`
17
+ Apply []json.RawMessage `json:"apply,omitempty"`
18
+ Respond json.RawMessage `json:"respond,omitempty"`
19
20
- Terminal bool `json:"terminal"`
20
+ Terminal bool `json:"terminal,omitempty"`
21
22
// decoded values
23
matchers []RequestMatcher
modules/caddyhttp/server.go
+10
-10
@@ -13,15 +13,15 @@ import (
13
14
// Server is an HTTP server.
15
type Server struct {
16
- Listen []string `json:"listen"`
17
- ReadTimeout caddy2.Duration `json:"read_timeout"`
18
- ReadHeaderTimeout caddy2.Duration `json:"read_header_timeout"`
19
- Routes RouteList `json:"routes"`
20
- Errors httpErrorConfig `json:"errors"`
21
- TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies"`
22
- DisableAutoHTTPS bool `json:"disable_auto_https"`
23
- DisableAutoHTTPSRedir bool `json:"disable_auto_https_redir"`
24
- MaxRehandles int `json:"max_rehandles"`
16
+ Listen []string `json:"listen,omitempty"`
17
+ ReadTimeout caddy2.Duration `json:"read_timeout,omitempty"`
18
+ ReadHeaderTimeout caddy2.Duration `json:"read_header_timeout,omitempty"`
19
+ Routes RouteList `json:"routes,omitempty"`
20
+ Errors *httpErrorConfig `json:"errors,omitempty"`
21
+ TLSConnPolicies caddytls.ConnectionPolicies `json:"tls_connection_policies,omitempty"`
22
+ DisableAutoHTTPS bool `json:"disable_auto_https,omitempty"`
23
+ DisableAutoHTTPSRedir bool `json:"disable_auto_https_redir,omitempty"`
24
+ MaxRehandles int `json:"max_rehandles,omitempty"`
25
26
tlsApp *caddytls.TLS
27
}
@@ -99,7 +99,7 @@ func (s *Server) executeCompositeRoute(w http.ResponseWriter, r *http.Request, s
99
}
100
101
type httpErrorConfig struct {
102
- Routes RouteList `json:"routes"`
102
+ Routes RouteList `json:"routes,omitempty"`
103
// TODO: some way to configure the logging of errors, probably? standardize
104
// the logging configuration first.
105
}