Instantiate apps that are needed but not explicitly configured

This commit is contained in:
Matthew Holt 2019-04-29 09:22:00 -06:00
parent 43961b542b
commit 5859cd8dad
4 changed files with 44 additions and 19 deletions

View File

@ -238,11 +238,19 @@ type Handle struct {
current *Config current *Config
} }
// App returns the configured app named name. // App returns the configured app named name. If no app with
// A nil value is returned if no app with that // that name is currently configured, a new empty one will be
// name is currently configured. // instantiated. (The app module must still be plugged in.)
func (h Handle) App(name string) interface{} { func (h Handle) App(name string) (interface{}, error) {
return h.current.apps[name] 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. // GetStorage returns the configured Caddy storage implementation.

View File

@ -171,10 +171,13 @@ func LoadModule(name string, rawMsg json.RawMessage) (interface{}, error) {
val = reflect.New(rv.Type()).Elem().Addr().Interface() val = reflect.New(rv.Type()).Elem().Addr().Interface()
} }
// fill in its config only if there is a config to fill in
if len(rawMsg) > 0 {
err = json.Unmarshal(rawMsg, &val) err = json.Unmarshal(rawMsg, &val)
if err != nil { if err != nil {
return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err) return nil, fmt.Errorf("decoding module config: %s: %v", mod.Name, err)
} }
}
if prov, ok := val.(Provisioner); ok { if prov, ok := val.(Provisioner); ok {
err := prov.Provision() err := prov.Provision()

View File

@ -111,7 +111,11 @@ func (hc *httpModuleConfig) Stop() error {
} }
func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) 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 { for srvName, srv := range hc.Servers {
srv.tlsApp = tlsApp srv.tlsApp = tlsApp
@ -120,6 +124,7 @@ func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
continue continue
} }
// find all qualifying domain names, de-duplicated
domainSet := make(map[string]struct{}) domainSet := make(map[string]struct{})
for _, route := range srv.Routes { for _, route := range srv.Routes {
for _, m := range route.matchers { for _, m := range route.matchers {
@ -133,21 +138,26 @@ func (hc *httpModuleConfig) automaticHTTPS(handle caddy2.Handle) error {
} }
} }
} }
if len(domainSet) > 0 {
// marshal the domains into a slice
var domains []string var domains []string
for d := range domainSet { for d := range domainSet {
domains = append(domains, d) domains = append(domains, d)
} }
if len(domains) > 0 {
// manage their certificates
err := tlsApp.Manage(domains) err := tlsApp.Manage(domains)
if err != nil { if err != nil {
return fmt.Errorf("%s: managing certificate for %s: %s", srvName, domains, err) 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{ srv.TLSConnPolicies = caddytls.ConnectionPolicies{
{ {ALPN: defaultALPN},
ALPN: defaultALPN,
},
} }
// TODO: create HTTP->HTTPS redirects
} }
} }

View File

@ -75,7 +75,11 @@ type ConnectionPolicy struct {
} }
func (cp *ConnectionPolicy) buildStandardTLSConfig(handle caddy2.Handle) error { 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{ cfg := &tls.Config{
NextProtos: cp.ALPN, NextProtos: cp.ALPN,