diff --git a/middleware/headers.go b/middleware/headers.go deleted file mode 100644 index e1ffbdc48..000000000 --- a/middleware/headers.go +++ /dev/null @@ -1,91 +0,0 @@ -package middleware - -import "net/http" - -// Headers is middleware that adds headers to the responses -// for requests matching a certain path. -func Headers(p parser) Middleware { - type ( - // Header represents a single HTTP header, simply a name and value. - header struct { - Name string - Value string - } - - // Headers groups a slice of HTTP headers by a URL pattern. - headers struct { - Url string - Headers []header - } - ) - var rules []headers - - for p.NextLine() { - var head headers - var isNewPattern bool - - if !p.NextArg() { - return p.ArgErr() - } - pattern := p.Val() - - // See if we already have a definition for this URL pattern... - for _, h := range rules { - if h.Url == pattern { - head = h - break - } - } - - // ...otherwise, this is a new pattern - if head.Url == "" { - head.Url = pattern - isNewPattern = true - } - - for p.NextBlock() { - h := header{Name: p.Val()} - - if p.NextArg() { - h.Value = p.Val() - } - - head.Headers = append(head.Headers, h) - } - if p.NextArg() { - h := header{Name: p.Val()} - - h.Value = p.Val() - - if p.NextArg() { - h.Value = p.Val() - } - - head.Headers = append(head.Headers, h) - } - - if isNewPattern { - rules = append(rules, head) - } else { - for i := 0; i < len(rules); i++ { - if rules[i].Url == pattern { - rules[i] = head - break - } - } - } - } - - return func(next http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - for _, rule := range rules { - if Path(r.URL.Path).Matches(rule.Url) { - for _, header := range rule.Headers { - w.Header().Set(header.Name, header.Value) - } - } - } - next(w, r) - } - } -} diff --git a/middleware/headers/headers.go b/middleware/headers/headers.go new file mode 100644 index 000000000..edac2f22f --- /dev/null +++ b/middleware/headers/headers.go @@ -0,0 +1,42 @@ +package headers + +import ( + "net/http" + + "github.com/mholt/caddy/middleware/util" +) + +// Headers is middleware that adds headers to the responses +// for requests matching a certain path. +type Headers struct { + next http.HandlerFunc + rules []headers +} + +// ServeHTTP implements the http.Handler interface and serves the requests, +// adding headers to the response according to the configured rules. +func (h *Headers) ServeHTTP(w http.ResponseWriter, r *http.Request) { + for _, rule := range h.rules { + if util.Path(r.URL.Path).Matches(rule.Url) { + for _, header := range rule.Headers { + w.Header().Set(header.Name, header.Value) + } + } + } + h.next(w, r) +} + +type ( + // Headers groups a slice of HTTP headers by a URL pattern. + // TODO: use http.Header type instead?? + headers struct { + Url string + Headers []header + } + + // Header represents a single HTTP header, simply a name and value. + header struct { + Name string + Value string + } +) diff --git a/middleware/headers/new.go b/middleware/headers/new.go new file mode 100644 index 000000000..fcb073a80 --- /dev/null +++ b/middleware/headers/new.go @@ -0,0 +1,24 @@ +package headers + +import ( + "net/http" + + "github.com/mholt/caddy/middleware" +) + +// New constructs and configures a new headers middleware instance. +func New(c middleware.Controller) (middleware.Middleware, error) { + + rules, err := parse(c) + if err != nil { + return nil, err + } + + return func(next http.HandlerFunc) http.HandlerFunc { + head := Headers{ + next: next, + rules: rules, + } + return head.ServeHTTP + }, nil +} diff --git a/middleware/headers/parse.go b/middleware/headers/parse.go new file mode 100644 index 000000000..0c969baea --- /dev/null +++ b/middleware/headers/parse.go @@ -0,0 +1,65 @@ +package headers + +import "github.com/mholt/caddy/middleware" + +func parse(c middleware.Controller) ([]headers, error) { + var rules []headers + + for c.NextLine() { + var head headers + var isNewPattern bool + + if !c.NextArg() { + return rules, c.ArgErr() + } + pattern := c.Val() + + // See if we already have a definition for this URL pattern... + for _, h := range rules { + if h.Url == pattern { + head = h + break + } + } + + // ...otherwise, this is a new pattern + if head.Url == "" { + head.Url = pattern + isNewPattern = true + } + + for c.NextBlock() { + h := header{Name: c.Val()} + + if c.NextArg() { + h.Value = c.Val() + } + + head.Headers = append(head.Headers, h) + } + if c.NextArg() { + h := header{Name: c.Val()} + + h.Value = c.Val() + + if c.NextArg() { + h.Value = c.Val() + } + + head.Headers = append(head.Headers, h) + } + + if isNewPattern { + rules = append(rules, head) + } else { + for i := 0; i < len(rules); i++ { + if rules[i].Url == pattern { + rules[i] = head + break + } + } + } + } + + return rules, nil +}