diff --git a/caddyhttp/httpserver/plugin.go b/caddyhttp/httpserver/plugin.go index a62baf5d5..2e1fa5e6a 100644 --- a/caddyhttp/httpserver/plugin.go +++ b/caddyhttp/httpserver/plugin.go @@ -190,7 +190,10 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd // Make our caddytls.Config, which has a pointer to the // instance's certificate cache and enough information // to use automatic HTTPS when the time comes - caddytlsConfig := caddytls.NewConfig(h.instance) + caddytlsConfig, err := caddytls.NewConfig(h.instance) + if err != nil { + return nil, fmt.Errorf("creating new caddytls configuration: %v", err) + } caddytlsConfig.Hostname = addr.Host caddytlsConfig.Manager.AltHTTPPort = altHTTPPort caddytlsConfig.Manager.AltTLSALPNPort = altTLSALPNPort diff --git a/caddytls/config.go b/caddytls/config.go index c8318b929..214eb73b8 100644 --- a/caddytls/config.go +++ b/caddytls/config.go @@ -19,6 +19,8 @@ import ( "crypto/x509" "fmt" "io/ioutil" + "os" + "sync/atomic" "github.com/xenolf/lego/challenge/tlsalpn01" @@ -95,11 +97,31 @@ type Config struct { // NewConfig returns a new Config with a pointer to the instance's // certificate cache. You will usually need to set other fields on // the returned Config for successful practical use. -func NewConfig(inst *caddy.Instance) *Config { +func NewConfig(inst *caddy.Instance) (*Config, error) { inst.StorageMu.RLock() certCache, ok := inst.Storage[CertCacheInstStorageKey].(*certmagic.Cache) inst.StorageMu.RUnlock() if !ok || certCache == nil { + // set up the clustering plugin, if there is one (and there should always + // be one since this tls plugin requires it) -- this should be done exactly + // once, but we can't do it during init while plugins are still registering, + // so do it as soon as we run a setup) + if atomic.CompareAndSwapInt32(&clusterPluginSetup, 0, 1) { + clusterPluginName := os.Getenv("CADDY_CLUSTERING") + if clusterPluginName == "" { + clusterPluginName = "file" // name of default storage plugin + } + clusterFn, ok := clusterProviders[clusterPluginName] + if ok { + storage, err := clusterFn() + if err != nil { + return nil, fmt.Errorf("constructing cluster plugin %s: %v", clusterPluginName, err) + } + certmagic.DefaultStorage = storage + } else { + return nil, fmt.Errorf("unrecognized cluster plugin (was it included in the Caddy build?): %s", clusterPluginName) + } + } certCache = certmagic.NewCache(certmagic.DefaultStorage) inst.OnShutdown = append(inst.OnShutdown, func() error { certCache.Stop() @@ -111,7 +133,7 @@ func NewConfig(inst *caddy.Instance) *Config { } return &Config{ Manager: certmagic.NewWithCache(certCache, certmagic.Config{}), - } + }, nil } // buildStandardTLSConfig converts cfg (*caddytls.Config) to a *tls.Config @@ -519,6 +541,8 @@ var defaultCurves = []tls.CurveID{ tls.CurveP256, } +var clusterPluginSetup int32 // access atomically + // CertCacheInstStorageKey is the name of the key for // accessing the certificate storage on the *caddy.Instance. const CertCacheInstStorageKey = "tls_cert_cache" diff --git a/caddytls/setup.go b/caddytls/setup.go index e76732385..b8f1af3a4 100644 --- a/caddytls/setup.go +++ b/caddytls/setup.go @@ -26,7 +26,6 @@ import ( "path/filepath" "strconv" "strings" - "sync/atomic" "github.com/mholt/caddy" "github.com/mholt/caddy/telemetry" @@ -44,27 +43,6 @@ func init() { // are specified by the user in the config file. All the automatic HTTPS // stuff comes later outside of this function. func setupTLS(c *caddy.Controller) error { - // set up the clustering plugin, if there is one (and there should always - // be one since this tls plugin requires it) -- this should be done exactly - // once, but we can't do it during init while plugins are still registering, - // so do it as soon as we run a setup) - if atomic.CompareAndSwapInt32(&clusterPluginSetup, 0, 1) { - clusterPluginName := os.Getenv("CADDY_CLUSTERING") - if clusterPluginName == "" { - clusterPluginName = "file" // name of default storage plugin - } - clusterFn, ok := clusterProviders[clusterPluginName] - if ok { - storage, err := clusterFn() - if err != nil { - return fmt.Errorf("constructing cluster plugin %s: %v", clusterPluginName, err) - } - certmagic.DefaultStorage = storage - } else { - return fmt.Errorf("unrecognized cluster plugin (was it included in the Caddy build?): %s", clusterPluginName) - } - } - configGetter, ok := configGetters[c.ServerType()] if !ok { return fmt.Errorf("no caddytls.ConfigGetter for %s server type; must call RegisterConfigGetter", c.ServerType()) @@ -445,5 +423,3 @@ func loadCertsInDir(cfg *Config, c *caddy.Controller, dir string) error { func constructDefaultClusterPlugin() (certmagic.Storage, error) { return &certmagic.FileStorage{Path: caddy.AssetsPath()}, nil } - -var clusterPluginSetup int32 // access atomically