From fe62afd3d92bbd46170842bc78880c447df406e8 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Thu, 29 Jan 2015 22:02:17 -0700 Subject: [PATCH] Beginning to move middleware into their own packages --- config/dispenser.go | 18 +++++------ config/middleware.go | 53 ++++++++++++++++++++++++++++++++ config/parser.go | 12 ++++---- config/parsing.go | 4 +-- middleware/middleware.go | 65 +++++----------------------------------- 5 files changed, 73 insertions(+), 79 deletions(-) create mode 100644 config/middleware.go diff --git a/config/dispenser.go b/config/dispenser.go index beba59a33..6e6c29d79 100644 --- a/config/dispenser.go +++ b/config/dispenser.go @@ -3,8 +3,6 @@ package config import ( "errors" "fmt" - - "github.com/mholt/caddy/middleware" ) // dispenser is a type that gets exposed to middleware @@ -15,7 +13,7 @@ type dispenser struct { cursor int nesting int tokens []token - err error + //err error } // newDispenser returns a new dispenser. @@ -117,25 +115,23 @@ func (d *dispenser) Val() string { // argument was expected but not found. The error is saved // within the dispenser, but this function returns nil for // convenience in practice. -func (d *dispenser) ArgErr() middleware.Middleware { +func (d *dispenser) ArgErr() error { if d.Val() == "{" { - d.Err("Unexpected token '{', expecting argument") - return nil + return d.Err("Unexpected token '{', expecting argument") } - d.Err("Unexpected line break after '" + d.Val() + "' (missing arguments?)") - return nil + return d.Err("Unexpected line break after '" + d.Val() + "' (missing arguments?)") } // 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 // error into the dispenser so it can be reported. The caller // of the middleware preparator is responsible for checking // the error in the dispenser after the middleware preparator // 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) - d.err = errors.New(msg) - return nil + return errors.New(msg) } // Args is a convenience function that loads the next arguments diff --git a/config/middleware.go b/config/middleware.go new file mode 100644 index 000000000..34d884020 --- /dev/null +++ b/config/middleware.go @@ -0,0 +1,53 @@ +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 +} diff --git a/config/parser.go b/config/parser.go index 42855ed85..b20d546f4 100644 --- a/config/parser.go +++ b/config/parser.go @@ -5,8 +5,6 @@ import ( "fmt" "os" "strings" - - "github.com/mholt/caddy/middleware" ) // parser is a type which can parse config files. @@ -108,12 +106,12 @@ func (p *parser) parseOne() error { // This function should be called only after p has filled out // p.other and that the entire server block has been consumed. func (p *parser) unwrap() error { - for _, directive := range middleware.Ordered() { + for directive := range registry.directiveMap { if disp, ok := p.other[directive]; ok { - if generator, ok := middleware.GetGenerator(directive); ok { - mid := generator(disp) - if mid == nil { - return disp.err + if generator, ok := registry.directiveMap[directive]; ok { + mid, err := generator(disp) + if err != nil { + return err } p.cfg.Middleware = append(p.cfg.Middleware, mid) } else { diff --git a/config/parsing.go b/config/parsing.go index 4d7289fb6..d04b5f5da 100644 --- a/config/parsing.go +++ b/config/parsing.go @@ -1,7 +1,5 @@ package config -import "github.com/mholt/caddy/middleware" - // This file contains the recursive-descent parsing // functions. @@ -98,7 +96,7 @@ func (p *parser) directives() error { if err != nil { return err } - } else if middleware.Registered(p.tkn()) { + } else if middlewareRegistered(p.tkn()) { err := p.collectTokens() if err != nil { return err diff --git a/middleware/middleware.go b/middleware/middleware.go index 848786a58..aadc491d0 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -7,41 +7,28 @@ import ( "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 ( // Generator represents the outer layer of a middleware that // 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 // 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 { + // Controller is the type which middleware generators use to access + // tokens and the server and any other information they need to + // configure themselves. + Controller interface { Next() bool NextArg() bool NextLine() bool NextBlock() bool Val() string Args(...*string) bool - ArgErr() Middleware - Err(string) Middleware + ArgErr() error + Err(string) error Startup(func() error) Root() string Host() string @@ -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. type Path string