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
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
Jack Baron committed
Dec 9, 2020 at 18:28 UTC
c898a37f4080fe3013974bee9a44ce98bd900cc3
2 files changed
+48
-5
caddytest/integration/caddyfile_adapt/matcher_syntax.txt
+24
@@ -31,6 +31,12 @@
31
query bar=baz
32
}
33
respond @matcher8 "query matcher merging pairs with the same keys"
34
+
35
+ @matcher9 {
36
+ header !Foo
37
+ header Bar foo
38
+ }
39
+ respond @matcher9 "header matcher with null field matcher"
40
}
41
----------
42
{
@@ -183,6 +189,24 @@
189
"handler": "static_response"
190
}
191
]
192
+ },
193
+ {
194
+ "match": [
195
+ {
196
+ "header": {
197
+ "Bar": [
198
+ "foo"
199
+ ],
200
+ "Foo": null
201
+ }
202
+ }
203
+ ],
204
+ "handle": [
205
+ {
206
+ "body": "header matcher with null field matcher",
207
+ "handler": "static_response"
208
+ }
209
+ ]
210
}
211
]
212
}
modules/caddyhttp/matchers.go
+24
-5
@@ -470,13 +470,32 @@ func (m *MatchHeader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
470
}
471
for d.Next() {
472
var field, val string
473
- if !d.Args(&field, &val) {
474
- return d.Errf("malformed header matcher: expected both field and value")
473
+ if !d.Args(&field) {
474
+ return d.Errf("malformed header matcher: expected field")
475
}
476
477
- // If multiple header matchers with the same header field are defined,
478
- // we want to add the existing to the list of headers (will be OR'ed)
479
- http.Header(*m).Add(field, val)
477
+ if strings.HasPrefix(field, "!") {
478
+ if len(field) == 1 {
479
+ return d.Errf("malformed header matcher: must have field name following ! character")
480
+ }
481
+
482
+ field = field[1:]
483
+ headers := *m
484
+ headers[field] = nil
485
+ m = &headers
486
+ if d.NextArg() {
487
+ return d.Errf("malformed header matcher: null matching headers cannot have a field value")
488
+ }
489
+ } else {
490
+ if !d.NextArg() {
491
+ return d.Errf("malformed header matcher: expected both field and value")
492
+ }
493
+
494
+ // If multiple header matchers with the same header field are defined,
495
+ // we want to add the existing to the list of headers (will be OR'ed)
496
+ val = d.Val()
497
+ http.Header(*m).Add(field, val)
498
+ }
499
500
if d.NextBlock(0) {
501
return d.Err("malformed header matcher: blocks are not supported")