summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Baron <jackmbaron@gmail.com>2020-12-09 18:28:14 +0000
committerGitHub <noreply@github.com>2020-12-09 11:28:14 -0700
commitc898a37f4080fe3013974bee9a44ce98bd900cc3 (patch)
tree14f9bf7d2259f83040031bda93d548badfd54449
parent31fbcd74016f35c4edf89b5de9c8a519663d588b (diff)
httpcaddyfile: support matching headers that do not exist (#3909)
* add integration test for null header matcher * implement null header matcher syntax * avoid repeating magic ! * check for field following ! character
-rw-r--r--caddytest/integration/caddyfile_adapt/matcher_syntax.txt24
-rw-r--r--modules/caddyhttp/matchers.go29
2 files changed, 48 insertions, 5 deletions
diff --git a/caddytest/integration/caddyfile_adapt/matcher_syntax.txt b/caddytest/integration/caddyfile_adapt/matcher_syntax.txt
index c5c2760..019ce14 100644
--- a/caddytest/integration/caddyfile_adapt/matcher_syntax.txt
+++ b/caddytest/integration/caddyfile_adapt/matcher_syntax.txt
@@ -31,6 +31,12 @@
query bar=baz
}
respond @matcher8 "query matcher merging pairs with the same keys"
+
+ @matcher9 {
+ header !Foo
+ header Bar foo
+ }
+ respond @matcher9 "header matcher with null field matcher"
}
----------
{
@@ -183,6 +189,24 @@
"handler": "static_response"
}
]
+ },
+ {
+ "match": [
+ {
+ "header": {
+ "Bar": [
+ "foo"
+ ],
+ "Foo": null
+ }
+ }
+ ],
+ "handle": [
+ {
+ "body": "header matcher with null field matcher",
+ "handler": "static_response"
+ }
+ ]
}
]
}
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index c5cf21d..4886ba6 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -470,13 +470,32 @@ func (m *MatchHeader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
for d.Next() {
var field, val string
- if !d.Args(&field, &val) {
- return d.Errf("malformed header matcher: expected both field and value")
+ if !d.Args(&field) {
+ return d.Errf("malformed header matcher: expected field")
}
- // If multiple header matchers with the same header field are defined,
- // we want to add the existing to the list of headers (will be OR'ed)
- http.Header(*m).Add(field, val)
+ if strings.HasPrefix(field, "!") {
+ if len(field) == 1 {
+ return d.Errf("malformed header matcher: must have field name following ! character")
+ }
+
+ field = field[1:]
+ headers := *m
+ headers[field] = nil
+ m = &headers
+ if d.NextArg() {
+ return d.Errf("malformed header matcher: null matching headers cannot have a field value")
+ }
+ } else {
+ if !d.NextArg() {
+ return d.Errf("malformed header matcher: expected both field and value")
+ }
+
+ // If multiple header matchers with the same header field are defined,
+ // we want to add the existing to the list of headers (will be OR'ed)
+ val = d.Val()
+ http.Header(*m).Add(field, val)
+ }
if d.NextBlock(0) {
return d.Err("malformed header matcher: blocks are not supported")