mirror of
https://github.com/caddyserver/caddy.git
synced 2025-03-20 20:48:59 +01: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.
|
// a particular directive and populates the config.
|
||||||
type dirFunc func(*parser) error
|
type dirFunc func(*parser) error
|
||||||
|
|
||||||
// validDirectives is a map of valid directive names to
|
// validDirectives is a map of valid, built-in directive names
|
||||||
// their parsing function.
|
// to their parsing function.
|
||||||
var validDirectives map[string]dirFunc
|
var validDirectives map[string]dirFunc
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -5,54 +5,10 @@ import (
|
||||||
"fmt"
|
"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
|
// dispenser is a type that gets exposed to middleware
|
||||||
// generators so that they can parse tokens to configure
|
// generators so that they can parse tokens to configure
|
||||||
// their instance.
|
// their instance. It basically dispenses tokens but can
|
||||||
// TODO: Rename this; it does more than dispense tokens.
|
// do so in a structured manner.
|
||||||
// It also provides access to the server to touch its
|
|
||||||
// configuration.
|
|
||||||
type dispenser struct {
|
type dispenser struct {
|
||||||
parser *parser
|
parser *parser
|
||||||
cursor int
|
cursor int
|
||||||
|
@ -115,7 +71,9 @@ func (d *dispenser) NextLine() bool {
|
||||||
// if the current token is an open curly brace on the
|
// if the current token is an open curly brace on the
|
||||||
// same line. If so, that token is consumed and this
|
// same line. If so, that token is consumed and this
|
||||||
// function will return true until the closing curly
|
// 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 {
|
func (d *dispenser) NextBlock() bool {
|
||||||
if d.nesting > 0 {
|
if d.nesting > 0 {
|
||||||
d.Next()
|
d.Next()
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (p *parser) addressBlock() error {
|
||||||
// openCurlyBrace expects the current token to be an
|
// openCurlyBrace expects the current token to be an
|
||||||
// opening curly brace. This acts like an assertion
|
// opening curly brace. This acts like an assertion
|
||||||
// because it returns an error if the token is not
|
// 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 {
|
func (p *parser) openCurlyBrace() error {
|
||||||
if p.tkn() != "{" {
|
if p.tkn() != "{" {
|
||||||
return p.syntaxErr("{")
|
return p.syntaxErr("{")
|
||||||
|
@ -73,7 +73,7 @@ func (p *parser) openCurlyBrace() error {
|
||||||
// closeCurlyBrace expects the current token to be
|
// closeCurlyBrace expects the current token to be
|
||||||
// a closing curly brace. This acts like an assertion
|
// a closing curly brace. This acts like an assertion
|
||||||
// because it returns an error if the token is not
|
// 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 {
|
func (p *parser) closeCurlyBrace() error {
|
||||||
if p.tkn() != "}" {
|
if p.tkn() != "}" {
|
||||||
return p.syntaxErr("}")
|
return p.syntaxErr("}")
|
||||||
|
@ -84,32 +84,80 @@ func (p *parser) closeCurlyBrace() error {
|
||||||
// directives parses through all the directives
|
// directives parses through all the directives
|
||||||
// and it expects the current token to be the first
|
// and it expects the current token to be the first
|
||||||
// directive. It goes until EOF or closing curly
|
// directive. It goes until EOF or closing curly
|
||||||
// brace.
|
// brace which ends the address block.
|
||||||
func (p *parser) directives() error {
|
func (p *parser) directives() error {
|
||||||
for p.next() {
|
for p.next() {
|
||||||
if p.tkn() == "}" {
|
if p.tkn() == "}" {
|
||||||
// end of address scope
|
// end of address scope
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if fn, ok := validDirectives[p.tkn()]; ok {
|
if p.tkn()[0] == '/' {
|
||||||
err := fn(p)
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if middlewareRegistered(p.tkn()) {
|
|
||||||
err := p.collectTokens()
|
for p.next() {
|
||||||
if err != nil {
|
err := p.closeCurlyBrace()
|
||||||
return err
|
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 {
|
} else if err := p.directive(); err != nil {
|
||||||
return p.err("Syntax", "Unexpected token '"+p.tkn()+"', expecting a valid directive")
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
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
|
// collectTokens consumes tokens until the directive's scope
|
||||||
// closes (either end of line or end of curly brace block).
|
// 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 {
|
func (p *parser) collectTokens() error {
|
||||||
directive := p.tkn()
|
directive := p.tkn()
|
||||||
line := p.line()
|
line := p.line()
|
||||||
|
|
|
@ -15,10 +15,6 @@ func New(c middleware.Controller) (middleware.Middleware, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(next http.HandlerFunc) http.HandlerFunc {
|
return func(next http.HandlerFunc) http.HandlerFunc {
|
||||||
head := Headers{
|
return Headers{Next: next, Rules: rules}.ServeHTTP
|
||||||
Next: next,
|
|
||||||
Rules: rules,
|
|
||||||
}
|
|
||||||
return head.ServeHTTP
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue