1package serve23import (4 "crypto/tls"5 "sync"67 "charm.land/log/v2"8)910// CertReloader is responsible for reloading TLS certificates when a SIGHUP signal is received.11type CertReloader struct {12 certMu sync.RWMutex13 cert *tls.Certificate14 certPath string15 keyPath string16}1718// NewCertReloader creates a new CertReloader that watches for SIGHUP signals.19func NewCertReloader(certPath, keyPath string, logger *log.Logger) (*CertReloader, error) {20 reloader := &CertReloader{21 certPath: certPath,22 keyPath: keyPath,23 }2425 cert, err := tls.LoadX509KeyPair(certPath, keyPath)26 if err != nil {27 return nil, err28 }29 reloader.cert = &cert3031 return reloader, nil32}3334// Reload attempts to reload the certificate and key.35func (cr *CertReloader) Reload() error {36 newCert, err := tls.LoadX509KeyPair(cr.certPath, cr.keyPath)37 if err != nil {38 return err39 }4041 cr.certMu.Lock()42 defer cr.certMu.Unlock()43 cr.cert = &newCert44 return nil45}4647// GetCertificateFunc returns a function that can be used with tls.Config.GetCertificate.48func (cr *CertReloader) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error) {49 return func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {50 cr.certMu.RLock()51 defer cr.certMu.RUnlock()52 return cr.cert, nil53 }54}