From 15bf9c196c5972051f40ebadf50811bd06e328dd Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Fri, 14 Feb 2020 11:00:16 -0700 Subject: caddyfile: Refactor; NewFromNextSegment(); fix repeated matchers Now multiple instances of the same matcher can be used within a named matcher without overwriting previous ones. --- caddyconfig/httpcaddyfile/builtins.go | 4 +-- caddyconfig/httpcaddyfile/httptype.go | 10 +++++- caddyconfig/httpcaddyfile/httptype_test.go | 50 +++++++++++++++++++++++++++++- caddyconfig/httpcaddyfile/options.go | 2 +- 4 files changed, 61 insertions(+), 5 deletions(-) (limited to 'caddyconfig/httpcaddyfile') diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go index bac12da..b758c39 100644 --- a/caddyconfig/httpcaddyfile/builtins.go +++ b/caddyconfig/httpcaddyfile/builtins.go @@ -368,7 +368,7 @@ func parseRoute(h Helper) (caddyhttp.MiddlewareHandler, error) { } subHelper := h - subHelper.Dispenser = h.NewFromNextTokens() + subHelper.Dispenser = h.NewFromNextSegment() results, err := dirFunc(subHelper) if err != nil { @@ -401,7 +401,7 @@ func parseHandle(h Helper) (caddyhttp.MiddlewareHandler, error) { } subHelper := h - subHelper.Dispenser = h.NewFromNextTokens() + subHelper.Dispenser = h.NewFromNextSegment() results, err := dirFunc(subHelper) if err != nil { diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index 5745b66..e54456e 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -751,8 +751,16 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M } matchers[definitionName] = make(caddy.ModuleMap) + // in case there are multiple instances of the same matcher, concatenate + // their tokens (we expect that UnmarshalCaddyfile should be able to + // handle more than one segment); otherwise, we'd overwrite other + // instances of the matcher in this set + tokensByMatcherName := make(map[string][]caddyfile.Token) for nesting := d.Nesting(); d.NextBlock(nesting); { matcherName := d.Val() + tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...) + } + for matcherName, tokens := range tokensByMatcherName { mod, err := caddy.GetModule("http.matchers." + matcherName) if err != nil { return fmt.Errorf("getting matcher module '%s': %v", matcherName, err) @@ -761,7 +769,7 @@ func parseMatcherDefinitions(d *caddyfile.Dispenser, matchers map[string]caddy.M if !ok { return fmt.Errorf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName) } - err = unm.UnmarshalCaddyfile(d.NewFromNextTokens()) + err = unm.UnmarshalCaddyfile(caddyfile.NewDispenser(tokens)) if err != nil { return err } diff --git a/caddyconfig/httpcaddyfile/httptype_test.go b/caddyconfig/httpcaddyfile/httptype_test.go index ae4f042..3b69677 100644 --- a/caddyconfig/httpcaddyfile/httptype_test.go +++ b/caddyconfig/httpcaddyfile/httptype_test.go @@ -1,6 +1,54 @@ package httpcaddyfile -import "testing" +import ( + "testing" + + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" +) + +func TestServerType(t *testing.T) { + for i, tc := range []struct { + input string + expectWarn bool + expectError bool + }{ + { + input: `http://localhost + @debug { + query showdebug=1 + } + `, + expectWarn: false, + expectError: false, + }, + { + input: `http://localhost + @debug { + query bad format + } + `, + expectWarn: false, + expectError: true, + }, + } { + + adapter := caddyfile.Adapter{ + ServerType: ServerType{}, + } + + _, warnings, err := adapter.Adapt([]byte(tc.input), nil) + + if len(warnings) > 0 != tc.expectWarn { + t.Errorf("Test %d warning expectation failed Expected: %v, got %v", i, tc.expectWarn, warnings) + continue + } + + if err != nil != tc.expectError { + t.Errorf("Test %d error expectation failed Expected: %v, got %s", i, tc.expectError, err) + continue + } + } +} func TestSpecificity(t *testing.T) { for i, tc := range []struct { diff --git a/caddyconfig/httpcaddyfile/options.go b/caddyconfig/httpcaddyfile/options.go index 9ebefea..fdecfa4 100644 --- a/caddyconfig/httpcaddyfile/options.go +++ b/caddyconfig/httpcaddyfile/options.go @@ -151,7 +151,7 @@ func parseOptStorage(d *caddyfile.Dispenser) (caddy.StorageConverter, error) { if !ok { return nil, fmt.Errorf("storage module '%s' is not a Caddyfile unmarshaler", mod.ID) } - err = unm.UnmarshalCaddyfile(d.NewFromNextTokens()) + err = unm.UnmarshalCaddyfile(d.NewFromNextSegment()) if err != nil { return nil, err } -- cgit v1.2.3