diff options
author | Matt Holt <mholt@users.noreply.github.com> | 2022-06-15 09:57:43 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-15 09:57:43 -0600 |
commit | 0bcd02d5f669869b0c79c00ea3c5a3f6a7072b20 (patch) | |
tree | 066b0f5accb2f7ab0a1097d42e23f0e2e6b81545 | |
parent | c82fe91104efbbe62826510579ea57fd54c55f8c (diff) |
headers: Support wildcards for delete ops (close #4830) (#4831)
-rw-r--r-- | modules/caddyhttp/headers/headers.go | 34 | ||||
-rw-r--r-- | modules/caddyhttp/headers/headers_test.go | 20 |
2 files changed, 51 insertions, 3 deletions
diff --git a/modules/caddyhttp/headers/headers.go b/modules/caddyhttp/headers/headers.go index 4cef0a9..f67df92 100644 --- a/modules/caddyhttp/headers/headers.go +++ b/modules/caddyhttp/headers/headers.go @@ -118,10 +118,16 @@ type HeaderOps struct { // Sets HTTP headers; replaces existing header fields. 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"` - // 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"` } @@ -208,7 +214,29 @@ func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) { // 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 diff --git a/modules/caddyhttp/headers/headers_test.go b/modules/caddyhttp/headers/headers_test.go index fb68225..d74e6fc 100644 --- a/modules/caddyhttp/headers/headers_test.go +++ b/modules/caddyhttp/headers/headers_test.go @@ -82,6 +82,26 @@ func TestHandler(t *testing.T) { { 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{ + Request: &HeaderOps{ Replace: map[string][]Replacement{ "Best-Server": { Replacement{ |