Refactored rewrite middleware

This commit is contained in:
Matthew Holt 2015-04-11 16:58:34 -06:00
parent d0a0216602
commit abeb337f45
2 changed files with 39 additions and 23 deletions

View File

@ -16,7 +16,7 @@ var (
func init() {
flag.StringVar(&conf, "conf", server.DefaultConfigFile, "the configuration file to use")
flag.BoolVar(&http2, "http2", true, "enable HTTP/2 support") // flag temporary until http2 merged into std lib
flag.BoolVar(&http2, "http2", true, "enable HTTP/2 support") // temporary flag until http2 merged into std lib
}
func main() {
@ -38,7 +38,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
s.HTTP2 = http2
s.HTTP2 = http2 // TODO: This setting is temporary
wg.Add(1)
go func(s *server.Server) {
defer wg.Done()

View File

@ -8,42 +8,58 @@ import (
"github.com/mholt/caddy/middleware"
)
// New instantiates a new rewrite middleware.
// New instantiates a new Rewrites middleware.
func New(c middleware.Controller) (middleware.Middleware, error) {
var rewrites []rewrite
rewrites, err := parse(c)
if err != nil {
return nil, err
}
return func(next middleware.Handler) middleware.Handler {
return Rewrite{Next: next, Rules: rewrites}
}, nil
}
// Rewrite is middleware to rewrite request locations internally before being handled.
type Rewrite struct {
Next middleware.Handler
Rules []RewriteRule
}
// ServeHTTP implements the middleware.Handler interface.
func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
for _, rule := range rw.Rules {
if r.URL.Path == rule.From {
r.URL.Path = rule.To
break
}
}
return rw.Next.ServeHTTP(w, r)
}
func parse(c middleware.Controller) ([]RewriteRule, error) {
var rewrites []RewriteRule
for c.Next() {
var rule rewrite
var rule RewriteRule
if !c.NextArg() {
return nil, c.ArgErr()
return rewrites, c.ArgErr()
}
rule.From = c.Val()
if !c.NextArg() {
return nil, c.ArgErr()
return rewrites, c.ArgErr()
}
rule.To = c.Val()
rewrites = append(rewrites, rule)
}
// TODO: Why can't we just return an http.Handler here instead?
return func(next middleware.Handler) middleware.Handler {
return middleware.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) {
for _, rule := range rewrites {
if r.URL.Path == rule.From {
r.URL.Path = rule.To
break
}
}
return next.ServeHTTP(w, r)
})
}, nil
return rewrites, nil
}
// rewrite describes an internal location rewrite rule.
type rewrite struct {
From string
To string
// RewriteRule describes an internal location rewrite rule.
type RewriteRule struct {
From, To string
}