From e7c842215e0980f9f81c19d972fe299eda4106c0 Mon Sep 17 00:00:00 2001 From: Garrett Squire Date: Wed, 20 Jul 2016 14:23:55 -0700 Subject: [PATCH] Allow multiple values for an HTTP header and add a test to ensure this works. --- caddyhttp/header/header.go | 4 ++++ caddyhttp/header/header_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/caddyhttp/header/header.go b/caddyhttp/header/header.go index c51199d1..08ba4bd2 100644 --- a/caddyhttp/header/header.go +++ b/caddyhttp/header/header.go @@ -24,8 +24,12 @@ func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) for _, rule := range h.Rules { if httpserver.Path(r.URL.Path).Matches(rule.Path) { for _, header := range rule.Headers { + // One can either delete a header, add multiple values to a header, or simply + // set a header. if strings.HasPrefix(header.Name, "-") { w.Header().Del(strings.TrimLeft(header.Name, "-")) + } else if strings.HasPrefix(header.Name, "+") { + w.Header().Add(strings.TrimLeft(header.Name, "+"), replacer.Replace(header.Value)) } else { w.Header().Set(header.Name, replacer.Replace(header.Value)) } diff --git a/caddyhttp/header/header_test.go b/caddyhttp/header/header_test.go index dd86a09c..787c4d7a 100644 --- a/caddyhttp/header/header_test.go +++ b/caddyhttp/header/header_test.go @@ -4,6 +4,8 @@ import ( "net/http" "net/http/httptest" "os" + "reflect" + "sort" "testing" "github.com/mholt/caddy/caddyhttp/httpserver" @@ -55,3 +57,33 @@ func TestHeader(t *testing.T) { } } } + +func TestMultipleHeaders(t *testing.T) { + he := Headers{ + Next: httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { + return 0, nil + }), + Rules: []Rule{ + {Path: "/a", Headers: []Header{ + {Name: "+Link", Value: "; rel=preload"}, + {Name: "+Link", Value: "; rel=preload"}, + }}, + }, + } + + req, err := http.NewRequest("GET", "/a", nil) + if err != nil { + t.Fatalf("Could not create HTTP request: %v", err) + } + + rec := httptest.NewRecorder() + he.ServeHTTP(rec, req) + + desiredHeaders := []string{"; rel=preload", "; rel=preload"} + actualHeaders := rec.HeaderMap[http.CanonicalHeaderKey("Link")] + sort.Strings(actualHeaders) + + if !reflect.DeepEqual(desiredHeaders, actualHeaders) { + t.Errorf("Expected header to contain: %v but got: %v", desiredHeaders, actualHeaders) + } +}