func errorsParse(c *caddy.Controller) (*ErrorHandler, error) { // Very important that we make a pointer because the startup // function that opens the log file must have access to the // same instance of the handler, not a copy. handler := &ErrorHandler{ErrorPages: make(map[int]string)} cfg := httpserver.GetConfig(c) optionalBlock := func() (bool, error) { var hadBlock bool for c.NextBlock() { hadBlock = true what := c.Val() if !c.NextArg() { return hadBlock, c.ArgErr() } where := c.Val() if what == "log" { if where == "visible" { handler.Debug = true } else { handler.LogFile = where if c.NextArg() { if c.Val() == "{" { c.IncrNest() logRoller, err := httpserver.ParseRoller(c) if err != nil { return hadBlock, err } handler.LogRoller = logRoller } } } } else { // Error page; ensure it exists where = filepath.Join(cfg.Root, where) f, err := os.Open(where) if err != nil { log.Printf("[WARNING] Unable to open error page '%s': %v", where, err) } f.Close() if what == "*" { if handler.GenericErrorPage != "" { return hadBlock, c.Errf("Duplicate status code entry: %s", what) } handler.GenericErrorPage = where } else { whatInt, err := strconv.Atoi(what) if err != nil { return hadBlock, c.Err("Expecting a numeric status code or '*', got '" + what + "'") } if _, exists := handler.ErrorPages[whatInt]; exists { return hadBlock, c.Errf("Duplicate status code entry: %s", what) } handler.ErrorPages[whatInt] = where } } } return hadBlock, nil } for c.Next() { // weird hack to avoid having the handler values overwritten. if c.Val() == "}" { continue } // Configuration may be in a block hadBlock, err := optionalBlock() if err != nil { return handler, err } // Otherwise, the only argument would be an error log file name or 'visible' if !hadBlock { if c.NextArg() { if c.Val() == "visible" { handler.Debug = true } else { handler.LogFile = c.Val() } } } } return handler, nil }
func logParse(c *caddy.Controller) ([]Rule, error) { var rules []Rule for c.Next() { args := c.RemainingArgs() var logRoller *httpserver.LogRoller if c.NextBlock() { if c.Val() == "rotate" { if c.NextArg() { if c.Val() == "{" { var err error logRoller, err = httpserver.ParseRoller(c) if err != nil { return nil, err } // This part doesn't allow having something after the rotate block if c.Next() { if c.Val() != "}" { return nil, c.ArgErr() } } } } } } if len(args) == 0 { // Nothing specified; use defaults rules = append(rules, Rule{ PathScope: "/", OutputFile: DefaultLogFilename, Format: DefaultLogFormat, Roller: logRoller, }) } else if len(args) == 1 { // Only an output file specified rules = append(rules, Rule{ PathScope: "/", OutputFile: args[0], Format: DefaultLogFormat, Roller: logRoller, }) } else { // Path scope, output file, and maybe a format specified format := DefaultLogFormat if len(args) > 2 { switch args[2] { case "{common}": format = CommonLogFormat case "{combined}": format = CombinedLogFormat default: format = args[2] } } rules = append(rules, Rule{ PathScope: args[0], OutputFile: args[1], Format: format, Roller: logRoller, }) } } return rules, nil }