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
Instantiate apps that are needed but not explicitly configured
Matthew Holt committed
Apr 29, 2019 at 09:22 UTC
5859cd8dad32fdd7ea55daa5e4377e273fb97a3e
4 files changed
+44
-19
caddy.go
+13
-5
@@ -238,11 +238,19 @@ type Handle struct {
238
current *Config
239
}
240
241
-// App returns the configured app named name.
242
-// A nil value is returned if no app with that
243
-// name is currently configured.
244
-func (h Handle) App(name string) interface{} {
245
- return h.current.apps[name]
241
+// App returns the configured app named name. If no app with
242
+// that name is currently configured, a new empty one will be
243
+// instantiated. (The app module must still be plugged in.)
244
+func (h Handle) App(name string) (interface{}, error) {
245
+ if app, ok := h.current.apps[name]; ok {
246
+ return app, nil
247
+ }
248
+ modVal, err := LoadModule(name, nil)
249
+ if err != nil {
250
+ return nil, fmt.Errorf("instantiating new module %s: %v", name, err)
251
+ }
252
+ h.current.apps[name] = modVal.(App)
253
+ return modVal, nil
254
}
255
256
// GetStorage returns the configured Caddy storage implementation.
modules.go
+6
-3
@@ -171,9 +171,12 @@ func LoadModule(name string, rawMsg json.RawMessage) (interface{}, error) {
171
val = reflect.New(rv.Type()).Elem().Addr().Interface()
172
}
173
174
- err = json.Unmarshal(rawMsg, &val)
175
- if err != nil {
176
- return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err)
174
+ // fill in its config only if there is a config to fill in
175
+ if len(rawMsg) > 0 {
176
+ err = json.Unmarshal(rawMsg, &val)
177
+ if err != nil {
178
+ return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err)
179
+ }
180
}
181
182
if prov, ok := val.(Provisioner); ok {
modules/caddyhttp/caddyhttp.go
+20
-10
@@ -111,7 +111,11 @@ func (hc *httpModuleConfig) Stop() error {
111
}
112
113
func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
114
- tlsApp := handle.App("tls").(*caddytls.TLS)
114
+ tlsAppIface, err := handle.App("tls")
115
+ if err != nil {
116
+ return fmt.Errorf("getting tls app: %v", err)
117
+ }
118
+ tlsApp := tlsAppIface.(*caddytls.TLS)
119
120
for srvName, srv := range hc.Servers {
121
srv.tlsApp = tlsApp
@@ -120,6 +124,7 @@ func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
124
continue
125
}
126
127
+ // find all qualifying domain names, de-duplicated
128
domainSet := make(map[string]struct{})
129
for _, route := range srv.Routes {
130
for _, m := range route.matchers {
@@ -133,21 +138,26 @@ func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
138
}
139
}
140
}
136
- var domains []string
137
- for d := range domainSet {
138
- domains = append(domains, d)
139
- }
140
- if len(domains) > 0 {
141
+
142
+ if len(domainSet) > 0 {
143
+ // marshal the domains into a slice
144
+ var domains []string
145
+ for d := range domainSet {
146
+ domains = append(domains, d)
147
+ }
148
+
149
+ // manage their certificates
150
err := tlsApp.Manage(domains)
151
if err != nil {
152
return fmt.Errorf("%s: managing certificate for %s: %s", srvName, domains, err)
153
}
145
- // TODO: Connection policies... redirects... man...
154
+
155
+ // tell the server to use TLS
156
srv.TLSConnPolicies = caddytls.ConnectionPolicies{
147
- {
148
- ALPN: defaultALPN,
149
- },
157
+ {ALPN: defaultALPN},
158
}
159
+
160
+ // TODO: create HTTP->HTTPS redirects
161
}
162
}
163
modules/caddytls/connpolicy.go
+5
-1
@@ -75,7 +75,11 @@ type ConnectionPolicy struct {
75
}
76
77
func (cp *ConnectionPolicy) buildStandardTLSConfig(handle caddy2.Handle) error {
78
- tlsApp := handle.App("tls").(*TLS)
78
+ tlsAppIface, err := handle.App("tls")
79
+ if err != nil {
80
+ return fmt.Errorf("getting tls app: %v", err)
81
+ }
82
+ tlsApp := tlsAppIface.(*TLS)
83
84
cfg := &tls.Config{
85
NextProtos: cp.ALPN,