summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-04-29 09:22:00 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-04-29 09:22:00 -0600
commit5859cd8dad32fdd7ea55daa5e4377e273fb97a3e (patch)
tree7237ca3c4c1de7f00ca508306b9ef7e427b5553c
parent43961b542b077f99f78d64629348b9300d3cd4a3 (diff)
Instantiate apps that are needed but not explicitly configured
-rw-r--r--caddy.go18
-rw-r--r--modules.go9
-rw-r--r--modules/caddyhttp/caddyhttp.go30
-rw-r--r--modules/caddytls/connpolicy.go6
4 files changed, 44 insertions, 19 deletions
diff --git a/caddy.go b/caddy.go
index 62b12b6..2aa0c6a 100644
--- a/caddy.go
+++ b/caddy.go
@@ -238,11 +238,19 @@ type Handle struct {
current *Config
}
-// App returns the configured app named name.
-// A nil value is returned if no app with that
-// name is currently configured.
-func (h Handle) App(name string) interface{} {
- return h.current.apps[name]
+// App returns the configured app named name. If no app with
+// that name is currently configured, a new empty one will be
+// instantiated. (The app module must still be plugged in.)
+func (h Handle) App(name string) (interface{}, error) {
+ if app, ok := h.current.apps[name]; ok {
+ return app, nil
+ }
+ modVal, err := LoadModule(name, nil)
+ if err != nil {
+ return nil, fmt.Errorf("instantiating new module %s: %v", name, err)
+ }
+ h.current.apps[name] = modVal.(App)
+ return modVal, nil
}
// GetStorage returns the configured Caddy storage implementation.
diff --git a/modules.go b/modules.go
index 5a4e69f..6afa6fb 100644
--- a/modules.go
+++ b/modules.go
@@ -171,9 +171,12 @@ func LoadModule(name string, rawMsg json.RawMessage) (interface{}, error) {
val = reflect.New(rv.Type()).Elem().Addr().Interface()
}
- err = json.Unmarshal(rawMsg, &val)
- if err != nil {
- return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err)
+ // fill in its config only if there is a config to fill in
+ if len(rawMsg) > 0 {
+ err = json.Unmarshal(rawMsg, &val)
+ if err != nil {
+ return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err)
+ }
}
if prov, ok := val.(Provisioner); ok {
diff --git a/modules/caddyhttp/caddyhttp.go b/modules/caddyhttp/caddyhttp.go
index 437e48f..de62b79 100644
--- a/modules/caddyhttp/caddyhttp.go
+++ b/modules/caddyhttp/caddyhttp.go
@@ -111,7 +111,11 @@ func (hc *httpModuleConfig) Stop() error {
}
func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
- tlsApp := handle.App("tls").(*caddytls.TLS)
+ tlsAppIface, err := handle.App("tls")
+ if err != nil {
+ return fmt.Errorf("getting tls app: %v", err)
+ }
+ tlsApp := tlsAppIface.(*caddytls.TLS)
for srvName, srv := range hc.Servers {
srv.tlsApp = tlsApp
@@ -120,6 +124,7 @@ func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
continue
}
+ // find all qualifying domain names, de-duplicated
domainSet := make(map[string]struct{})
for _, route := range srv.Routes {
for _, m := range route.matchers {
@@ -133,21 +138,26 @@ func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
}
}
}
- var domains []string
- for d := range domainSet {
- domains = append(domains, d)
- }
- if len(domains) > 0 {
+
+ if len(domainSet) > 0 {
+ // marshal the domains into a slice
+ var domains []string
+ for d := range domainSet {
+ domains = append(domains, d)
+ }
+
+ // manage their certificates
err := tlsApp.Manage(domains)
if err != nil {
return fmt.Errorf("%s: managing certificate for %s: %s", srvName, domains, err)
}
- // TODO: Connection policies... redirects... man...
+
+ // tell the server to use TLS
srv.TLSConnPolicies = caddytls.ConnectionPolicies{
- {
- ALPN: defaultALPN,
- },
+ {ALPN: defaultALPN},
}
+
+ // TODO: create HTTP->HTTPS redirects
}
}
diff --git a/modules/caddytls/connpolicy.go b/modules/caddytls/connpolicy.go
index 9400034..a085fa3 100644
--- a/modules/caddytls/connpolicy.go
+++ b/modules/caddytls/connpolicy.go
@@ -75,7 +75,11 @@ type ConnectionPolicy struct {
}
func (cp *ConnectionPolicy) buildStandardTLSConfig(handle caddy2.Handle) error {
- tlsApp := handle.App("tls").(*TLS)
+ tlsAppIface, err := handle.App("tls")
+ if err != nil {
+ return fmt.Errorf("getting tls app: %v", err)
+ }
+ tlsApp := tlsAppIface.(*TLS)
cfg := &tls.Config{
NextProtos: cp.ALPN,