2015-01-13 14:43:45 -05:00
|
|
|
// Package middleware includes a variety of middleware for
|
|
|
|
// the servers to use, according to their configuration.
|
|
|
|
package middleware
|
|
|
|
|
2015-01-19 01:11:21 -05:00
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
)
|
2015-01-13 14:43:45 -05:00
|
|
|
|
2015-01-19 01:11:21 -05:00
|
|
|
// This init function registers middleware. Register middleware
|
|
|
|
// in the order they should be executed during a request.
|
|
|
|
// Middlewares execute in an order like A-B-C-C-B-A.
|
|
|
|
func init() {
|
|
|
|
register("gzip", Gzip)
|
|
|
|
register("header", Headers)
|
|
|
|
register("log", RequestLog)
|
|
|
|
register("rewrite", Rewrite)
|
|
|
|
register("redir", Redirect)
|
|
|
|
register("ext", Extensionless)
|
|
|
|
}
|
|
|
|
|
|
|
|
type (
|
|
|
|
// Generator represents the outer layer of a middleware that
|
|
|
|
// parses tokens to configure the middleware instance.
|
|
|
|
Generator func(parser) Middleware
|
|
|
|
|
|
|
|
// Middleware is the middle layer which represents the traditional
|
|
|
|
// idea of middleware: it is passed the next HandlerFunc in the chain
|
|
|
|
// and returns the inner layer, which is the actual HandlerFunc.
|
|
|
|
Middleware func(http.HandlerFunc) http.HandlerFunc
|
|
|
|
|
|
|
|
// parser is the type which middleware generators use to access
|
|
|
|
// tokens and other information they need to configure the instance.
|
|
|
|
parser interface {
|
|
|
|
Next() bool
|
|
|
|
NextArg() bool
|
|
|
|
NextLine() bool
|
|
|
|
Val() string
|
|
|
|
OpenCurlyBrace() bool
|
|
|
|
CloseCurlyBrace() bool
|
|
|
|
ArgErr() Middleware
|
|
|
|
Err(string, string) Middleware
|
|
|
|
Args(...*string)
|
|
|
|
Startup(func() error)
|
|
|
|
Root() string
|
|
|
|
Host() string
|
|
|
|
Port() string
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// registry stores the registered middleware:
|
|
|
|
// both the order and the directives to which they
|
|
|
|
// are bound.
|
|
|
|
registry = struct {
|
|
|
|
directiveMap map[string]Generator
|
|
|
|
order []string
|
|
|
|
}{
|
|
|
|
directiveMap: make(map[string]Generator),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// GetGenerator gets the generator function (outer layer)
|
|
|
|
// of a middleware, according to the directive passed in.
|
|
|
|
func GetGenerator(directive string) (Generator, bool) {
|
|
|
|
rm, ok := registry.directiveMap[directive]
|
|
|
|
return rm, ok
|
|
|
|
}
|
|
|
|
|
|
|
|
// register binds a middleware generator (outer function)
|
|
|
|
// to a directive. Upon each request, middleware will be
|
|
|
|
// executed in the order they are registered.
|
|
|
|
func register(directive string, generator Generator) {
|
|
|
|
registry.directiveMap[directive] = generator
|
|
|
|
registry.order = append(registry.order, directive)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ordered returns the ordered list of registered directives.
|
|
|
|
func Ordered() []string {
|
|
|
|
return registry.order
|
|
|
|
}
|
|
|
|
|
|
|
|
// Registered returns whether or not a directive is registered.
|
|
|
|
func Registered(directive string) bool {
|
|
|
|
_, ok := GetGenerator(directive)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
|
|
|
// Path represents a URI path, maybe with pattern characters.
|
|
|
|
type Path string
|
|
|
|
|
|
|
|
// Path matching will probably not always be a direct
|
|
|
|
// comparison; this method assures that paths can be
|
|
|
|
// easily matched.
|
|
|
|
func (p Path) Matches(other string) bool {
|
|
|
|
return strings.HasPrefix(string(p), other)
|
|
|
|
}
|