From 4c55d26f11329243591d04ca5a52298b38bca9a8 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 11 May 2020 16:38:33 -0400 Subject: caddyhttp: Fix merging of Caddyfile matchers in not blocks (#3379) --- caddytest/integration/caddyfile_adapt_test.go | 54 ++++++++++++++++++++++++++- modules/caddyhttp/matchers.go | 18 +++++++-- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/caddytest/integration/caddyfile_adapt_test.go b/caddytest/integration/caddyfile_adapt_test.go index f6120ae..514a506 100644 --- a/caddytest/integration/caddyfile_adapt_test.go +++ b/caddytest/integration/caddyfile_adapt_test.go @@ -362,4 +362,56 @@ func TestMatcherSyntax(t *testing.T) { } } }`) -} \ No newline at end of file +} + +func TestNotBlockMerging(t *testing.T) { + caddytest.AssertAdapt(t, ` + :80 + + @test { + not { + header Abc "123" + header Bcd "123" + } + } + respond @test 403 + `, "caddyfile", `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":80" + ], + "routes": [ + { + "match": [ + { + "not": [ + { + "header": { + "Abc": [ + "123" + ], + "Bcd": [ + "123" + ] + } + } + ] + } + ], + "handle": [ + { + "handler": "static_response", + "status_code": 403 + } + ] + } + ] + } + } + } + } +}`) +} diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go index 95100d5..0860780 100644 --- a/modules/caddyhttp/matchers.go +++ b/modules/caddyhttp/matchers.go @@ -592,8 +592,17 @@ func (m *MatchNot) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { var mp matcherPair matcherMap := make(map[string]RequestMatcher) - for d.NextArg() || d.NextBlock(0) { + + // 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.NextArg() || 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 d.Errf("getting matcher module '%s': %v", matcherName, err) @@ -602,11 +611,14 @@ func (m *MatchNot) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { if !ok { return d.Errf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName) } - err = unm.UnmarshalCaddyfile(d.NewFromNextSegment()) + err = unm.UnmarshalCaddyfile(caddyfile.NewDispenser(tokens)) if err != nil { return err } - rm := unm.(RequestMatcher) + rm, ok := unm.(RequestMatcher) + if !ok { + return fmt.Errorf("matcher module '%s' is not a request matcher", matcherName) + } matcherMap[matcherName] = rm mp.decoded = append(mp.decoded, rm) } -- cgit v1.2.3