header: match subdirective for response matching (#6765)

This commit is contained in:
Arsh 2025-01-08 11:18:06 +05:30 committed by GitHub
parent 1f927d6b07
commit e48b75843b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 0 deletions

View file

@ -12,10 +12,14 @@
@images path /images/* @images path /images/*
header @images { header @images {
Cache-Control "public, max-age=3600, stale-while-revalidate=86400" Cache-Control "public, max-age=3600, stale-while-revalidate=86400"
match {
status 200
}
} }
header { header {
+Link "Foo" +Link "Foo"
+Link "Bar" +Link "Bar"
match status 200
} }
header >Set Defer header >Set Defer
header >Replace Deferred Replacement header >Replace Deferred Replacement
@ -42,6 +46,11 @@
{ {
"handler": "headers", "handler": "headers",
"response": { "response": {
"require": {
"status_code": [
200
]
},
"set": { "set": {
"Cache-Control": [ "Cache-Control": [
"public, max-age=3600, stale-while-revalidate=86400" "public, max-age=3600, stale-while-revalidate=86400"
@ -136,6 +145,11 @@
"Foo", "Foo",
"Bar" "Bar"
] ]
},
"require": {
"status_code": [
200
]
} }
} }
}, },

View file

@ -99,6 +99,16 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
handler.Response.Deferred = true handler.Response.Deferred = true
continue continue
} }
if field == "match" {
responseMatchers := make(map[string]caddyhttp.ResponseMatcher)
err := caddyhttp.ParseNamedResponseMatcher(h.NewFromNextSegment(), responseMatchers)
if err != nil {
return nil, err
}
matcher := responseMatchers["match"]
handler.Response.Require = &matcher
continue
}
if hasArgs { if hasArgs {
return nil, h.Err("cannot specify headers in both arguments and block") // because it would be weird return nil, h.Err("cannot specify headers in both arguments and block") // because it would be weird
} }

View file

@ -143,6 +143,28 @@ func TestHandler(t *testing.T) {
"Cache-Control": []string{"no-cache"}, "Cache-Control": []string{"no-cache"},
}, },
}, },
{ // same as above, but checks that response headers are left alone when "Require" conditions are unmet
handler: Handler{
Response: &RespHeaderOps{
Require: &caddyhttp.ResponseMatcher{
Headers: http.Header{
"Cache-Control": nil,
},
},
HeaderOps: &HeaderOps{
Add: http.Header{
"Cache-Control": []string{"no-cache"},
},
},
},
},
respHeader: http.Header{
"Cache-Control": []string{"something"},
},
expectedRespHeader: http.Header{
"Cache-Control": []string{"something"},
},
},
{ {
handler: Handler{ handler: Handler{
Response: &RespHeaderOps{ Response: &RespHeaderOps{