author | Alberto Bertogli
<albertito@blitiri.com.ar> 2020-06-13 01:28:25 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2020-06-13 12:14:28 UTC |
parent | 5195e1f005e1512a8a4aaa84095575e461ed6acf |
config/config.go | +76 | -0 |
gofer.go | +15 | -2 |
diff --git a/config/config.go b/config/config.go index 9e6f236..6fe1ece 100644 --- a/config/config.go +++ b/config/config.go @@ -78,6 +78,72 @@ func (c Config) ToString() (string, error) { return string(d), err } +func (c Config) Check() []error { + errs := []error{} + for addr, h := range c.HTTP { + errs = append(errs, h.Check(c, addr)...) + + } + + for addr, h := range c.HTTPS { + errs = append(errs, h.Check(c, addr)...) + + // Certs must be set for HTTPS. + if h.Certs == "" { + errs = append(errs, + fmt.Errorf("%q: certs must be set", addr)) + } + } + + for addr, r := range c.Raw { + if _, ok := c.ReqLog[r.ReqLog]; r.ReqLog != "" && !ok { + errs = append(errs, + fmt.Errorf("%q: unknown reqlog %q", addr, r.ReqLog)) + } + } + return errs +} + +func (h HTTP) Check(c Config, addr string) []error { + errs := []error{} + + if len(h.Routes) == 0 { + errs = append(errs, fmt.Errorf("%q: missing routes", addr)) + } + + for path, r := range h.Routes { + if len(r.DirOpts.Listing)+len(r.DirOpts.Exclude) > 0 && r.Dir == "" { + errs = append(errs, + fmt.Errorf("%q: %q: diropts is set on non-dir route", + addr, path)) + } + + nSet := nTrue( + r.Dir != "", + r.File != "", + r.Proxy != nil, + r.Redirect != nil, + len(r.CGI) > 0, + r.Status > 0) + if nSet > 1 { + errs = append(errs, + fmt.Errorf("%q: %q: too many actions set", addr, path)) + } else if nSet == 0 { + errs = append(errs, + fmt.Errorf("%q: %q: action missing", addr, path)) + } + } + + for path, name := range h.ReqLog { + if _, ok := c.ReqLog[name]; !ok { + errs = append(errs, + fmt.Errorf("%q: %q: unknown reqlog %q", addr, path, name)) + } + } + + return errs +} + func Load(filename string) (*Config, error) { contents, err := ioutil.ReadFile(filename) if err != nil { @@ -138,3 +204,13 @@ func (u URL) String() string { p := u.URL() return p.String() } + +func nTrue(bs ...bool) int { + n := 0 + for _, b := range bs { + if b { + n++ + } + } + return n +} diff --git a/gofer.go b/gofer.go index 573cb0a..6f003b1 100644 --- a/gofer.go +++ b/gofer.go @@ -16,7 +16,9 @@ import ( // Flags. var ( - configfile = flag.String("configfile", "gofer.yaml", "Configuration file") + configFile = flag.String("configfile", "gofer.yaml", "Configuration file") + configCheck = flag.Bool("configcheck", false, + "Check the configuration and exit afterwards") ) func main() { @@ -24,11 +26,22 @@ func main() { log.Init() log.Infof("gofer starting (%s, %s)", debug.Version, debug.SourceDateStr) - conf, err := config.Load(*configfile) + conf, err := config.Load(*configFile) if err != nil { log.Fatalf("error reading config file: %v", err) } + if errs := conf.Check(); len(errs) > 0 { + for _, err := range errs { + log.Errorf("%v", err) + } + log.Fatalf("invalid configuration") + } + if *configCheck { + log.Infof("config ok") + return + } + go signalHandler() for name, rlog := range conf.ReqLog {