1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
package errors
import (
"log"
"os"
"path/filepath"
"strconv"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver"
)
// setup configures a new errors middleware instance.
func setup(c *caddy.Controller) error {
handler, err := errorsParse(c)
if err != nil {
return err
}
handler.Log.Attach(c)
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
handler.Next = next
return handler
})
return nil
}
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),
Log: &httpserver.Logger{},
}
cfg := httpserver.GetConfig(c)
optionalBlock := func() error {
for c.NextBlock() {
what := c.Val()
if !c.NextArg() {
return c.ArgErr()
}
where := c.Val()
if httpserver.IsLogRollerSubdirective(what) {
var err error
err = httpserver.ParseRoller(handler.Log.Roller, what, where)
if err != nil {
return err
}
} else {
// Error page; ensure it exists
if !filepath.IsAbs(where) {
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 c.Errf("Duplicate status code entry: %s", what)
}
handler.GenericErrorPage = where
} else {
whatInt, err := strconv.Atoi(what)
if err != nil {
return c.Err("Expecting a numeric status code or '*', got '" + what + "'")
}
if _, exists := handler.ErrorPages[whatInt]; exists {
return c.Errf("Duplicate status code entry: %s", what)
}
handler.ErrorPages[whatInt] = where
}
}
}
return nil
}
for c.Next() {
// weird hack to avoid having the handler values overwritten.
if c.Val() == "}" {
continue
}
args := c.RemainingArgs()
if len(args) == 1 {
switch args[0] {
case "visible":
handler.Debug = true
default:
handler.Log.Output = args[0]
handler.Log.Roller = httpserver.DefaultLogRoller()
}
}
// Configuration may be in a block
err := optionalBlock()
if err != nil {
return handler, err
}
}
return handler, nil
}
|