mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-13 22:51:08 -05:00
Moved controller into its own file; other minor cleanups
This commit is contained in:
parent
16997d85eb
commit
5ae1790e52
5 changed files with 110 additions and 65 deletions
43
config/controller.go
Normal file
43
config/controller.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package config
|
||||
|
||||
// controller is a dispenser of tokens and also
|
||||
// facilitates setup with the server by providing
|
||||
// access to its configuration. It implements
|
||||
// the middleware.Controller interface.
|
||||
type controller struct {
|
||||
dispenser
|
||||
}
|
||||
|
||||
// newController returns a new controller.
|
||||
func newController(p *parser) *controller {
|
||||
return &controller{
|
||||
dispenser: dispenser{
|
||||
cursor: -1,
|
||||
parser: p,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Startup registers a function to execute when the server starts.
|
||||
func (c *controller) Startup(fn func() error) {
|
||||
c.parser.cfg.Startup = append(c.parser.cfg.Startup, fn)
|
||||
}
|
||||
|
||||
// Root returns the server root file path.
|
||||
func (c *controller) Root() string {
|
||||
if c.parser.cfg.Root == "" {
|
||||
return "."
|
||||
} else {
|
||||
return c.parser.cfg.Root
|
||||
}
|
||||
}
|
||||
|
||||
// Host returns the hostname the server is bound to.
|
||||
func (c *controller) Host() string {
|
||||
return c.parser.cfg.Host
|
||||
}
|
||||
|
||||
// Port returns the port that the server is listening on.
|
||||
func (c *controller) Port() string {
|
||||
return c.parser.cfg.Port
|
||||
}
|
|
@ -11,8 +11,8 @@ import (
|
|||
// a particular directive and populates the config.
|
||||
type dirFunc func(*parser) error
|
||||
|
||||
// validDirectives is a map of valid directive names to
|
||||
// their parsing function.
|
||||
// validDirectives is a map of valid, built-in directive names
|
||||
// to their parsing function.
|
||||
var validDirectives map[string]dirFunc
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -5,54 +5,10 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// newController returns a new controller.
|
||||
func newController(p *parser) *controller {
|
||||
return &controller{
|
||||
dispenser: dispenser{
|
||||
cursor: -1,
|
||||
parser: p,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// controller is a dispenser of tokens and also
|
||||
// facilitates setup with the server by providing
|
||||
// access to its configuration. It implements
|
||||
// the middleware.Controller interface.
|
||||
type controller struct {
|
||||
dispenser
|
||||
}
|
||||
|
||||
// Startup registers a function to execute when the server starts.
|
||||
func (c *controller) Startup(fn func() error) {
|
||||
c.parser.cfg.Startup = append(c.parser.cfg.Startup, fn)
|
||||
}
|
||||
|
||||
// Root returns the server root file path.
|
||||
func (c *controller) Root() string {
|
||||
if c.parser.cfg.Root == "" {
|
||||
return "."
|
||||
} else {
|
||||
return c.parser.cfg.Root
|
||||
}
|
||||
}
|
||||
|
||||
// Host returns the hostname the server is bound to.
|
||||
func (c *controller) Host() string {
|
||||
return c.parser.cfg.Host
|
||||
}
|
||||
|
||||
// Port returns the port that the server is listening on.
|
||||
func (c *controller) Port() string {
|
||||
return c.parser.cfg.Port
|
||||
}
|
||||
|
||||
// dispenser is a type that gets exposed to middleware
|
||||
// generators so that they can parse tokens to configure
|
||||
// their instance.
|
||||
// TODO: Rename this; it does more than dispense tokens.
|
||||
// It also provides access to the server to touch its
|
||||
// configuration.
|
||||
// their instance. It basically dispenses tokens but can
|
||||
// do so in a structured manner.
|
||||
type dispenser struct {
|
||||
parser *parser
|
||||
cursor int
|
||||
|
@ -115,7 +71,9 @@ func (d *dispenser) NextLine() bool {
|
|||
// if the current token is an open curly brace on the
|
||||
// same line. If so, that token is consumed and this
|
||||
// function will return true until the closing curly
|
||||
// brace is consumed by this method.
|
||||
// brace is consumed by this method. Usually, you would
|
||||
// use this as the condition of a for loop to parse
|
||||
// tokens while being inside the block.
|
||||
func (d *dispenser) NextBlock() bool {
|
||||
if d.nesting > 0 {
|
||||
d.Next()
|
||||
|
|
|
@ -62,7 +62,7 @@ func (p *parser) addressBlock() error {
|
|||
// openCurlyBrace expects the current token to be an
|
||||
// opening curly brace. This acts like an assertion
|
||||
// because it returns an error if the token is not
|
||||
// a opening curly brace.
|
||||
// a opening curly brace. It does not advance the token.
|
||||
func (p *parser) openCurlyBrace() error {
|
||||
if p.tkn() != "{" {
|
||||
return p.syntaxErr("{")
|
||||
|
@ -73,7 +73,7 @@ func (p *parser) openCurlyBrace() error {
|
|||
// closeCurlyBrace expects the current token to be
|
||||
// a closing curly brace. This acts like an assertion
|
||||
// because it returns an error if the token is not
|
||||
// a closing curly brace.
|
||||
// a closing curly brace. It does not advance the token.
|
||||
func (p *parser) closeCurlyBrace() error {
|
||||
if p.tkn() != "}" {
|
||||
return p.syntaxErr("}")
|
||||
|
@ -84,32 +84,80 @@ func (p *parser) closeCurlyBrace() error {
|
|||
// directives parses through all the directives
|
||||
// and it expects the current token to be the first
|
||||
// directive. It goes until EOF or closing curly
|
||||
// brace.
|
||||
// brace which ends the address block.
|
||||
func (p *parser) directives() error {
|
||||
for p.next() {
|
||||
if p.tkn() == "}" {
|
||||
// end of address scope
|
||||
break
|
||||
}
|
||||
if fn, ok := validDirectives[p.tkn()]; ok {
|
||||
err := fn(p)
|
||||
if p.tkn()[0] == '/' {
|
||||
// Path scope (a.k.a. location context)
|
||||
// TODO: The parser can handle the syntax (obviously), but the
|
||||
// implementation is incomplete. This is intentional,
|
||||
// until we can better decide what kind of feature set we
|
||||
// want to support. Until this is ready, we leave this
|
||||
// syntax undocumented.
|
||||
|
||||
// location := p.tkn()
|
||||
|
||||
if !p.next() {
|
||||
return p.eofErr()
|
||||
}
|
||||
|
||||
err := p.openCurlyBrace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if middlewareRegistered(p.tkn()) {
|
||||
err := p.collectTokens()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
for p.next() {
|
||||
err := p.closeCurlyBrace()
|
||||
if err == nil { // end of location context
|
||||
break
|
||||
}
|
||||
|
||||
// TODO: How should we give the context to the directives?
|
||||
// Or how do we tell the server that these directives should only
|
||||
// be executed for requests routed to the current path?
|
||||
|
||||
err = p.directive()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return p.err("Syntax", "Unexpected token '"+p.tkn()+"', expecting a valid directive")
|
||||
} else if err := p.directive(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// directive asserts that the current token is either a built-in
|
||||
// directive or a registered middleware directive; otherwise an error
|
||||
// will be returned.
|
||||
func (p *parser) directive() error {
|
||||
if fn, ok := validDirectives[p.tkn()]; ok {
|
||||
// Built-in (standard) directive
|
||||
err := fn(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if middlewareRegistered(p.tkn()) {
|
||||
// Middleware directive
|
||||
err := p.collectTokens()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return p.err("Syntax", "Unexpected token '"+p.tkn()+"', expecting a valid directive")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectTokens consumes tokens until the directive's scope
|
||||
// closes (either end of line or end of curly brace block).
|
||||
// It creates a controller which is stored in the parser for
|
||||
// later use by the middleware.
|
||||
func (p *parser) collectTokens() error {
|
||||
directive := p.tkn()
|
||||
line := p.line()
|
||||
|
|
|
@ -15,10 +15,6 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
|
|||
}
|
||||
|
||||
return func(next http.HandlerFunc) http.HandlerFunc {
|
||||
head := Headers{
|
||||
Next: next,
|
||||
Rules: rules,
|
||||
}
|
||||
return head.ServeHTTP
|
||||
return Headers{Next: next, Rules: rules}.ServeHTTP
|
||||
}, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue