fix data race in CertificateReloader with RWMutex
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/urfave/negroni"
|
"github.com/urfave/negroni"
|
||||||
@@ -145,6 +146,7 @@ func redirectHttpToHttps() {
|
|||||||
type CertificateReloader struct {
|
type CertificateReloader struct {
|
||||||
CertificateFilePath string
|
CertificateFilePath string
|
||||||
KeyFilePath string
|
KeyFilePath string
|
||||||
|
mu sync.RWMutex
|
||||||
certificate *tls.Certificate
|
certificate *tls.Certificate
|
||||||
lastUpdatedAt time.Time
|
lastUpdatedAt time.Time
|
||||||
}
|
}
|
||||||
@@ -155,16 +157,27 @@ func (cr *CertificateReloader) GetCertificate(*tls.ClientHelloInfo) (*tls.Certif
|
|||||||
return nil, fmt.Errorf("failed checking key file modification time: %w", err)
|
return nil, fmt.Errorf("failed checking key file modification time: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cr.certificate == nil || stat.ModTime().After(cr.lastUpdatedAt) {
|
cr.mu.RLock()
|
||||||
pair, err := tls.LoadX509KeyPair(cr.CertificateFilePath, cr.KeyFilePath)
|
if cr.certificate != nil && !stat.ModTime().After(cr.lastUpdatedAt) {
|
||||||
if err != nil {
|
defer cr.mu.RUnlock()
|
||||||
return nil, fmt.Errorf("failed loading tls key pair: %w", err)
|
return cr.certificate, nil
|
||||||
}
|
}
|
||||||
|
cr.mu.RUnlock()
|
||||||
|
|
||||||
cr.certificate = &pair
|
cr.mu.Lock()
|
||||||
cr.lastUpdatedAt = stat.ModTime()
|
defer cr.mu.Unlock()
|
||||||
|
|
||||||
|
if cr.certificate != nil && !stat.ModTime().After(cr.lastUpdatedAt) {
|
||||||
|
return cr.certificate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair, err := tls.LoadX509KeyPair(cr.CertificateFilePath, cr.KeyFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed loading tls key pair: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cr.certificate = &pair
|
||||||
|
cr.lastUpdatedAt = stat.ModTime()
|
||||||
return cr.certificate, nil
|
return cr.certificate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user