headers: Support wildcards for delete ops (close #4830) (#4831)

This commit is contained in:
Matt Holt 2022-06-15 09:57:43 -06:00 committed by GitHub
parent c82fe91104
commit 0bcd02d5f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 3 deletions

View file

@ -118,10 +118,16 @@ type HeaderOps struct {
// Sets HTTP headers; replaces existing header fields. // Sets HTTP headers; replaces existing header fields.
Set http.Header `json:"set,omitempty"` Set http.Header `json:"set,omitempty"`
// Names of HTTP header fields to delete. // Names of HTTP header fields to delete. Basic wildcards are supported:
//
// - Start with `*` for all field names with the given suffix;
// - End with `*` for all field names with the given prefix;
// - Start and end with `*` for all field names containing a substring.
Delete []string `json:"delete,omitempty"` Delete []string `json:"delete,omitempty"`
// Performs substring replacements of HTTP headers in-situ. // Performs in-situ substring replacements of HTTP headers.
// Keys are the field names on which to perform the associated replacements.
// If the field name is `*`, the replacements are performed on all header fields.
Replace map[string][]Replacement `json:"replace,omitempty"` Replace map[string][]Replacement `json:"replace,omitempty"`
} }
@ -208,7 +214,29 @@ func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) {
// delete // delete
for _, fieldName := range ops.Delete { for _, fieldName := range ops.Delete {
hdr.Del(repl.ReplaceAll(fieldName, "")) fieldName = strings.ToLower(repl.ReplaceAll(fieldName, ""))
switch {
case strings.HasPrefix(fieldName, "*") && strings.HasSuffix(fieldName, "*"):
for existingField := range hdr {
if strings.Contains(strings.ToLower(existingField), fieldName[1:len(fieldName)-1]) {
delete(hdr, existingField)
}
}
case strings.HasPrefix(fieldName, "*"):
for existingField := range hdr {
if strings.HasSuffix(strings.ToLower(existingField), fieldName[1:]) {
delete(hdr, existingField)
}
}
case strings.HasSuffix(fieldName, "*"):
for existingField := range hdr {
if strings.HasPrefix(strings.ToLower(existingField), fieldName[:len(fieldName)-1]) {
delete(hdr, existingField)
}
}
default:
hdr.Del(fieldName)
}
} }
// replace // replace

View file

@ -79,6 +79,26 @@ func TestHandler(t *testing.T) {
"Keep-Me": []string{"i swear i'm innocent"}, "Keep-Me": []string{"i swear i'm innocent"},
}, },
}, },
{
handler: Handler{
Request: &HeaderOps{
Delete: []string{
"*-suffix",
"prefix-*",
"*_*",
},
},
},
reqHeader: http.Header{
"Header-Suffix": []string{"lalala"},
"Prefix-Test": []string{"asdf"},
"Host_Header": []string{"silly django... sigh"}, // see issue #4830
"Keep-Me": []string{"foofoofoo"},
},
expectedReqHeader: http.Header{
"Keep-Me": []string{"foofoofoo"},
},
},
{ {
handler: Handler{ handler: Handler{
Request: &HeaderOps{ Request: &HeaderOps{