Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
Some minor updates, and get rid of OnLoad/OnUnload
Matthew Holt committed
May 16, 2019 at 11:46 UTC
ff5b4639d597203f8aec43e5eae8fe3774976d32
7 files changed
+20
-107
caddy.go
+1
-53
@@ -100,33 +100,6 @@ func Run(cfg *Config) error {
100
}
101
}()
102
103
- // OnLoad
104
- err = func() error {
105
- for modName, instances := range moduleInstances {
106
- mod, err := GetModule(modName)
107
- if err != nil {
108
- return err
109
- }
110
- if mod.OnLoad != nil {
111
- var priorState interface{}
112
- if oldCfg != nil {
113
- priorState = oldCfg.moduleStates[modName]
114
- }
115
- modState, err := mod.OnLoad(instances, priorState)
116
- if err != nil {
117
- return fmt.Errorf("module OnLoad: %s: %v", modName, err)
118
- }
119
- if modState != nil {
120
- cfg.moduleStates[modName] = modState
121
- }
122
- }
123
- }
124
- return nil
125
- }()
126
- if err != nil {
127
- return err
128
- }
129
-
103
// Start
104
err = func() error {
105
h := Handle{cfg}
@@ -158,31 +131,6 @@ func Run(cfg *Config) error {
131
}
132
}
133
161
- // OnUnload
162
- err = func() error {
163
- for modName := range oldModuleInstances {
164
- mod, err := GetModule(modName)
165
- if err != nil {
166
- return err
167
- }
168
- if mod.OnUnload != nil {
169
- var unloadingState interface{}
170
- if oldCfg != nil {
171
- unloadingState = oldCfg.moduleStates[modName]
172
- }
173
- err := mod.OnUnload(unloadingState)
174
- if err != nil {
175
- log.Printf("[ERROR] module OnUnload: %s: %v", modName, err)
176
- continue
177
- }
178
- }
179
- }
180
- return nil
181
- }()
182
- if err != nil {
183
- return err
184
- }
185
-
134
// shut down listeners that are no longer being used
135
err = func() error {
136
listenersMu.Lock()
@@ -240,7 +188,7 @@ type Handle struct {
188
189
// App returns the configured app named name. If no app with
190
// that name is currently configured, a new empty one will be
243
-// instantiated. (The app module must still be plugged in.)
191
+// instantiated. (The app module must still be registered.)
192
func (h Handle) App(name string) (interface{}, error) {
193
if app, ok := h.current.apps[name]; ok {
194
return app, nil
modules.go
+3
-21
@@ -22,27 +22,6 @@ type Module struct {
22
// It must return a pointer; if not, it
23
// is converted into one.
24
New func() (interface{}, error)
25
-
26
- // OnLoad is invoked after all module
27
- // instances ave been loaded. It receives
28
- // pointers to each instance of this
29
- // module, and any state from a previous
30
- // running configuration, which may be
31
- // nil.
32
- //
33
- // If this module is to carry "global"
34
- // state between all instances through
35
- // reloads, you might find it helpful
36
- // to return it.
37
- // TODO: Is this really better/safer than a global variable?
38
- OnLoad func(instances []interface{}, priorState interface{}) (newState interface{}, err error)
39
-
40
- // OnUnload is called after all module
41
- // instances have been stopped, possibly
42
- // in favor of a new configuration. It
43
- // receives the state given by OnLoad (if
44
- // any).
45
- OnUnload func(state interface{}) error
25
}
26
27
func (m Module) String() string { return m.Name }
@@ -53,6 +32,9 @@ func RegisterModule(mod Module) error {
32
if mod.Name == "caddy" {
33
return fmt.Errorf("modules cannot be named 'caddy'")
34
}
35
+ if strings.HasPrefix(mod.Name, "caddy.") {
36
+ return fmt.Errorf("modules cannot be namespaced in 'caddy'")
37
+ }
38
39
modulesMu.Lock()
40
defer modulesMu.Unlock()
modules/caddyhttp/caddylog/log.go
-18
@@ -13,24 +13,6 @@ func init() {
13
caddy2.RegisterModule(caddy2.Module{
14
Name: "http.middleware.log",
15
New: func() (interface{}, error) { return new(Log), nil },
16
- // TODO: Examples of OnLoad and OnUnload.
17
- OnLoad: func(instances []interface{}, priorState interface{}) (interface{}, error) {
18
- var counter int
19
- if priorState != nil {
20
- counter = priorState.(int)
21
- }
22
- counter++
23
- for _, inst := range instances {
24
- logInst := inst.(*Log)
25
- logInst.counter = counter
26
- }
27
- log.Println("State is now:", counter)
28
- return counter, nil
29
- },
30
- OnUnload: func(state interface{}) error {
31
- log.Println("Closing log files, state:", state)
32
- return nil
33
- },
16
})
17
}
18
modules/caddyhttp/matchers.go
+2
-2
@@ -233,14 +233,14 @@ func (mre *matchRegexp) match(input string, repl *Replacer, scope string) bool {
233
234
// save all capture groups, first by index
235
for i, match := range matches {
236
- key := fmt.Sprintf("http.matchers.%s.%s.%d", scope, mre.Name, i)
236
+ key := fmt.Sprintf("matchers.%s.%s.%d", scope, mre.Name, i)
237
repl.Map(key, match)
238
}
239
240
// then by name
241
for i, name := range mre.compiled.SubexpNames() {
242
if i != 0 && name != "" {
243
- key := fmt.Sprintf("http.matchers.%s.%s.%s", scope, mre.Name, name)
243
+ key := fmt.Sprintf("matchers.%s.%s.%s", scope, mre.Name, name)
244
repl.Map(key, matches[i])
245
}
246
}
modules/caddyhttp/matchers_test.go
+4
-4
@@ -217,10 +217,10 @@ func TestPathREMatcher(t *testing.T) {
217
}
218
219
for key, expectVal := range tc.expectRepl {
220
- placeholder := fmt.Sprintf("{http.matchers.path_regexp.%s}", key)
220
+ placeholder := fmt.Sprintf("{matchers.path_regexp.%s}", key)
221
actualVal := repl.Replace(placeholder, "<empty>")
222
if actualVal != expectVal {
223
- t.Errorf("Test %d [%v]: Expected placeholder {http.matchers.path_regexp.%s} to be '%s' but got '%s'",
223
+ t.Errorf("Test %d [%v]: Expected placeholder {matchers.path_regexp.%s} to be '%s' but got '%s'",
224
i, tc.match.Pattern, key, expectVal, actualVal)
225
continue
226
}
@@ -334,10 +334,10 @@ func TestHeaderREMatcher(t *testing.T) {
334
}
335
336
for key, expectVal := range tc.expectRepl {
337
- placeholder := fmt.Sprintf("{http.matchers.header_regexp.%s}", key)
337
+ placeholder := fmt.Sprintf("{matchers.header_regexp.%s}", key)
338
actualVal := repl.Replace(placeholder, "<empty>")
339
if actualVal != expectVal {
340
- t.Errorf("Test %d [%v]: Expected placeholder {http.matchers.header_regexp.%s} to be '%s' but got '%s'",
340
+ t.Errorf("Test %d [%v]: Expected placeholder {matchers.header_regexp.%s} to be '%s' but got '%s'",
341
i, tc.match, key, expectVal, actualVal)
342
continue
343
}
modules/caddyhttp/replacer.go
+9
-8
@@ -93,19 +93,20 @@ func (r *Replacer) defaults() map[string]string {
93
m["request.uri"] = r.req.URL.RequestURI()
94
m["request.uri.path"] = r.req.URL.Path
95
96
- // TODO: why should header fields, cookies, and query params get special treatment like this?
97
- // maybe they should be scoped by words like "request.header." just like everything else.
96
for field, vals := range r.req.Header {
99
- m[">"+strings.ToLower(field)] = strings.Join(vals, ",")
100
- }
101
- for field, vals := range r.resp.Header() {
102
- m["<"+strings.ToLower(field)] = strings.Join(vals, ",")
97
+ m["request.header."+strings.ToLower(field)] = strings.Join(vals, ",")
98
}
99
for _, cookie := range r.req.Cookies() {
105
- m["~"+cookie.Name] = cookie.Value
100
+ m["request.cookie."+cookie.Name] = cookie.Value
101
}
102
for param, vals := range r.req.URL.Query() {
108
- m["?"+param] = strings.Join(vals, ",")
103
+ m["request.uri.query."+param] = strings.Join(vals, ",")
104
+ }
105
+ }
106
+
107
+ if r.resp != nil {
108
+ for field, vals := range r.resp.Header() {
109
+ m["response.header."+strings.ToLower(field)] = strings.Join(vals, ",")
110
}
111
}
112
modules/caddyhttp/staticresp.go
+1
-1
@@ -25,7 +25,7 @@ type Static struct {
25
func (s Static) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
26
repl := r.Context().Value(ReplacerCtxKey).(*Replacer)
27
28
- // close the connection
28
+ // close the connection after responding
29
r.Close = s.Close
30
31
// set all headers, with replacements