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