ACME申请证书时可以设置回调URL

This commit is contained in:
GoEdgeLab
2021-06-24 09:27:39 +08:00
parent 62ae0d67ba
commit 9a61ec4afc
5 changed files with 123 additions and 33 deletions

View File

@@ -39,7 +39,7 @@ func TestRequest_Run_DNS(t *testing.T) {
req := NewRequest(&Task{ req := NewRequest(&Task{
User: user, User: user,
Type: TaskTypeDNS, AuthType: AuthTypeDNS,
DNSProvider: dnsProvider, DNSProvider: dnsProvider,
DNSDomain: "yun4s.cn", DNSDomain: "yun4s.cn",
Domains: []string{"yun4s.cn"}, Domains: []string{"yun4s.cn"},
@@ -75,7 +75,7 @@ func TestRequest_Run_HTTP(t *testing.T) {
req := NewRequest(&Task{ req := NewRequest(&Task{
User: user, User: user,
Type: TaskTypeHTTP, AuthType: AuthTypeHTTP,
Domains: []string{"teaos.cn", "www.teaos.cn", "meloy.cn"}, Domains: []string{"teaos.cn", "www.teaos.cn", "meloy.cn"},
}) })
certData, keyData, err := req.runHTTP() certData, keyData, err := req.runHTTP()

View File

@@ -1,6 +1,7 @@
package acme package acme
import ( import (
"bytes"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/acme" "github.com/TeaOSLab/EdgeAPI/internal/acme"
"github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeAPI/internal/db/models"
@@ -8,13 +9,17 @@ import (
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils" dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients" "github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
"github.com/TeaOSLab/EdgeAPI/internal/errors" "github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
"github.com/go-acme/lego/v4/registration" "github.com/go-acme/lego/v4/registration"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
"net/http"
"time" "time"
) )
@@ -44,7 +49,7 @@ func init() {
}) })
} }
// 启用条目 // EnableACMETask 启用条目
func (this *ACMETaskDAO) EnableACMETask(tx *dbs.Tx, id int64) error { func (this *ACMETaskDAO) EnableACMETask(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx). _, err := this.Query(tx).
Pk(id). Pk(id).
@@ -53,7 +58,7 @@ func (this *ACMETaskDAO) EnableACMETask(tx *dbs.Tx, id int64) error {
return err return err
} }
// 禁用条目 // DisableACMETask 禁用条目
func (this *ACMETaskDAO) DisableACMETask(tx *dbs.Tx, id int64) error { func (this *ACMETaskDAO) DisableACMETask(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx). _, err := this.Query(tx).
Pk(id). Pk(id).
@@ -62,7 +67,7 @@ func (this *ACMETaskDAO) DisableACMETask(tx *dbs.Tx, id int64) error {
return err return err
} }
// 查找启用中的条目 // FindEnabledACMETask 查找启用中的条目
func (this *ACMETaskDAO) FindEnabledACMETask(tx *dbs.Tx, id int64) (*ACMETask, error) { func (this *ACMETaskDAO) FindEnabledACMETask(tx *dbs.Tx, id int64) (*ACMETask, error) {
result, err := this.Query(tx). result, err := this.Query(tx).
Pk(id). Pk(id).
@@ -74,7 +79,7 @@ func (this *ACMETaskDAO) FindEnabledACMETask(tx *dbs.Tx, id int64) (*ACMETask, e
return result.(*ACMETask), err return result.(*ACMETask), err
} }
// 计算某个ACME用户相关的任务数量 // CountACMETasksWithACMEUserId 计算某个ACME用户相关的任务数量
func (this *ACMETaskDAO) CountACMETasksWithACMEUserId(tx *dbs.Tx, acmeUserId int64) (int64, error) { func (this *ACMETaskDAO) CountACMETasksWithACMEUserId(tx *dbs.Tx, acmeUserId int64) (int64, error) {
return this.Query(tx). return this.Query(tx).
State(ACMETaskStateEnabled). State(ACMETaskStateEnabled).
@@ -82,7 +87,7 @@ func (this *ACMETaskDAO) CountACMETasksWithACMEUserId(tx *dbs.Tx, acmeUserId int
Count() Count()
} }
// 计算某个DNS服务商相关的任务数量 // CountACMETasksWithDNSProviderId 计算某个DNS服务商相关的任务数量
func (this *ACMETaskDAO) CountACMETasksWithDNSProviderId(tx *dbs.Tx, dnsProviderId int64) (int64, error) { func (this *ACMETaskDAO) CountACMETasksWithDNSProviderId(tx *dbs.Tx, dnsProviderId int64) (int64, error) {
return this.Query(tx). return this.Query(tx).
State(ACMETaskStateEnabled). State(ACMETaskStateEnabled).
@@ -90,7 +95,7 @@ func (this *ACMETaskDAO) CountACMETasksWithDNSProviderId(tx *dbs.Tx, dnsProvider
Count() Count()
} }
// 停止某个证书相关任务 // DisableAllTasksWithCertId 停止某个证书相关任务
func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) error { func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) error {
_, err := this.Query(tx). _, err := this.Query(tx).
Attr("certId", certId). Attr("certId", certId).
@@ -99,7 +104,7 @@ func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) err
return err return err
} }
// 计算所有任务数量 // CountAllEnabledACMETasks 计算所有任务数量
func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string) (int64, error) { func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string) (int64, error) {
query := dbutils.NewQuery(tx, this, adminId, userId) query := dbutils.NewQuery(tx, this, adminId, userId)
if isAvailable || isExpired || expiringDays > 0 { if isAvailable || isExpired || expiringDays > 0 {
@@ -130,7 +135,7 @@ func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, use
Count() Count()
} }
// 列出单页任务 // ListEnabledACMETasks 列出单页任务
func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, offset int64, size int64) (result []*ACMETask, err error) { func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, offset int64, size int64) (result []*ACMETask, err error) {
query := dbutils.NewQuery(tx, this, adminId, userId) query := dbutils.NewQuery(tx, this, adminId, userId)
if isAvailable || isExpired || expiringDays > 0 { if isAvailable || isExpired || expiringDays > 0 {
@@ -161,8 +166,8 @@ func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId
return return
} }
// 创建任务 // CreateACMETask 创建任务
func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64, authType acme.AuthType, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool) (int64, error) { func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64, authType acme.AuthType, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool, authURL string) (int64, error) {
op := NewACMETaskOperator() op := NewACMETaskOperator()
op.AdminId = adminId op.AdminId = adminId
op.UserId = userId op.UserId = userId
@@ -182,6 +187,7 @@ func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64,
} }
op.AutoRenew = autoRenew op.AutoRenew = autoRenew
op.AuthURL = authURL
op.IsOn = true op.IsOn = true
op.State = ACMETaskStateEnabled op.State = ACMETaskStateEnabled
err := this.Save(tx, op) err := this.Save(tx, op)
@@ -191,8 +197,8 @@ func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64,
return types.Int64(op.Id), nil return types.Int64(op.Id), nil
} }
// 修改任务 // UpdateACMETask 修改任务
func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool) error { func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool, authURL string) error {
if acmeTaskId <= 0 { if acmeTaskId <= 0 {
return errors.New("invalid acmeTaskId") return errors.New("invalid acmeTaskId")
} }
@@ -214,11 +220,12 @@ func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId
} }
op.AutoRenew = autoRenew op.AutoRenew = autoRenew
op.AuthURL = authURL
err := this.Save(tx, op) err := this.Save(tx, op)
return err return err
} }
// 检查权限 // CheckACMETask 检查权限
func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64, acmeTaskId int64) (bool, error) { func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64, acmeTaskId int64) (bool, error) {
return dbutils.NewQuery(tx, this, adminId, userId). return dbutils.NewQuery(tx, this, adminId, userId).
State(ACMETaskStateEnabled). State(ACMETaskStateEnabled).
@@ -226,7 +233,7 @@ func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64,
Exist() Exist()
} }
// 设置任务关联的证书 // UpdateACMETaskCert 设置任务关联的证书
func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int64) error { func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int64) error {
if taskId <= 0 { if taskId <= 0 {
return errors.New("invalid taskId") return errors.New("invalid taskId")
@@ -239,7 +246,7 @@ func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int
return err return err
} }
// 执行任务并记录日志 // RunTask 执行任务并记录日志
func (this *ACMETaskDAO) RunTask(tx *dbs.Tx, taskId int64) (isOk bool, errMsg string, resultCertId int64) { func (this *ACMETaskDAO) RunTask(tx *dbs.Tx, taskId int64) (isOk bool, errMsg string, resultCertId int64) {
isOk, errMsg, resultCertId = this.runTaskWithoutLog(tx, taskId) isOk, errMsg, resultCertId = this.runTaskWithoutLog(tx, taskId)
@@ -350,7 +357,33 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
acmeRequest.OnAuth(func(domain, token, keyAuth string) { acmeRequest.OnAuth(func(domain, token, keyAuth string) {
err := SharedACMEAuthenticationDAO.CreateAuth(tx, taskId, domain, token, keyAuth) err := SharedACMEAuthenticationDAO.CreateAuth(tx, taskId, domain, token, keyAuth)
if err != nil { if err != nil {
logs.Println("[ACME]write authentication to database error: " + err.Error()) remotelogs.Error("ACME", "write authentication to database error: "+err.Error())
} else {
// 调用校验URL
if len(task.AuthURL) > 0 {
authJSON, err := json.Marshal(maps.Map{
"domain": domain,
"token": token,
"key": keyAuth,
})
if err != nil {
remotelogs.Error("ACME", "encode auth data failed: '"+task.AuthURL+"'")
} else {
client := utils.SharedHttpClient(5 * time.Second)
req, err := http.NewRequest(http.MethodPost, task.AuthURL, bytes.NewReader(authJSON))
req.Header.Set("Content-Type", "application/json")
if err != nil {
remotelogs.Error("ACME", "parse auth url failed '"+task.AuthURL+"': "+err.Error())
} else {
resp, err := client.Do(req)
if err != nil {
remotelogs.Error("ACME", "call auth url failed '"+task.AuthURL+"': "+err.Error())
} else {
_ = resp.Body.Close()
}
}
}
}
} }
}) })
certData, keyData, err := acmeRequest.Run() certData, keyData, err := acmeRequest.Run()

View File

@@ -1,6 +1,6 @@
package acme package acme
// ACME任务 // ACMETask ACME任务
type ACMETask struct { type ACMETask struct {
Id uint64 `field:"id"` // ID Id uint64 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID AdminId uint32 `field:"adminId"` // 管理员ID
@@ -15,6 +15,7 @@ type ACMETask struct {
CertId uint64 `field:"certId"` // 生成的证书ID CertId uint64 `field:"certId"` // 生成的证书ID
AutoRenew uint8 `field:"autoRenew"` // 是否自动更新 AutoRenew uint8 `field:"autoRenew"` // 是否自动更新
AuthType string `field:"authType"` // 认证类型 AuthType string `field:"authType"` // 认证类型
AuthURL string `field:"authURL"` // 认证URL
} }
type ACMETaskOperator struct { type ACMETaskOperator struct {
@@ -31,6 +32,7 @@ type ACMETaskOperator struct {
CertId interface{} // 生成的证书ID CertId interface{} // 生成的证书ID
AutoRenew interface{} // 是否自动更新 AutoRenew interface{} // 是否自动更新
AuthType interface{} // 认证类型 AuthType interface{} // 认证类型
AuthURL interface{} // 认证URL
} }
func NewACMETaskOperator() *ACMETaskOperator { func NewACMETaskOperator() *ACMETaskOperator {

View File

@@ -10,12 +10,12 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
) )
// ACME任务相关服务 // ACMETaskService ACME任务相关服务
type ACMETaskService struct { type ACMETaskService struct {
BaseService BaseService
} }
// 计算某个ACME用户相关的任务数量 // CountAllEnabledACMETasksWithACMEUserId 计算某个ACME用户相关的任务数量
func (this *ACMETaskService) CountAllEnabledACMETasksWithACMEUserId(ctx context.Context, req *pb.CountAllEnabledACMETasksWithACMEUserIdRequest) (*pb.RPCCountResponse, error) { func (this *ACMETaskService) CountAllEnabledACMETasksWithACMEUserId(ctx context.Context, req *pb.CountAllEnabledACMETasksWithACMEUserIdRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, 0) _, _, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -33,7 +33,7 @@ func (this *ACMETaskService) CountAllEnabledACMETasksWithACMEUserId(ctx context.
return this.SuccessCount(count) return this.SuccessCount(count)
} }
// 计算跟某个DNS服务商相关的任务数量 // CountEnabledACMETasksWithDNSProviderId 计算跟某个DNS服务商相关的任务数量
func (this *ACMETaskService) CountEnabledACMETasksWithDNSProviderId(ctx context.Context, req *pb.CountEnabledACMETasksWithDNSProviderIdRequest) (*pb.RPCCountResponse, error) { func (this *ACMETaskService) CountEnabledACMETasksWithDNSProviderId(ctx context.Context, req *pb.CountEnabledACMETasksWithDNSProviderIdRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, 0) _, _, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -51,7 +51,7 @@ func (this *ACMETaskService) CountEnabledACMETasksWithDNSProviderId(ctx context.
return this.SuccessCount(count) return this.SuccessCount(count)
} }
// 计算所有任务数量 // CountAllEnabledACMETasks 计算所有任务数量
func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *pb.CountAllEnabledACMETasksRequest) (*pb.RPCCountResponse, error) { func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *pb.CountAllEnabledACMETasksRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId) _, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
if err != nil { if err != nil {
@@ -67,7 +67,7 @@ func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *
return this.SuccessCount(count) return this.SuccessCount(count)
} }
// 列出单页任务 // ListEnabledACMETasks 列出单页任务
func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.ListEnabledACMETasksRequest) (*pb.ListEnabledACMETasksResponse, error) { func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.ListEnabledACMETasksRequest) (*pb.ListEnabledACMETasksResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId) _, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
if err != nil { if err != nil {
@@ -162,13 +162,14 @@ func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.L
SslCert: pbCert, SslCert: pbCert,
LatestACMETaskLog: pbTaskLog, LatestACMETaskLog: pbTaskLog,
AuthType: task.AuthType, AuthType: task.AuthType,
AuthURL: task.AuthURL,
}) })
} }
return &pb.ListEnabledACMETasksResponse{AcmeTasks: result}, nil return &pb.ListEnabledACMETasksResponse{AcmeTasks: result}, nil
} }
// 创建任务 // CreateACMETask 创建任务
func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateACMETaskRequest) (*pb.CreateACMETaskResponse, error) { func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateACMETaskRequest) (*pb.CreateACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0) adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -180,14 +181,14 @@ func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateA
} }
tx := this.NullTx() tx := this.NullTx()
taskId, err := acmemodels.SharedACMETaskDAO.CreateACMETask(tx, adminId, userId, req.AuthType, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew) taskId, err := acmemodels.SharedACMETaskDAO.CreateACMETask(tx, adminId, userId, req.AuthType, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew, req.AuthURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &pb.CreateACMETaskResponse{AcmeTaskId: taskId}, nil return &pb.CreateACMETaskResponse{AcmeTaskId: taskId}, nil
} }
// 修改任务 // UpdateACMETask 修改任务
func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateACMETaskRequest) (*pb.RPCSuccess, error) { func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateACMETaskRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0) adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -204,14 +205,14 @@ func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateA
return nil, this.PermissionError() return nil, this.PermissionError()
} }
err = acmemodels.SharedACMETaskDAO.UpdateACMETask(tx, req.AcmeTaskId, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew) err = acmemodels.SharedACMETaskDAO.UpdateACMETask(tx, req.AcmeTaskId, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew, req.AuthURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return this.Success() return this.Success()
} }
// 删除任务 // DeleteACMETask 删除任务
func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteACMETaskRequest) (*pb.RPCSuccess, error) { func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteACMETaskRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0) adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -235,7 +236,7 @@ func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteA
return this.Success() return this.Success()
} }
// 运行某个任务 // RunACMETask 运行某个任务
func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETaskRequest) (*pb.RunACMETaskResponse, error) { func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETaskRequest) (*pb.RunACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0) adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -261,7 +262,7 @@ func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETas
}, nil }, nil
} }
// 查找单个任务信息 // FindEnabledACMETask 查找单个任务信息
func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.FindEnabledACMETaskRequest) (*pb.FindEnabledACMETaskResponse, error) { func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.FindEnabledACMETaskRequest) (*pb.FindEnabledACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0) adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil { if err != nil {
@@ -328,5 +329,6 @@ func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.Fi
DnsProvider: pbProvider, DnsProvider: pbProvider,
AcmeUser: pbACMEUser, AcmeUser: pbACMEUser,
AuthType: task.AuthType, AuthType: task.AuthType,
AuthURL: task.AuthURL,
}}, nil }}, nil
} }

53
internal/utils/http.go Normal file
View File

@@ -0,0 +1,53 @@
package utils
import (
"crypto/tls"
"io/ioutil"
"net/http"
"net/http/httputil"
"sync"
"time"
)
// HTTP请求客户端管理
var timeoutClientMap = map[time.Duration]*http.Client{} // timeout => Client
var timeoutClientLocker = sync.Mutex{}
// DumpResponse 导出响应
func DumpResponse(resp *http.Response) (header []byte, body []byte, err error) {
header, err = httputil.DumpResponse(resp, false)
body, err = ioutil.ReadAll(resp.Body)
return
}
// NewHTTPClient 获取一个新的Client
func NewHTTPClient(timeout time.Duration) *http.Client {
return &http.Client{
Timeout: timeout,
Transport: &http.Transport{
MaxIdleConns: 4096,
MaxIdleConnsPerHost: 32,
MaxConnsPerHost: 32,
IdleConnTimeout: 2 * time.Minute,
ExpectContinueTimeout: 1 * time.Second,
TLSHandshakeTimeout: 0,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
}
// SharedHttpClient 获取一个公用的Client
func SharedHttpClient(timeout time.Duration) *http.Client {
timeoutClientLocker.Lock()
defer timeoutClientLocker.Unlock()
client, ok := timeoutClientMap[timeout]
if ok {
return client
}
client = NewHTTPClient(timeout)
timeoutClientMap[timeout] = client
return client
}