Moved headers middleware into its own package

Further trying out spreading out the code outside of the nested functions
This commit is contained in:
Matthew Holt 2015-01-29 22:05:05 -07:00
parent 80ef5d761c
commit 1e4baa53f0
4 changed files with 131 additions and 91 deletions

View File

@ -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)
}
}
}

View File

@ -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
}
)

24
middleware/headers/new.go Normal file
View File

@ -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
}

View File

@ -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
}