From b5fff09b543d2caeff10fe0c8a5a4ee10d3c9db9 Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sat, 9 May 2015 21:45:28 +0200 Subject: [PATCH 1/5] headers: Changed Rule.Url to Rule.Path Updated ServeHTTP comment to indicate that it is setting headers and not adding them to existing values. --- middleware/headers/headers.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/middleware/headers/headers.go b/middleware/headers/headers.go index 7e3d6dbb..e71e9fe3 100644 --- a/middleware/headers/headers.go +++ b/middleware/headers/headers.go @@ -18,10 +18,10 @@ type Headers struct { } // ServeHTTP implements the middleware.Handler interface and serves requests, -// adding headers to the response according to the configured rules. +// setting headers on the response according to the configured rules. func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { for _, rule := range h.Rules { - if middleware.Path(r.URL.Path).Matches(rule.Url) { + if middleware.Path(r.URL.Path).Matches(rule.Path) { for _, header := range rule.Headers { if strings.HasPrefix(header.Name, "-") { w.Header().Del(strings.TrimLeft(header.Name, "-")) @@ -38,7 +38,7 @@ type ( // Rule groups a slice of HTTP headers by a URL pattern. // TODO: use http.Header type instead? Rule struct { - Url string + Path string Headers []Header } From d9dc9326f2b21831155c103e0c9b8aef73b2ba50 Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sat, 9 May 2015 21:47:02 +0200 Subject: [PATCH 2/5] headers: Initial test for Headers --- middleware/headers/headers_test.go | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 middleware/headers/headers_test.go diff --git a/middleware/headers/headers_test.go b/middleware/headers/headers_test.go new file mode 100644 index 00000000..e6285897 --- /dev/null +++ b/middleware/headers/headers_test.go @@ -0,0 +1,50 @@ +package headers + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/mholt/caddy/middleware" +) + +func TestHeaders(t *testing.T) { + for i, test := range []struct { + from string + name string + value string + }{ + {"/a", "Foo", "Bar"}, + {"/a", "Bar", ""}, + {"/a", "Baz", ""}, + {"/b", "Foo", ""}, + {"/b", "Bar", "Removed in /a"}, + } { + he := Headers{ + Next: middleware.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { + return 0, nil + }), + Rules: []Rule{ + {Path: "/a", Headers: []Header{ + {Name: "Foo", Value: "Bar"}, + {Name: "-Bar"}, + }}, + }, + } + + req, err := http.NewRequest("GET", test.from, nil) + if err != nil { + t.Fatalf("Test %d: Could not create HTTP request: %v", i, err) + } + + rec := httptest.NewRecorder() + rec.Header().Set("Bar", "Removed in /a") + + he.ServeHTTP(rec, req) + + if got := rec.Header().Get(test.name); got != test.value { + t.Errorf("Test %d: Expected %s header to be %q but was %q", + i, test.name, test.value, got) + } + } +} From df6efe5d889748e7719240ba8ed1c59b910e11dd Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sat, 9 May 2015 21:57:55 +0200 Subject: [PATCH 3/5] headers: Replaced usage of Url to Path in setup --- config/setup/headers.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/setup/headers.go b/config/setup/headers.go index 3300f072..553f20b1 100644 --- a/config/setup/headers.go +++ b/config/setup/headers.go @@ -29,17 +29,17 @@ func headersParse(c *Controller) ([]headers.Rule, error) { } pattern := c.Val() - // See if we already have a definition for this URL pattern... + // See if we already have a definition for this Path pattern... for _, h := range rules { - if h.Url == pattern { + if h.Path == pattern { head = h break } } // ...otherwise, this is a new pattern - if head.Url == "" { - head.Url = pattern + if head.Path == "" { + head.Path = pattern isNewPattern = true } @@ -72,7 +72,7 @@ func headersParse(c *Controller) ([]headers.Rule, error) { rules = append(rules, head) } else { for i := 0; i < len(rules); i++ { - if rules[i].Url == pattern { + if rules[i].Path == pattern { rules[i] = head break } From 0d5a8a738315da6b2b579c052d920a4243302228 Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sat, 9 May 2015 23:10:08 +0200 Subject: [PATCH 4/5] headers: Test for Headers and headersParse funcs --- config/setup/headers_test.go | 85 ++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 config/setup/headers_test.go diff --git a/config/setup/headers_test.go b/config/setup/headers_test.go new file mode 100644 index 00000000..5abc56b7 --- /dev/null +++ b/config/setup/headers_test.go @@ -0,0 +1,85 @@ +package setup + +import ( + "fmt" + "testing" + + "github.com/mholt/caddy/middleware/headers" +) + +func TestHeaders(t *testing.T) { + c := newTestController(`header / Foo Bar`) + + mid, err := Headers(c) + if err != nil { + t.Errorf("Expected no errors, but got: %v", err) + } + if mid == nil { + t.Fatal("Expected middleware, was nil instead") + } + + handler := mid(emptyNext) + myHandler, ok := handler.(headers.Headers) + if !ok { + t.Fatalf("Expected handler to be type BasicAuth, got: %#v", handler) + } + + if !sameNext(myHandler.Next, emptyNext) { + t.Error("'Next' field of handler was not set properly") + } +} + +func TestHeadersParse(t *testing.T) { + tests := []struct { + input string + shouldErr bool + expected []headers.Rule + }{ + {`header /foo Foo "Bar Baz"`, + false, []headers.Rule{ + {Path: "/foo", Headers: []headers.Header{ + {"Foo", "Bar Baz"}, + }}, + }}, + {`header /bar { Foo "Bar Baz" Baz Qux }`, + false, []headers.Rule{ + {Path: "/bar", Headers: []headers.Header{ + {"Foo", "Bar Baz"}, + {"Baz", "Qux"}, + }}, + }}, + } + + for i, test := range tests { + c := newTestController(test.input) + actual, err := headersParse(c) + + if err == nil && test.shouldErr { + t.Errorf("Test %d didn't error, but it should have", i) + } else if err != nil && !test.shouldErr { + t.Errorf("Test %d errored, but it shouldn't have; got '%v'", i, err) + } + + if len(actual) != len(test.expected) { + t.Fatalf("Test %d expected %d rules, but got %d", + i, len(test.expected), len(actual)) + } + + for j, expectedRule := range test.expected { + actualRule := actual[j] + + if actualRule.Path != expectedRule.Path { + t.Errorf("Test %d, rule %d: Expected path %s, but got %s", + i, j, expectedRule.Path, actualRule.Path) + } + + expectedHeaders := fmt.Sprintf("%v", expectedRule.Headers) + actualHeaders := fmt.Sprintf("%v", actualRule.Headers) + + if actualHeaders != expectedHeaders { + t.Errorf("Test %d, rule %d: Expected headers %s, but got %s", + i, j, expectedHeaders, actualHeaders) + } + } + } +} From 37b1a81fc7203e1db0335a415a5b5ddc84f290bc Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sun, 10 May 2015 07:44:43 +0200 Subject: [PATCH 5/5] headers: Corrected copy paste (BasicAuth->Headers) --- config/setup/headers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/setup/headers_test.go b/config/setup/headers_test.go index 5abc56b7..81c758ae 100644 --- a/config/setup/headers_test.go +++ b/config/setup/headers_test.go @@ -21,7 +21,7 @@ func TestHeaders(t *testing.T) { handler := mid(emptyNext) myHandler, ok := handler.(headers.Headers) if !ok { - t.Fatalf("Expected handler to be type BasicAuth, got: %#v", handler) + t.Fatalf("Expected handler to be type Headers, got: %#v", handler) } if !sameNext(myHandler.Next, emptyNext) {