Commit fe62afd3 authored by Matthew Holt's avatar Matthew Holt

Beginning to move middleware into their own packages

parent dca59d0e
...@@ -3,8 +3,6 @@ package config ...@@ -3,8 +3,6 @@ package config
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/mholt/caddy/middleware"
) )
// dispenser is a type that gets exposed to middleware // dispenser is a type that gets exposed to middleware
...@@ -15,7 +13,7 @@ type dispenser struct { ...@@ -15,7 +13,7 @@ type dispenser struct {
cursor int cursor int
nesting int nesting int
tokens []token tokens []token
err error //err error
} }
// newDispenser returns a new dispenser. // newDispenser returns a new dispenser.
...@@ -117,25 +115,23 @@ func (d *dispenser) Val() string { ...@@ -117,25 +115,23 @@ func (d *dispenser) Val() string {
// argument was expected but not found. The error is saved // argument was expected but not found. The error is saved
// within the dispenser, but this function returns nil for // within the dispenser, but this function returns nil for
// convenience in practice. // convenience in practice.
func (d *dispenser) ArgErr() middleware.Middleware { func (d *dispenser) ArgErr() error {
if d.Val() == "{" { if d.Val() == "{" {
d.Err("Unexpected token '{', expecting argument") return d.Err("Unexpected token '{', expecting argument")
return nil
} }
d.Err("Unexpected line break after '" + d.Val() + "' (missing arguments?)") return d.Err("Unexpected line break after '" + d.Val() + "' (missing arguments?)")
return nil
} }
// Err generates a custom parse error with a message of msg. // Err generates a custom parse error with a message of msg.
// TODO: Update the docs of all these Err methods!
// This function returns nil for convenience, but loads the // This function returns nil for convenience, but loads the
// error into the dispenser so it can be reported. The caller // error into the dispenser so it can be reported. The caller
// of the middleware preparator is responsible for checking // of the middleware preparator is responsible for checking
// the error in the dispenser after the middleware preparator // the error in the dispenser after the middleware preparator
// is finished. // is finished.
func (d *dispenser) Err(msg string) middleware.Middleware { func (d *dispenser) Err(msg string) error {
msg = fmt.Sprintf("%s:%d - Parse error: %s", d.parser.filename, d.tokens[d.cursor].line, msg) msg = fmt.Sprintf("%s:%d - Parse error: %s", d.parser.filename, d.tokens[d.cursor].line, msg)
d.err = errors.New(msg) return errors.New(msg)
return nil
} }
// Args is a convenience function that loads the next arguments // Args is a convenience function that loads the next arguments
......
package config
import (
"github.com/mholt/caddy/middleware"
"github.com/mholt/caddy/middleware/extensionless"
"github.com/mholt/caddy/middleware/fastcgi"
"github.com/mholt/caddy/middleware/gzip"
"github.com/mholt/caddy/middleware/headers"
"github.com/mholt/caddy/middleware/log"
"github.com/mholt/caddy/middleware/proxy"
"github.com/mholt/caddy/middleware/redirect"
"github.com/mholt/caddy/middleware/rewrite"
)
// This init function registers middleware. Register middleware
// in the order they should be executed during a request.
// Middleware execute in an order like this: A-B-C-*-C-B-A
func init() {
register("gzip", gzip.New)
register("header", headers.New)
register("log", log.New)
register("rewrite", rewrite.New)
register("redirect", redirect.New)
register("ext", extensionless.New)
register("proxy", proxy.New)
register("fastcgi", fastcgi.New)
}
var (
// registry stores the registered middleware:
// both the order and the directives to which they
// are bound.
registry = struct {
directiveMap map[string]middleware.Generator
order []string
}{
directiveMap: make(map[string]middleware.Generator),
}
)
// 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 middleware.Generator) {
registry.directiveMap[directive] = generator
registry.order = append(registry.order, directive)
}
// middlewareRegistered returns whether or not a directive is registered.
func middlewareRegistered(directive string) bool {
_, ok := registry.directiveMap[directive]
return ok
}
...@@ -5,8 +5,6 @@ import ( ...@@ -5,8 +5,6 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"github.com/mholt/caddy/middleware"
) )
// parser is a type which can parse config files. // parser is a type which can parse config files.
...@@ -108,12 +106,12 @@ func (p *parser) parseOne() error { ...@@ -108,12 +106,12 @@ func (p *parser) parseOne() error {
// This function should be called only after p has filled out // This function should be called only after p has filled out
// p.other and that the entire server block has been consumed. // p.other and that the entire server block has been consumed.
func (p *parser) unwrap() error { func (p *parser) unwrap() error {
for _, directive := range middleware.Ordered() { for directive := range registry.directiveMap {
if disp, ok := p.other[directive]; ok { if disp, ok := p.other[directive]; ok {
if generator, ok := middleware.GetGenerator(directive); ok { if generator, ok := registry.directiveMap[directive]; ok {
mid := generator(disp) mid, err := generator(disp)
if mid == nil { if err != nil {
return disp.err return err
} }
p.cfg.Middleware = append(p.cfg.Middleware, mid) p.cfg.Middleware = append(p.cfg.Middleware, mid)
} else { } else {
......
package config package config
import "github.com/mholt/caddy/middleware"
// This file contains the recursive-descent parsing // This file contains the recursive-descent parsing
// functions. // functions.
...@@ -98,7 +96,7 @@ func (p *parser) directives() error { ...@@ -98,7 +96,7 @@ func (p *parser) directives() error {
if err != nil { if err != nil {
return err return err
} }
} else if middleware.Registered(p.tkn()) { } else if middlewareRegistered(p.tkn()) {
err := p.collectTokens() err := p.collectTokens()
if err != nil { if err != nil {
return err return err
......
...@@ -7,41 +7,28 @@ import ( ...@@ -7,41 +7,28 @@ import (
"strings" "strings"
) )
// 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)
register("proxy", Proxy)
register("fastcgi", FastCGI)
}
type ( type (
// Generator represents the outer layer of a middleware that // Generator represents the outer layer of a middleware that
// parses tokens to configure the middleware instance. // parses tokens to configure the middleware instance.
Generator func(parser) Middleware Generator func(Controller) (Middleware, error)
// Middleware is the middle layer which represents the traditional // Middleware is the middle layer which represents the traditional
// idea of middleware: it is passed the next HandlerFunc in the chain // idea of middleware: it is passed the next HandlerFunc in the chain
// and returns the inner layer, which is the actual HandlerFunc. // and returns the inner layer, which is the actual HandlerFunc.
Middleware func(http.HandlerFunc) http.HandlerFunc Middleware func(http.HandlerFunc) http.HandlerFunc
// parser is the type which middleware generators use to access // Controller is the type which middleware generators use to access
// tokens and other information they need to configure the instance. // tokens and the server and any other information they need to
parser interface { // configure themselves.
Controller interface {
Next() bool Next() bool
NextArg() bool NextArg() bool
NextLine() bool NextLine() bool
NextBlock() bool NextBlock() bool
Val() string Val() string
Args(...*string) bool Args(...*string) bool
ArgErr() Middleware ArgErr() error
Err(string) Middleware Err(string) error
Startup(func() error) Startup(func() error)
Root() string Root() string
Host() string Host() string
...@@ -49,44 +36,6 @@ type ( ...@@ -49,44 +36,6 @@ type (
} }
) )
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. // Path represents a URI path, maybe with pattern characters.
type Path string type Path string
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment