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
caddyfile: Refactor; NewFromNextSegment(); fix repeated matchers
Now multiple instances of the same matcher can be used within a named matcher without overwriting previous ones.
Matthew Holt committed
Feb 14, 2020 at 11:00 UTC
15bf9c196c5972051f40ebadf50811bd06e328dd
8 files changed
+76
-13
caddyconfig/caddyfile/dispenser.go
+11
-4
@@ -249,13 +249,20 @@ func (d *Dispenser) RemainingArgs() []string {
249
return args
250
}
251
252
-// NewFromNextTokens returns a new dispenser with a copy of
252
+// NewFromNextSegment returns a new dispenser with a copy of
253
// the tokens from the current token until the end of the
254
// "directive" whether that be to the end of the line or
255
// the end of a block that starts at the end of the line;
256
// in other words, until the end of the segment.
257
-func (d *Dispenser) NewFromNextTokens() *Dispenser {
258
- tkns := []Token{d.Token()}
257
+func (d *Dispenser) NewFromNextSegment() *Dispenser {
258
+ return NewDispenser(d.NextSegment())
259
+}
260
+
261
+// NextSegment returns a copy of the tokens from the current
262
+// token until the end of the line or block that starts at
263
+// the end of the line.
264
+func (d *Dispenser) NextSegment() Segment {
265
+ tkns := Segment{d.Token()}
266
for d.NextArg() {
267
tkns = append(tkns, d.Token())
268
}
@@ -282,7 +289,7 @@ func (d *Dispenser) NewFromNextTokens() *Dispenser {
289
// next iteration of the enclosing loop will
290
// call Next() and consume it
291
}
285
- return NewDispenser(tkns)
292
+ return tkns
293
}
294
295
// Token returns the current token.
caddyconfig/httpcaddyfile/builtins.go
+2
-2
@@ -368,7 +368,7 @@ func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) {
368
}
369
370
subHelper := h
371
- subHelper.Dispenser = h.NewFromNextTokens()
371
+ subHelper.Dispenser = h.NewFromNextSegment()
372
373
results, err := dirFunc(subHelper)
374
if err != nil {
@@ -401,7 +401,7 @@ func parseHandle(h Helper) (caddyhttp.MiddlewareHandler, error) {
401
}
402
403
subHelper := h
404
- subHelper.Dispenser = h.NewFromNextTokens()
404
+ subHelper.Dispenser = h.NewFromNextSegment()
405
406
results, err := dirFunc(subHelper)
407
if err != nil {
caddyconfig/httpcaddyfile/httptype.go
+9
-1
@@ -751,8 +751,16 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
751
}
752
matchers[definitionName] = make(caddy.ModuleMap)
753
754
+ // in case there are multiple instances of the same matcher, concatenate
755
+ // their tokens (we expect that UnmarshalCaddyfile should be able to
756
+ // handle more than one segment); otherwise, we'd overwrite other
757
+ // instances of the matcher in this set
758
+ tokensByMatcherName := make(map[string][]caddyfile.Token)
759
for nesting := d.Nesting(); d.NextBlock(nesting); {
760
matcherName := d.Val()
761
+ tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...)
762
+ }
763
+ for matcherName, tokens := range tokensByMatcherName {
764
mod, err := caddy.GetModule("http.matchers." + matcherName)
765
if err != nil {
766
return fmt.Errorf("getting matcher module '%s': %v", matcherName, err)
@@ -761,7 +769,7 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M
769
if !ok {
770
return fmt.Errorf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
771
}
764
- err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
772
+ err = unm.UnmarshalCaddyfile(caddyfile.NewDispenser(tokens))
773
if err != nil {
774
return err
775
}
caddyconfig/httpcaddyfile/httptype_test.go
+49
-1
@@ -1,6 +1,54 @@
1
package httpcaddyfile
2
3
-import "testing"
3
+import (
4
+ "testing"
5
+
6
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
7
+)
8
+
9
+func TestServerType(t *testing.T) {
10
+ for i, tc := range []struct {
11
+ input string
12
+ expectWarn bool
13
+ expectError bool
14
+ }{
15
+ {
16
+ input: `http://localhost
17
+ @debug {
18
+ query showdebug=1
19
+ }
20
+ `,
21
+ expectWarn: false,
22
+ expectError: false,
23
+ },
24
+ {
25
+ input: `http://localhost
26
+ @debug {
27
+ query bad format
28
+ }
29
+ `,
30
+ expectWarn: false,
31
+ expectError: true,
32
+ },
33
+ } {
34
+
35
+ adapter := caddyfile.Adapter{
36
+ ServerType: ServerType{},
37
+ }
38
+
39
+ _, warnings, err := adapter.Adapt([]byte(tc.input), nil)
40
+
41
+ if len(warnings) > 0 != tc.expectWarn {
42
+ t.Errorf("Test %d warning expectation failed Expected: %v, got %v", i, tc.expectWarn, warnings)
43
+ continue
44
+ }
45
+
46
+ if err != nil != tc.expectError {
47
+ t.Errorf("Test %d error expectation failed Expected: %v, got %s", i, tc.expectError, err)
48
+ continue
49
+ }
50
+ }
51
+}
52
53
func TestSpecificity(t *testing.T) {
54
for i, tc := range []struct {
caddyconfig/httpcaddyfile/options.go
+1
-1
@@ -151,7 +151,7 @@ func parseOptStorage(d *caddyfile.Dispenser) (caddy.StorageConverter, error) {
151
if !ok {
152
return nil, fmt.Errorf("storage module '%s' is not a Caddyfile unmarshaler", mod.ID)
153
}
154
- err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
154
+ err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
155
if err != nil {
156
return nil, err
157
}
modules/caddyhttp/encode/caddyfile.go
+1
-1
@@ -73,7 +73,7 @@ func (enc *Encode) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
73
if !ok {
74
return fmt.Errorf("encoder module '%s' is not a Caddyfile unmarshaler", mod)
75
}
76
- err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
76
+ err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
77
if err != nil {
78
return err
79
}
modules/caddyhttp/matchers.go
+1
-1
@@ -520,7 +520,7 @@ func (m *MatchNegate) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
520
if !ok {
521
return d.Errf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
522
}
523
- err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
523
+ err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
524
if err != nil {
525
return err
526
}
modules/caddyhttp/reverseproxy/caddyfile.go
+2
-2
@@ -114,7 +114,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
114
if !ok {
115
return d.Errf("load balancing policy module '%s' is not a Caddyfile unmarshaler", mod)
116
}
117
- err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
117
+ err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
118
if err != nil {
119
return err
120
}
@@ -401,7 +401,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
401
if !ok {
402
return d.Errf("transport module '%s' is not a Caddyfile unmarshaler", mod)
403
}
404
- err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())
404
+ err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
405
if err != nil {
406
return err
407
}