Commit 63f74911 authored by Mateusz Gajewski's avatar Mateusz Gajewski Committed by Matt Holt

Use http.Header instead of custom type (#1214)

* Use http.Header

* This initialization was just stupid
parent e19a007b
...@@ -26,15 +26,21 @@ func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) ...@@ -26,15 +26,21 @@ func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
rww := &responseWriterWrapper{w: w} rww := &responseWriterWrapper{w: w}
for _, rule := range h.Rules { for _, rule := range h.Rules {
if httpserver.Path(r.URL.Path).Matches(rule.Path) { if httpserver.Path(r.URL.Path).Matches(rule.Path) {
for _, header := range rule.Headers { for name := range rule.Headers {
// One can either delete a header, add multiple values to a header, or simply // One can either delete a header, add multiple values to a header, or simply
// set a header. // set a header.
if strings.HasPrefix(header.Name, "-") {
rww.delHeader(strings.TrimLeft(header.Name, "-")) if strings.HasPrefix(name, "-") {
} else if strings.HasPrefix(header.Name, "+") { rww.delHeader(strings.TrimLeft(name, "-"))
rww.Header().Add(strings.TrimLeft(header.Name, "+"), replacer.Replace(header.Value)) } else if strings.HasPrefix(name, "+") {
for _, value := range rule.Headers[name] {
rww.Header().Add(strings.TrimLeft(name, "+"), replacer.Replace(value))
}
} else { } else {
rww.Header().Set(header.Name, replacer.Replace(header.Value)) for _, value := range rule.Headers[name] {
rww.Header().Set(name, replacer.Replace(value))
}
} }
} }
} }
...@@ -44,16 +50,9 @@ func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) ...@@ -44,16 +50,9 @@ func (h Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
type ( type (
// Rule groups a slice of HTTP headers by a URL pattern. // Rule groups a slice of HTTP headers by a URL pattern.
// TODO: use http.Header type instead?
Rule struct { Rule struct {
Path string Path string
Headers []Header Headers http.Header
}
// Header represents a single HTTP header, simply a name and value.
Header struct {
Name string
Value string
} }
) )
......
...@@ -37,11 +37,11 @@ func TestHeader(t *testing.T) { ...@@ -37,11 +37,11 @@ func TestHeader(t *testing.T) {
return 0, nil return 0, nil
}), }),
Rules: []Rule{ Rules: []Rule{
{Path: "/a", Headers: []Header{ {Path: "/a", Headers: http.Header{
{Name: "Foo", Value: "Bar"}, "Foo": []string{"Bar"},
{Name: "ServerName", Value: "{hostname}"}, "ServerName": []string{"{hostname}"},
{Name: "-Bar"}, "-Bar": []string{""},
{Name: "-Server"}, "-Server": []string{},
}}, }},
}, },
} }
...@@ -71,9 +71,8 @@ func TestMultipleHeaders(t *testing.T) { ...@@ -71,9 +71,8 @@ func TestMultipleHeaders(t *testing.T) {
return 0, nil return 0, nil
}), }),
Rules: []Rule{ Rules: []Rule{
{Path: "/a", Headers: []Header{ {Path: "/a", Headers: http.Header{
{Name: "+Link", Value: "</images/image.png>; rel=preload"}, "+Link": []string{"</images/image.png>; rel=preload", "</css/main.css>; rel=preload"},
{Name: "+Link", Value: "</css/main.css>; rel=preload"},
}}, }},
}, },
} }
......
package header package header
import ( import (
"net/http"
"github.com/mholt/caddy" "github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
) )
...@@ -31,6 +33,7 @@ func headersParse(c *caddy.Controller) ([]Rule, error) { ...@@ -31,6 +33,7 @@ func headersParse(c *caddy.Controller) ([]Rule, error) {
for c.NextLine() { for c.NextLine() {
var head Rule var head Rule
head.Headers = http.Header{}
var isNewPattern bool var isNewPattern bool
if !c.NextArg() { if !c.NextArg() {
...@@ -54,27 +57,26 @@ func headersParse(c *caddy.Controller) ([]Rule, error) { ...@@ -54,27 +57,26 @@ func headersParse(c *caddy.Controller) ([]Rule, error) {
for c.NextBlock() { for c.NextBlock() {
// A block of headers was opened... // A block of headers was opened...
name := c.Val()
h := Header{Name: c.Val()} value := ""
if c.NextArg() { if c.NextArg() {
h.Value = c.Val() value = c.Val()
} }
head.Headers = append(head.Headers, h) head.Headers.Add(name, value)
} }
if c.NextArg() { if c.NextArg() {
// ... or single header was defined as an argument instead. // ... or single header was defined as an argument instead.
h := Header{Name: c.Val()} name := c.Val()
value := c.Val()
h.Value = c.Val()
if c.NextArg() { if c.NextArg() {
h.Value = c.Val() value = c.Val()
} }
head.Headers = append(head.Headers, h) head.Headers.Add(name, value)
} }
if isNewPattern { if isNewPattern {
......
...@@ -2,6 +2,8 @@ package header ...@@ -2,6 +2,8 @@ package header
import ( import (
"fmt" "fmt"
"net/http"
"reflect"
"testing" "testing"
"github.com/mholt/caddy" "github.com/mholt/caddy"
...@@ -39,15 +41,15 @@ func TestHeadersParse(t *testing.T) { ...@@ -39,15 +41,15 @@ func TestHeadersParse(t *testing.T) {
}{ }{
{`header /foo Foo "Bar Baz"`, {`header /foo Foo "Bar Baz"`,
false, []Rule{ false, []Rule{
{Path: "/foo", Headers: []Header{ {Path: "/foo", Headers: http.Header{
{Name: "Foo", Value: "Bar Baz"}, "Foo": []string{"Bar Baz"},
}}, }},
}}, }},
{`header /bar { Foo "Bar Baz" Baz Qux }`, {`header /bar { Foo "Bar Baz" Baz Qux }`,
false, []Rule{ false, []Rule{
{Path: "/bar", Headers: []Header{ {Path: "/bar", Headers: http.Header{
{Name: "Foo", Value: "Bar Baz"}, "Foo": []string{"Bar Baz"},
{Name: "Baz", Value: "Qux"}, "Baz": []string{"Qux"},
}}, }},
}}, }},
} }
...@@ -77,7 +79,7 @@ func TestHeadersParse(t *testing.T) { ...@@ -77,7 +79,7 @@ func TestHeadersParse(t *testing.T) {
expectedHeaders := fmt.Sprintf("%v", expectedRule.Headers) expectedHeaders := fmt.Sprintf("%v", expectedRule.Headers)
actualHeaders := fmt.Sprintf("%v", actualRule.Headers) actualHeaders := fmt.Sprintf("%v", actualRule.Headers)
if actualHeaders != expectedHeaders { if !reflect.DeepEqual(actualRule.Headers, expectedRule.Headers) {
t.Errorf("Test %d, rule %d: Expected headers %s, but got %s", t.Errorf("Test %d, rule %d: Expected headers %s, but got %s",
i, j, expectedHeaders, actualHeaders) i, j, expectedHeaders, actualHeaders)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment