mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Merge branch 'master' into log-request-body
This commit is contained in:
commit
8e8e2f596d
6 changed files with 90 additions and 4 deletions
23
caddy.go
23
caddy.go
|
@ -50,6 +50,14 @@ var (
|
|||
// was started as part of an upgrade, where a parent
|
||||
// Caddy process started this one.
|
||||
isUpgrade bool
|
||||
|
||||
// started will be set to true when the first
|
||||
// instance is started; it never gets set to
|
||||
// false after that.
|
||||
started bool
|
||||
|
||||
// mu protects the variables 'isUpgrade' and 'started'.
|
||||
mu sync.Mutex
|
||||
)
|
||||
|
||||
// Instance contains the state of servers created as a result of
|
||||
|
@ -497,6 +505,10 @@ func startWithListenerFds(cdyfile Input, inst *Instance, restartFds map[string]r
|
|||
}
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
started = true
|
||||
mu.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -737,9 +749,20 @@ func Upgrade() error {
|
|||
// where a parent caddy process spawned this one to ugprade
|
||||
// the binary.
|
||||
func IsUpgrade() bool {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return isUpgrade
|
||||
}
|
||||
|
||||
// Started returns true if at least one instance has been
|
||||
// started by this package. It never gets reset to false
|
||||
// once it is set to true.
|
||||
func Started() bool {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return started
|
||||
}
|
||||
|
||||
// CaddyfileInput represents a Caddyfile as input
|
||||
// and is simply a convenient way to implement
|
||||
// the Input interface.
|
||||
|
|
|
@ -10,7 +10,9 @@ import (
|
|||
)
|
||||
|
||||
func activateHTTPS(cctx caddy.Context) error {
|
||||
if !caddy.Quiet {
|
||||
operatorPresent := !caddy.Started()
|
||||
|
||||
if !caddy.Quiet && operatorPresent {
|
||||
fmt.Print("Activating privacy features...")
|
||||
}
|
||||
|
||||
|
@ -21,7 +23,7 @@ func activateHTTPS(cctx caddy.Context) error {
|
|||
|
||||
// place certificates and keys on disk
|
||||
for _, c := range ctx.siteConfigs {
|
||||
err := c.TLS.ObtainCert(true)
|
||||
err := c.TLS.ObtainCert(operatorPresent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -44,9 +46,10 @@ func activateHTTPS(cctx caddy.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if !caddy.Quiet {
|
||||
if !caddy.Quiet && operatorPresent {
|
||||
fmt.Println(" done.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -144,9 +144,11 @@ var newACMEClient = func(config *Config, allowPrompts bool) (*ACMEClient, error)
|
|||
func (c *ACMEClient) Obtain(names []string) error {
|
||||
Attempts:
|
||||
for attempts := 0; attempts < 2; attempts++ {
|
||||
namesObtaining.Add(names)
|
||||
acmeMu.Lock()
|
||||
certificate, failures := c.ObtainCertificate(names, true, nil)
|
||||
acmeMu.Unlock()
|
||||
namesObtaining.Remove(names)
|
||||
if len(failures) > 0 {
|
||||
// Error - try to fix it or report it to the user and abort
|
||||
var errMsg string // we'll combine all the failures into a single error message
|
||||
|
@ -234,9 +236,11 @@ func (c *ACMEClient) Renew(name string) error {
|
|||
var newCertMeta acme.CertificateResource
|
||||
var success bool
|
||||
for attempts := 0; attempts < 2; attempts++ {
|
||||
namesObtaining.Add([]string{name})
|
||||
acmeMu.Lock()
|
||||
newCertMeta, err = c.RenewCertificate(certMeta, true)
|
||||
acmeMu.Unlock()
|
||||
namesObtaining.Remove([]string{name})
|
||||
if err == nil {
|
||||
success = true
|
||||
break
|
||||
|
@ -294,3 +298,47 @@ func (c *ACMEClient) Revoke(name string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// namesObtaining is a set of hostnames with thread-safe
|
||||
// methods. A name should be in this set only while this
|
||||
// package is in the process of obtaining a certificate
|
||||
// for the name. ACME challenges that are received for
|
||||
// names which are not in this set were not initiated by
|
||||
// this package and probably should not be handled by
|
||||
// this package.
|
||||
var namesObtaining = nameCoordinator{names: make(map[string]struct{})}
|
||||
|
||||
type nameCoordinator struct {
|
||||
names map[string]struct{}
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// Add adds names to c. It is safe for concurrent use.
|
||||
func (c *nameCoordinator) Add(names []string) {
|
||||
c.mu.Lock()
|
||||
for _, name := range names {
|
||||
c.names[strings.ToLower(name)] = struct{}{}
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// Remove removes names from c. It is safe for concurrent use.
|
||||
func (c *nameCoordinator) Remove(names []string) {
|
||||
c.mu.Lock()
|
||||
for _, name := range names {
|
||||
delete(c.names, strings.ToLower(name))
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// Has returns true if c has name. It is safe for concurrent use.
|
||||
func (c *nameCoordinator) Has(name string) bool {
|
||||
hostname, _, err := net.SplitHostPort(name)
|
||||
if err != nil {
|
||||
hostname = name
|
||||
}
|
||||
c.mu.RLock()
|
||||
_, ok := c.names[strings.ToLower(hostname)]
|
||||
c.mu.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
|
|
@ -214,9 +214,11 @@ func (c *Config) renewCertName(name string, allowPrompts bool) error {
|
|||
var newCertMeta acme.CertificateResource
|
||||
var success bool
|
||||
for attempts := 0; attempts < 2; attempts++ {
|
||||
namesObtaining.Add([]string{name})
|
||||
acmeMu.Lock()
|
||||
newCertMeta, err = client.RenewCertificate(certMeta, true)
|
||||
acmeMu.Unlock()
|
||||
namesObtaining.Remove([]string{name})
|
||||
if err == nil {
|
||||
success = true
|
||||
break
|
||||
|
|
|
@ -19,6 +19,9 @@ func HTTPChallengeHandler(w http.ResponseWriter, r *http.Request, altPort string
|
|||
if !strings.HasPrefix(r.URL.Path, challengeBasePath) {
|
||||
return false
|
||||
}
|
||||
if !namesObtaining.Has(r.Host) {
|
||||
return false
|
||||
}
|
||||
|
||||
scheme := "http"
|
||||
if r.TLS != nil {
|
||||
|
|
|
@ -8,13 +8,17 @@ import (
|
|||
)
|
||||
|
||||
func TestHTTPChallengeHandlerNoOp(t *testing.T) {
|
||||
// try base paths that aren't handled by this handler
|
||||
namesObtaining.Add([]string{"localhost"})
|
||||
|
||||
// try base paths and host names that aren't
|
||||
// handled by this handler
|
||||
for _, url := range []string{
|
||||
"http://localhost/",
|
||||
"http://localhost/foo.html",
|
||||
"http://localhost/.git",
|
||||
"http://localhost/.well-known/",
|
||||
"http://localhost/.well-known/acme-challenging",
|
||||
"http://other/.well-known/acme-challenge/foo",
|
||||
} {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
|
@ -46,6 +50,9 @@ func TestHTTPChallengeHandlerSuccess(t *testing.T) {
|
|||
}
|
||||
ts.Listener = ln
|
||||
|
||||
// Tell this package that we are handling a challenge for 127.0.0.1
|
||||
namesObtaining.Add([]string{"127.0.0.1"})
|
||||
|
||||
// Start our engines and run the test
|
||||
ts.Start()
|
||||
defer ts.Close()
|
||||
|
|
Loading…
Reference in a new issue