2015-01-13 14:43:45 -05:00
|
|
|
package config
|
|
|
|
|
2015-01-21 16:10:52 -05:00
|
|
|
import (
|
2015-05-01 17:23:28 -05:00
|
|
|
"fmt"
|
|
|
|
"log"
|
2015-01-21 16:10:52 -05:00
|
|
|
"os"
|
2015-03-26 10:52:03 -05:00
|
|
|
"os/exec"
|
|
|
|
|
|
|
|
"github.com/mholt/caddy/middleware"
|
2015-01-21 16:10:52 -05:00
|
|
|
)
|
2015-01-19 01:11:21 -05:00
|
|
|
|
2015-01-13 14:43:45 -05:00
|
|
|
// dirFunc is a type of parsing function which processes
|
|
|
|
// a particular directive and populates the config.
|
|
|
|
type dirFunc func(*parser) error
|
|
|
|
|
2015-01-31 12:15:17 -05:00
|
|
|
// validDirectives is a map of valid, built-in directive names
|
2015-03-03 11:49:01 -05:00
|
|
|
// to their parsing function. Built-in directives cannot be
|
|
|
|
// ordered, so they should only be used for internal server
|
|
|
|
// configuration; not directly handling requests.
|
2015-01-13 14:43:45 -05:00
|
|
|
var validDirectives map[string]dirFunc
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// This has to be in the init function
|
|
|
|
// to avoid an initialization loop error because
|
|
|
|
// the 'import' directive (key) in this map
|
|
|
|
// invokes a method that uses this map.
|
|
|
|
validDirectives = map[string]dirFunc{
|
|
|
|
"root": func(p *parser) error {
|
2015-01-19 01:11:21 -05:00
|
|
|
if !p.nextArg() {
|
2015-01-13 14:43:45 -05:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
p.cfg.Root = p.tkn()
|
2015-05-01 14:35:43 -05:00
|
|
|
|
|
|
|
// Ensure root folder exists
|
2015-05-02 12:57:53 -05:00
|
|
|
_, err := os.Stat(p.cfg.Root)
|
2015-05-01 14:35:43 -05:00
|
|
|
if err != nil {
|
|
|
|
if os.IsNotExist(err) {
|
2015-05-01 17:23:28 -05:00
|
|
|
// Allow this, because the folder might appear later.
|
|
|
|
// But make sure the user knows!
|
|
|
|
log.Printf("Warning: Root path %s does not exist", p.cfg.Root)
|
2015-05-01 14:35:43 -05:00
|
|
|
} else {
|
2015-05-01 17:23:28 -05:00
|
|
|
return p.err("Path", fmt.Sprintf("Unable to access root path '%s': %s", p.cfg.Root, err.Error()))
|
2015-05-01 14:35:43 -05:00
|
|
|
}
|
|
|
|
}
|
2015-01-13 14:43:45 -05:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
"import": func(p *parser) error {
|
2015-01-19 01:11:21 -05:00
|
|
|
if !p.nextArg() {
|
2015-01-13 14:43:45 -05:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
|
2015-01-21 15:19:25 -05:00
|
|
|
filename := p.tkn()
|
|
|
|
file, err := os.Open(filename)
|
2015-01-13 14:43:45 -05:00
|
|
|
if err != nil {
|
|
|
|
return p.err("Parse", err.Error())
|
|
|
|
}
|
2015-01-19 01:11:21 -05:00
|
|
|
defer file.Close()
|
2015-01-21 15:19:25 -05:00
|
|
|
p2, err := newParser(file)
|
|
|
|
if err != nil {
|
|
|
|
return p.err("Parse", "Could not import "+filename+"; "+err.Error())
|
|
|
|
}
|
2015-01-13 14:43:45 -05:00
|
|
|
|
|
|
|
p2.cfg = p.cfg
|
|
|
|
err = p2.directives()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
p.cfg = p2.cfg
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
"tls": func(p *parser) error {
|
|
|
|
tls := TLSConfig{Enabled: true}
|
|
|
|
|
2015-01-19 01:11:21 -05:00
|
|
|
if !p.nextArg() {
|
2015-01-13 14:43:45 -05:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
tls.Certificate = p.tkn()
|
|
|
|
|
2015-01-19 01:11:21 -05:00
|
|
|
if !p.nextArg() {
|
2015-01-13 14:43:45 -05:00
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
tls.Key = p.tkn()
|
|
|
|
|
|
|
|
p.cfg.TLS = tls
|
|
|
|
return nil
|
|
|
|
},
|
2015-03-26 10:52:03 -05:00
|
|
|
"startup": func(p *parser) error {
|
|
|
|
// TODO: This code is duplicated with the shutdown directive below
|
|
|
|
|
|
|
|
if !p.nextArg() {
|
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
|
|
|
|
command, args, err := middleware.SplitCommandAndArgs(p.tkn())
|
|
|
|
if err != nil {
|
|
|
|
return p.err("Parse", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
startupfn := func() error {
|
|
|
|
cmd := exec.Command(command, args...)
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
p.cfg.Startup = append(p.cfg.Startup, startupfn)
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
"shutdown": func(p *parser) error {
|
|
|
|
if !p.nextArg() {
|
|
|
|
return p.argErr()
|
|
|
|
}
|
|
|
|
|
|
|
|
command, args, err := middleware.SplitCommandAndArgs(p.tkn())
|
|
|
|
if err != nil {
|
|
|
|
return p.err("Parse", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
shutdownfn := func() error {
|
|
|
|
cmd := exec.Command(command, args...)
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
p.cfg.Shutdown = append(p.cfg.Shutdown, shutdownfn)
|
|
|
|
return nil
|
|
|
|
},
|
2015-01-13 14:43:45 -05:00
|
|
|
}
|
|
|
|
}
|