forked from rekby/lets-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
acme-client-pool.go
74 lines (64 loc) · 1.73 KB
/
acme-client-pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package main
import (
"context"
"crypto"
"github.com/Sirupsen/logrus"
"github.com/hlandau/acme/acmeapi"
"sync/atomic"
"time"
)
const (
ACMECLIENT_ACCEPT_RULES_INTERVAL = time.Hour * 24 // Accept rules once per day
)
type acmeClientPool struct {
privateKey crypto.PrivateKey
serverAddress string
ch chan bool
rulesAcceptNextTime atomic.Value
}
func NewAcmeClientPool(maxCount int, key crypto.PrivateKey, serverAddress string) *acmeClientPool {
res := &acmeClientPool{
privateKey: key,
serverAddress: serverAddress,
}
res.ch = make(chan bool, maxCount)
for i := 0; i < maxCount; i++ {
res.ch <- false
}
return res
}
func (pool *acmeClientPool) Get(ctx context.Context) (*acmeapi.Client, error) {
logrus.Debug("Get acme client from pool")
<-pool.ch
client := &acmeapi.Client{
AccountKey: pool.privateKey,
DirectoryURL: pool.serverAddress,
}
rulesAcceptNextTime, _ := pool.rulesAcceptNextTime.Load().(time.Time)
if rulesAcceptNextTime.Before(time.Now()) {
reg := &acmeapi.Registration{}
for {
// repeat until success or context timeout
reg.AgreementURI = reg.LatestAgreementURI
if reg.AgreementURI != "" {
logrus.Debug("Try agree with terms:", reg.LatestAgreementURI)
}
err := client.UpsertRegistration(reg, ctx)
if reg.AgreementURI != "" && err == nil {
nextTime := time.Now().Add(ACMECLIENT_ACCEPT_RULES_INTERVAL)
pool.rulesAcceptNextTime.Store(nextTime)
logrus.Infof("Agree with terms: %v. Next agree: %v", reg.LatestAgreementURI, nextTime)
break
}
if ctx.Err() != nil {
pool.ch <- false
return nil, err
}
}
}
return client, nil
}
func (pool *acmeClientPool) Put(*acmeapi.Client) {
logrus.Debug("Put acme client in pool")
pool.ch <- false
}