@marcel91200 / caddy Mirror · read-only / commits / 4c55d26f
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

caddyhttp: Fix merging of Caddyfile matchers in not blocks (#3379)

Francis Lavoie committed May 11, 2020 at 16:38 UTC 4c55d26f11329243591d04ca5a52298b38bca9a8
2 files changed +68 -4
caddytest/integration/caddyfile_adapt_test.go
+53 -1
@@ -362,4 +362,56 @@ func TestMatcherSyntax(t *testing.T) {
362 }
363 }
364 }`)
365 -}
\ No newline at end of file
365 +}
366 +
367 +func TestNotBlockMerging(t *testing.T) {
368 + caddytest.AssertAdapt(t, `
369 + :80
370 +
371 + @test {
372 + not {
373 + header Abc "123"
374 + header Bcd "123"
375 + }
376 + }
377 + respond @test 403
378 + `, "caddyfile", `{
379 + "apps": {
380 + "http": {
381 + "servers": {
382 + "srv0": {
383 + "listen": [
384 + ":80"
385 + ],
386 + "routes": [
387 + {
388 + "match": [
389 + {
390 + "not": [
391 + {
392 + "header": {
393 + "Abc": [
394 + "123"
395 + ],
396 + "Bcd": [
397 + "123"
398 + ]
399 + }
400 + }
401 + ]
402 + }
403 + ],
404 + "handle": [
405 + {
406 + "handler": "static_response",
407 + "status_code": 403
408 + }
409 + ]
410 + }
411 + ]
412 + }
413 + }
414 + }
415 + }
416 +}`)
417 +}
modules/caddyhttp/matchers.go
+15 -3
@@ -592,8 +592,17 @@ func (m *MatchNot) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
592 for d.Next() {
593 var mp matcherPair
594 matcherMap := make(map[string]RequestMatcher)
595 - for d.NextArg() || d.NextBlock(0) {
595 +
596 + // in case there are multiple instances of the same matcher, concatenate
597 + // their tokens (we expect that UnmarshalCaddyfile should be able to
598 + // handle more than one segment); otherwise, we'd overwrite other
599 + // instances of the matcher in this set
600 + tokensByMatcherName := make(map[string][]caddyfile.Token)
601 + for nesting := d.Nesting(); d.NextArg() || d.NextBlock(nesting); {
602 matcherName := d.Val()
603 + tokensByMatcherName[matcherName] = append(tokensByMatcherName[matcherName], d.NextSegment()...)
604 + }
605 + for matcherName, tokens := range tokensByMatcherName {
606 mod, err := caddy.GetModule("http.matchers." + matcherName)
607 if err != nil {
608 return d.Errf("getting matcher module '%s': %v", matcherName, err)
@@ -602,11 +611,14 @@ func (m *MatchNot) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
611 if !ok {
612 return d.Errf("matcher module '%s' is not a Caddyfile unmarshaler", matcherName)
613 }
605 - err = unm.UnmarshalCaddyfile(d.NewFromNextSegment())
614 + err = unm.UnmarshalCaddyfile(caddyfile.NewDispenser(tokens))
615 if err != nil {
616 return err
617 }
609 - rm := unm.(RequestMatcher)
618 + rm, ok := unm.(RequestMatcher)
619 + if !ok {
620 + return fmt.Errorf("matcher module '%s' is not a request matcher", matcherName)
621 + }
622 matcherMap[matcherName] = rm
623 mp.decoded = append(mp.decoded, rm)
624 }