68 lines
1.2 KiB
Go
68 lines
1.2 KiB
Go
|
package utils
|
||
|
|
||
|
import (
|
||
|
"crypto/tls"
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type CertCache struct {
|
||
|
syncLock *sync.RWMutex
|
||
|
certs map[string]*certCacheItem
|
||
|
}
|
||
|
|
||
|
func NewCertCache() *CertCache {
|
||
|
return &CertCache{&sync.RWMutex{}, make(map[string]*certCacheItem)}
|
||
|
}
|
||
|
|
||
|
func (cc *CertCache) Put(domain string, cert *tls.Certificate) {
|
||
|
cc.syncLock.Lock()
|
||
|
a, ok := cc.certs[domain]
|
||
|
if ok {
|
||
|
a.tick.Stop()
|
||
|
close(a.end)
|
||
|
delete(cc.certs, domain)
|
||
|
}
|
||
|
|
||
|
// Set up a ticker and timeout value
|
||
|
i := &certCacheItem{cert, time.NewTicker(time.Minute * 10), make(chan struct{})}
|
||
|
go cc.internalItemTick(domain, i)
|
||
|
cc.certs[domain] = i
|
||
|
cc.syncLock.Unlock()
|
||
|
}
|
||
|
|
||
|
func (cc *CertCache) Get(domain string) (*tls.Certificate, bool) {
|
||
|
cc.syncLock.RLock()
|
||
|
c, ok := cc.certs[domain]
|
||
|
cc.syncLock.RUnlock()
|
||
|
if ok {
|
||
|
return c.cert, ok
|
||
|
}
|
||
|
return nil, false
|
||
|
}
|
||
|
|
||
|
func (cc *CertCache) Del(domain string) {
|
||
|
cc.syncLock.Lock()
|
||
|
a, ok := cc.certs[domain]
|
||
|
if ok {
|
||
|
a.tick.Stop()
|
||
|
close(a.end)
|
||
|
}
|
||
|
delete(cc.certs, domain)
|
||
|
cc.syncLock.Unlock()
|
||
|
}
|
||
|
|
||
|
func (cc *CertCache) internalItemTick(domain string, item *certCacheItem) {
|
||
|
select {
|
||
|
case <-item.tick.C:
|
||
|
cc.Del(domain)
|
||
|
case <-item.end:
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type certCacheItem struct {
|
||
|
cert *tls.Certificate
|
||
|
tick *time.Ticker
|
||
|
end chan struct{}
|
||
|
}
|