Procházet zdrojové kódy

feat(cdn): 添加 SSL策略功能并优化 HTTPS域名转发

- 在 cdn.go 中添加了 SSL 策略相关的字段和方法
- 实现了添加 SSL 策略的功能,包括 HTTP/2、HTTP/3、TLS 版本设置等
- 优化了 HTTPS域名转发的 SSL 证书和策略处理逻辑
huangjl před 1 měsícem
rodič
revize
9602e37ca1
3 změnil soubory, kde provedl 319 přidání a 302 odebrání
  1. 87 86
      api/v1/cdn.go
  2. 129 104
      internal/service/cdn.go
  3. 103 112
      internal/service/webforwarding.go

+ 87 - 86
api/v1/cdn.go

@@ -1,139 +1,140 @@
 package v1
 
 type User struct {
-	ID       int64  `json:"id" form:"id"`
-	Username string `json:"username" form:"username"`
-	Password string `json:"password" form:"password"`
-	Fullname string `json:"fullname" form:"fullname"`
-	Mobile 	string `json:"mobile" form:"mobile"`
-	Tel     string `json:"tel" form:"tel"`
-	Email    string `json:"email" form:"email"`
-	Remark   string `json:"remark" form:"remark"`
-	Source   string `json:"source" form:"source"` // 用户来源
-	NodeClusterId int64 `json:"nodeClusterId" form:"nodeClusterId"` // 节点集群ID
+	ID            int64  `json:"id" form:"id"`
+	Username      string `json:"username" form:"username"`
+	Password      string `json:"password" form:"password"`
+	Fullname      string `json:"fullname" form:"fullname"`
+	Mobile        string `json:"mobile" form:"mobile"`
+	Tel           string `json:"tel" form:"tel"`
+	Email         string `json:"email" form:"email"`
+	Remark        string `json:"remark" form:"remark"`
+	Source        string `json:"source" form:"source"`               // 用户来源
+	NodeClusterId int64  `json:"nodeClusterId" form:"nodeClusterId"` // 节点集群ID
 }
 
-
 type Group struct {
 	Name string `json:"name" form:"name"`
 }
 
 type Plan struct {
-	UserId int64 `json:"userId" form:"userId"`
-	PlanId int64 `json:"planId" form:"planId"`
-	DayTo  string `json:"dayTo" form:"dayTo"` // 结束日期,格式:YYYY-MM-DD,适用于按带宽和流量计费的套餐
-	Period string `json:"period" form:"period"` // 周期类型:yearly、seasonally、monthly,适用于按时间周期计费的套餐
-	CountPeriod int64 `json:"countPeriod" form:"countPeriod"` // 周期数量,适用于带宽和流量计费
-	Name   string `json:"name" form:"name"` // 备注名称
-	IsFree bool `json:"isFree" form:"isFree"` // 可选项,是否免费
+	UserId      int64  `json:"userId" form:"userId"`
+	PlanId      int64  `json:"planId" form:"planId"`
+	DayTo       string `json:"dayTo" form:"dayTo"`             // 结束日期,格式:YYYY-MM-DD,适用于按带宽和流量计费的套餐
+	Period      string `json:"period" form:"period"`           // 周期类型:yearly、seasonally、monthly,适用于按时间周期计费的套餐
+	CountPeriod int64  `json:"countPeriod" form:"countPeriod"` // 周期数量,适用于带宽和流量计费
+	Name        string `json:"name" form:"name"`               // 备注名称
+	IsFree      bool   `json:"isFree" form:"isFree"`           // 可选项,是否免费
 	PeriodDayTo string `json:"periodDayTo" form:"periodDayTo"` // 可选项, 按周期计费的套餐结束日期
 }
 
 type RenewalPlan struct {
-	UserPlanId int64 `json:"userPlanId" form:"userPlanId"`
-	DayTo  string `json:"dayTo" form:"dayTo"` // 结束日期,格式:YYYY-MM-DD,适用于按带宽和流量计费的套餐
-	Period string `json:"period" form:"period"` // 周期类型:yearly、seasonally、monthly,适用于按时间周期计费的套餐
-	CountPeriod int64 `json:"countPeriod" form:"countPeriod"` // 周期数量,适用于带宽和流量计费
-	IsFree bool `json:"isFree" form:"isFree"` // 可选项,是否免费
+	UserPlanId  int64  `json:"userPlanId" form:"userPlanId"`
+	DayTo       string `json:"dayTo" form:"dayTo"`             // 结束日期,格式:YYYY-MM-DD,适用于按带宽和流量计费的套餐
+	Period      string `json:"period" form:"period"`           // 周期类型:yearly、seasonally、monthly,适用于按时间周期计费的套餐
+	CountPeriod int64  `json:"countPeriod" form:"countPeriod"` // 周期数量,适用于带宽和流量计费
+	IsFree      bool   `json:"isFree" form:"isFree"`           // 可选项,是否免费
 	PeriodDayTo string `json:"periodDayTo" form:"periodDayTo"` // 可选项, 按周期计费的套餐结束日期
 }
 
 type Website struct {
-	UserId int64 `json:"userId" form:"userId"` //可选项,用户ID,如果不想指定用户,此值可以为0
-	AdminId int64 `json:"adminId" form:"adminId"` //可选项,管理员ID
-	Type string `json:"type" form:"type"` // 类型:httpProxy(HTTP反向代理,一般CDN服务都选这个)、httpWeb(静态文件服务,只会从服务器上读取文件内容,不会转发到源站)、tcpProxy(TCP反向代理)、udpProxy(UDP反向代理)
-	Name string `json:"name" form:"name"` // 网站名称
-	Description string `json:"description" form:"description"` // 可选项,网站描述
-	ServerNamesJSON []byte `json:"serverNamesJSON,omitempty" form:"serverNamesJSON"` // 域名列表 json:server_names
-	HttpJSON []byte `json:"httpJSON,omitempty" form:"httpJSON"` // HTTP协议设置,当type为httpProxy或者httpWeb时填写 json:http_protocol
-	HttpsJSON []byte `json:"httpsJSON,omitempty" form:"httpsJSON"` // HTTPS协议设置,当type为httpProxy或者httpWeb时填写 json:https_protocol
-	TcpJSON []byte `json:"tcpJSON,omitempty" form:"tcpJSON"` // TCP协议设置,当type为tcpProxy时填写 json:tcp_protocol
-	TlsJSON []byte `json:"tlsJSON,omitempty" form:"tlsJSON"` // TLS协议设置,当type为tcpProxy时填写 json:tls_protocol
-	UdpJSON []byte `json:"udpJSON,omitempty" form:"udpJSON"` // UDP协议设置,当type为udpProxy时填写 json:udp_protocol
-	WebId int64 `json:"webId" form:"webId"` // 可选项,Web配置ID,当type为httpProxy或者httpWeb时填写,可以通过 /HTTPWebService/createHTTPWeb 接口创建;如果你需要配置缓存等信息时需要在 HTTPWebService 接口操作=
-	ReverseProxyJSON []byte `json:"reverseProxyJSON,omitempty" form:"reverseProxyJSON"` // 反向代理(包含源站)配置引用,此项可以在创建网站后再设置 json:reverse_proxy_ref
-	ServerGroupIds []int64 `json:"serverGroupIds" form:"serverGroupIds"` // 可选项,所属网站分组ID列表
-	UserPlanId int64 `json:"userPlanId" form:"userPlanId"` // 可选项,套餐ID
-	NodeClusterId int64 `json:"nodeClusterId" form:"nodeClusterId"` // 所部署的集群ID
-	IncludeNodesJSON string `json:"includeNodesJSON" form:"includeNodesJSON"` // 备用参数,不用填写
-	ExcludeNodesJSON string `json:"excludeNodesJSON" form:"excludeNodesJSON"` // 备用参数,不用填写
+	UserId           int64   `json:"userId" form:"userId"`                               //可选项,用户ID,如果不想指定用户,此值可以为0
+	AdminId          int64   `json:"adminId" form:"adminId"`                             //可选项,管理员ID
+	Type             string  `json:"type" form:"type"`                                   // 类型:httpProxy(HTTP反向代理,一般CDN服务都选这个)、httpWeb(静态文件服务,只会从服务器上读取文件内容,不会转发到源站)、tcpProxy(TCP反向代理)、udpProxy(UDP反向代理)
+	Name             string  `json:"name" form:"name"`                                   // 网站名称
+	Description      string  `json:"description" form:"description"`                     // 可选项,网站描述
+	ServerNamesJSON  []byte  `json:"serverNamesJSON,omitempty" form:"serverNamesJSON"`   // 域名列表 json:server_names
+	HttpJSON         []byte  `json:"httpJSON,omitempty" form:"httpJSON"`                 // HTTP协议设置,当type为httpProxy或者httpWeb时填写 json:http_protocol
+	HttpsJSON        []byte  `json:"httpsJSON,omitempty" form:"httpsJSON"`               // HTTPS协议设置,当type为httpProxy或者httpWeb时填写 json:https_protocol
+	TcpJSON          []byte  `json:"tcpJSON,omitempty" form:"tcpJSON"`                   // TCP协议设置,当type为tcpProxy时填写 json:tcp_protocol
+	TlsJSON          []byte  `json:"tlsJSON,omitempty" form:"tlsJSON"`                   // TLS协议设置,当type为tcpProxy时填写 json:tls_protocol
+	UdpJSON          []byte  `json:"udpJSON,omitempty" form:"udpJSON"`                   // UDP协议设置,当type为udpProxy时填写 json:udp_protocol
+	WebId            int64   `json:"webId" form:"webId"`                                 // 可选项,Web配置ID,当type为httpProxy或者httpWeb时填写,可以通过 /HTTPWebService/createHTTPWeb 接口创建;如果你需要配置缓存等信息时需要在 HTTPWebService 接口操作=
+	ReverseProxyJSON []byte  `json:"reverseProxyJSON,omitempty" form:"reverseProxyJSON"` // 反向代理(包含源站)配置引用,此项可以在创建网站后再设置 json:reverse_proxy_ref
+	ServerGroupIds   []int64 `json:"serverGroupIds" form:"serverGroupIds"`               // 可选项,所属网站分组ID列表
+	UserPlanId       int64   `json:"userPlanId" form:"userPlanId"`                       // 可选项,套餐ID
+	NodeClusterId    int64   `json:"nodeClusterId" form:"nodeClusterId"`                 // 所部署的集群ID
+	IncludeNodesJSON string  `json:"includeNodesJSON" form:"includeNodesJSON"`           // 备用参数,不用填写
+	ExcludeNodesJSON string  `json:"excludeNodesJSON" form:"excludeNodesJSON"`           // 备用参数,不用填写
 }
 
 type TypeJSON struct {
-	IsOn bool `json:"isOn" form:"isOn"` // 是否开启
-	Listen []Listen `json:"listen" form:"listen"` // 监听端口
+	IsOn         bool         `json:"isOn" form:"isOn"`                 // 是否开启
+	Listen       []Listen     `json:"listen" form:"listen"`             // 监听端口
 	SslPolicyRef SslPolicyRef `json:"sslPolicyRef" form:"sslPolicyRef"` // SSL策略
 }
 
 type Listen struct {
-	Protocol string `json:"protocol" form:"protocol"` // 协议类型:tcp、udp
-	Host string `json:"host" form:"host"` // 监听地址
-	Port string `json:"portRange" form:"portRange"` // 端口
+	Protocol string `json:"protocol" form:"protocol"`   // 协议类型:tcp、udp
+	Host     string `json:"host" form:"host"`           // 监听地址
+	Port     string `json:"portRange" form:"portRange"` // 端口
 }
 
 type SslPolicyRef struct {
-	IsOn bool `json:"isOn" form:"isOn"` // 是否开启 isOn
+	IsOn        bool  `json:"isOn" form:"isOn"`               // 是否开启 isOn
 	SslPolicyId int64 `json:"sslPolicyId" form:"sslPolicyId"` // SSL策略ID
 }
 
 type EditWebsite struct {
-	Id int64 `json:"id" form:"id"`
+	Id       int64  `json:"id" form:"id"`
 	TypeJSON []byte `json:"typeJSON" form:"typeJSON"`
 }
 
 type ProxyJson struct {
 	ServerId int64 `json:"serverId" form:"serverId"` // 网站ID
-	JSON  byte  `json:"JSON" form:"JSON"`   // TCP协议设置
+	JSON     byte  `json:"JSON" form:"JSON"`         // TCP协议设置
 }
 
 type Origin struct {
-	OriginId int64 `json:"originId" form:"originId"`
-	Name string `json:"name" form:"name"` // 源站名称
-	Addr Addr `json:"addr" form:"addr"` // 源站地址
-	OssJSON []byte `json:"ossJSON" form:"ossJSON"` // Oss配置 json:oss_config
-	Description string `json:"description" form:"description"` // 备注
-	Weight int64 `json:"weight" form:"weight"` // 权重
-	IsOn bool `json:"isOn" form:"isOn"` // 是否开启
-	Domains []string `json:"domains" form:"domains"` // 域名
-	CertRefJSON []byte `json:"certRefJSON" form:"certRefJSON"` // 证书引用,可选项
-	Host string `json:"host" form:"host"` // 回源主机域名,可选项
-	FollowPort bool `json:"followPort" form:"followPort"` // 是否跟随端口,可选项
-	Http2Enabled bool `json:"http2Enabled" form:"http2Enabled"` //可选项,是否支持HTTP/2,只在HTTPS源站时生效
-	TlsSecurityVerifyMode string `json:"tlsSecurityVerifyMode" form:"tlsSecurityVerifyMode"` // // 安全校验模式:auto系统默认,force强校验,skip不校验
+	OriginId              int64    `json:"originId" form:"originId"`
+	Name                  string   `json:"name" form:"name"`                                   // 源站名称
+	Addr                  Addr     `json:"addr" form:"addr"`                                   // 源站地址
+	OssJSON               []byte   `json:"ossJSON" form:"ossJSON"`                             // Oss配置 json:oss_config
+	Description           string   `json:"description" form:"description"`                     // 备注
+	Weight                int64    `json:"weight" form:"weight"`                               // 权重
+	IsOn                  bool     `json:"isOn" form:"isOn"`                                   // 是否开启
+	Domains               []string `json:"domains" form:"domains"`                             // 域名
+	CertRefJSON           []byte   `json:"certRefJSON" form:"certRefJSON"`                     // 证书引用,可选项
+	Host                  string   `json:"host" form:"host"`                                   // 回源主机域名,可选项
+	FollowPort            bool     `json:"followPort" form:"followPort"`                       // 是否跟随端口,可选项
+	Http2Enabled          bool     `json:"http2Enabled" form:"http2Enabled"`                   //可选项,是否支持HTTP/2,只在HTTPS源站时生效
+	TlsSecurityVerifyMode string   `json:"tlsSecurityVerifyMode" form:"tlsSecurityVerifyMode"` // // 安全校验模式:auto系统默认,force强校验,skip不校验
 }
 
 type Addr struct {
-	Protocol string `json:"protocol" form:"protocol"` // 协议类型:tcp、udp
-	Host string `json:"host" form:"host"` // 监听地址
-	Port string `json:"portRange" form:"portRange"` // 端口
+	Protocol string `json:"protocol" form:"protocol"`   // 协议类型:tcp、udp
+	Host     string `json:"host" form:"host"`           // 监听地址
+	Port     string `json:"portRange" form:"portRange"` // 端口
 }
 
-
 type SSlCert struct {
-	IsOn bool `json:"isOn" form:"isOn"`  //是否开启
-	UserId int64 `json:"userId" form:"userId"`  //用户id
-	Name string `json:"name" form:"name"`  //证书名称
-	Description string `json:"description" form:"description"`  //证书描述
-	IsCA bool `json:"isCA" form:"isCA"`  //是否是CA证书
-	CertData []byte `json:"certData" form:"certData"`  //证书内容
-	KeyData []byte `json:"keyData" form:"keyData"`  //证书内容
-	TimeBeginAt int64 `json:"timeBeginAt" form:"timeBeginAt"`  //证书生效时间
-	TimeEndAt int64 `json:"timeEndAt" form:"timeEndAt"`  //证书失效时间
-	DnsNames []string `json:"dnsNames" form:"dnsNames"` // 包含的DNS域名
-	CommonNames []string `json:"commonNames" form:"commonNames"` // 包含的COMMON域名
-	IsSelfSigned bool `json:"isSelfSigned" form:"isSelfSigned"`  //是否是自签名证书
+	IsOn         bool     `json:"isOn" form:"isOn"`                 //是否开启
+	UserId       int64    `json:"userId" form:"userId"`             //用户id
+	Name         string   `json:"name" form:"name"`                 //证书名称
+	Description  string   `json:"description" form:"description"`   //证书描述
+	IsCA         bool     `json:"isCA" form:"isCA"`                 //是否是CA证书
+	CertData     []byte   `json:"certData" form:"certData"`         //证书内容
+	KeyData      []byte   `json:"keyData" form:"keyData"`           //证书内容
+	TimeBeginAt  int64    `json:"timeBeginAt" form:"timeBeginAt"`   //证书生效时间
+	TimeEndAt    int64    `json:"timeEndAt" form:"timeEndAt"`       //证书失效时间
+	DnsNames     []string `json:"dnsNames" form:"dnsNames"`         // 包含的DNS域名
+	CommonNames  []string `json:"commonNames" form:"commonNames"`   // 包含的COMMON域名
+	IsSelfSigned bool     `json:"isSelfSigned" form:"isSelfSigned"` //是否是自签名证书
 }
 
 type EditServerNames struct {
-	ServerId int64 `json:"serverId" form:"serverId"`
+	ServerId        int64  `json:"serverId" form:"serverId"`
 	ServerNamesJSON []byte `json:"serverNamesJSON" form:"serverNamesJSON"`
 }
 
 type AddSSLPolicy struct {
-	Http2Enabled bool `json:"http2Enabled" form:"http2Enabled"` //是否支持HTTP/2
-	Http3Enabled bool `json:"http3Enabled" form:"http3Enabled"` //是否支持Http3Enabled
-	MinVersion string `json:"minVersion" form:"minVersion"` //最小TLS版本
-	SslCertsJSON []byte `json:"sslCertsJSON" form:"sslCertsJSON"` //SslCertsJSON
-	HstsJSON []byte `json:"hstsJSON" form:"hstsJSON"` //HstsJSON
-	ClientAuthType string `json:"clientAuthType" form:"clientAuthType"` //可选项,客户端校验类型:0 无需证书,1 需要客户端证书,2 需要任一客户端证书,3 如果客户端上传了证书才校验,4 需要客户端证书而且需要校验
-}
+	Http2Enabled     bool     `json:"http2Enabled" form:"http2Enabled"`         //是否支持HTTP/2
+	Http3Enabled     bool     `json:"http3Enabled" form:"http3Enabled"`         //是否支持Http3Enabled
+	MinVersion       string   `json:"minVersion" form:"minVersion"`             //最小TLS版本
+	SslCertsJSON     []byte   `json:"sslCertsJSON" form:"sslCertsJSON"`         //SslCertsJSON
+	HstsJSON         []byte   `json:"hstsJSON" form:"hstsJSON"`                 //HstsJSON
+	ClientAuthType   string   `json:"clientAuthType" form:"clientAuthType"`     //可选项,客户端校验类型:0 无需证书,1 需要客户端证书,2 需要任一客户端证书,3 如果客户端上传了证书才校验,4 需要客户端证书而且需要校验
+	CipherSuites     []string `json:"cipherSuites" form:"cipherSuites"`         //可选项,支持的TLS加密套件
+	CipherSuitesIsOn bool     `json:"cipherSuitesIsOn" form:"cipherSuitesIsOn"` //可选项,是否启用自定义加密套件
+	OcspIsOn         bool     `json:"ocspIsOn" form:"ocspIsOn"`                 //可选项,是否开启OCSP
+}

+ 129 - 104
internal/service/cdn.go

@@ -19,22 +19,24 @@ type CdnService interface {
 	BindPlan(ctx context.Context, req v1.Plan) (int64, error)
 	RenewPlan(ctx context.Context, req v1.RenewalPlan) error
 	CreateWebsite(ctx context.Context, req v1.Website) (int64, error)
-	EditServerType(ctx context.Context, req v1.EditWebsite,apiType string) error
+	EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error
 	EditProtocol(ctx context.Context, req v1.ProxyJson, action string) error
 	CreateOrigin(ctx context.Context, req v1.Origin) (int64, error)
 	EditOrigin(ctx context.Context, req v1.Origin) error
 	AddServerOrigin(ctx context.Context, serverId int64, originId int64) error
 	EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error
 	// 修改网站基本信息
-	EditServerBasic (ctx context.Context, serverId int64,name string) error
+	EditServerBasic(ctx context.Context, serverId int64, name string) error
 	// 从网站中删除某个源站
-	DelServerOrigin (ctx context.Context,serverId int64, originId int64) error
+	DelServerOrigin(ctx context.Context, serverId int64, originId int64) error
 	// 删除网站
 	DelServer(ctx context.Context, serverId int64) error
 	// 添加ssl证书
 	AddSSLCert(ctx context.Context, req v1.SSlCert) (int64, error)
 	// 修改网站域名
 	EditServerName(ctx context.Context, req v1.EditServerNames) error
+	// 添加ssl策略
+	AddSSLPolicy(ctx context.Context, req v1.AddSSLPolicy) (int64, error)
 }
 
 func NewCdnService(
@@ -44,25 +46,25 @@ func NewCdnService(
 	cdnRepository repository.CdnRepository,
 ) CdnService {
 	return &cdnService{
-		Service:         service,
-		Url:              conf.GetString("flexCdn.Url"),
-		AccessKeyID:      conf.GetString("flexCdn.AccessKeyID"),
-		AccessKeySecret:  conf.GetString("flexCdn.AccessKeySecret"),
-		request:          request,
-		cdnRepository:    cdnRepository,
-		maxRetryCount:    3, // 可以配置最大重试次数
+		Service:           service,
+		Url:               conf.GetString("flexCdn.Url"),
+		AccessKeyID:       conf.GetString("flexCdn.AccessKeyID"),
+		AccessKeySecret:   conf.GetString("flexCdn.AccessKeySecret"),
+		request:           request,
+		cdnRepository:     cdnRepository,
+		maxRetryCount:     3, // 可以配置最大重试次数
 		retryDelaySeconds: 2, // 可以配置重试间隔
 	}
 }
 
 type cdnService struct {
 	*Service
-	Url              string
-	AccessKeyID      string
-	AccessKeySecret  string
-	request          RequestService
-	cdnRepository    repository.CdnRepository
-	maxRetryCount    int
+	Url               string
+	AccessKeyID       string
+	AccessKeySecret   string
+	request           RequestService
+	cdnRepository     repository.CdnRepository
+	maxRetryCount     int
 	retryDelaySeconds int
 }
 
@@ -177,18 +179,18 @@ func (s *cdnService) Token(ctx context.Context) (string, error) {
 	return token, nil
 }
 
-//注册用户
+// 注册用户
 func (s *cdnService) AddUser(ctx context.Context, req v1.User) (int64, error) {
 	formData := map[string]interface{}{
-		"id":       req.ID,
-		"username": req.Username,
-		"password": "a7fKiKujgAzzsJ6", // 这个密码应该被妥善管理,而不是硬编码
-		"fullname": req.Fullname,
-		"mobile":   req.Mobile,
-		"tel":      req.Tel,
-		"email":    req.Email,
-		"remark":   req.Remark,
-		"source":   req.Source,
+		"id":            req.ID,
+		"username":      req.Username,
+		"password":      "a7fKiKujgAzzsJ6", // 这个密码应该被妥善管理,而不是硬编码
+		"fullname":      req.Fullname,
+		"mobile":        req.Mobile,
+		"tel":           req.Tel,
+		"email":         req.Email,
+		"remark":        req.Remark,
+		"source":        req.Source,
 		"nodeClusterId": 1,
 	}
 	apiUrl := s.Url + "UserService/createUser"
@@ -213,7 +215,7 @@ func (s *cdnService) AddUser(ctx context.Context, req v1.User) (int64, error) {
 	return res.Data.UserId, nil
 }
 
-//创建规则分组
+// 创建规则分组
 func (s *cdnService) CreateGroup(ctx context.Context, req v1.Group) (int64, error) {
 	formData := map[string]interface{}{
 		"name": req.Name,
@@ -239,17 +241,17 @@ func (s *cdnService) CreateGroup(ctx context.Context, req v1.Group) (int64, erro
 	return res.Data.ServerGroupId, nil
 }
 
-//分配套餐
+// 分配套餐
 func (s *cdnService) BindPlan(ctx context.Context, req v1.Plan) (int64, error) {
 	formData := map[string]interface{}{
-		"userId":        req.UserId,
-		"planId":        req.PlanId,
-		"dayTo":         req.DayTo,
-		"period":        req.Period,
-		"countPeriod":   req.CountPeriod,
-		"name":          req.Name,
-		"isFree":        req.IsFree,
-		"periodDayTo":   req.PeriodDayTo,
+		"userId":      req.UserId,
+		"planId":      req.PlanId,
+		"dayTo":       req.DayTo,
+		"period":      req.Period,
+		"countPeriod": req.CountPeriod,
+		"name":        req.Name,
+		"isFree":      req.IsFree,
+		"periodDayTo": req.PeriodDayTo,
 	}
 	apiUrl := s.Url + "UserPlanService/buyUserPlan"
 	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
@@ -272,15 +274,15 @@ func (s *cdnService) BindPlan(ctx context.Context, req v1.Plan) (int64, error) {
 	return res.Data.UserPlanId, nil
 }
 
-//续费套餐
+// 续费套餐
 func (s *cdnService) RenewPlan(ctx context.Context, req v1.RenewalPlan) error {
 	formData := map[string]interface{}{
-		"userPlanId":    req.UserPlanId,
-		"dayTo":         req.DayTo,
-		"period":        req.Period,
-		"countPeriod":   req.CountPeriod,
-		"isFree":        req.IsFree,
-		"periodDayTo":   req.PeriodDayTo,
+		"userPlanId":  req.UserPlanId,
+		"dayTo":       req.DayTo,
+		"period":      req.Period,
+		"countPeriod": req.CountPeriod,
+		"isFree":      req.IsFree,
+		"periodDayTo": req.PeriodDayTo,
 	}
 	apiUrl := s.Url + "UserPlanService/renewUserPlan"
 	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
@@ -297,24 +299,24 @@ func (s *cdnService) RenewPlan(ctx context.Context, req v1.RenewalPlan) error {
 	return nil
 }
 
-//创建网站
+// 创建网站
 func (s *cdnService) CreateWebsite(ctx context.Context, req v1.Website) (int64, error) {
 	formData := map[string]interface{}{
-		"userId":             req.UserId,
-		"type":               req.Type,
-		"name":               req.Name,
-		"description":        req.Description,
-		"serverNamesJSON":    req.ServerNamesJSON,
-		"httpJSON":           req.HttpJSON,
-		"httpsJSON":          req.HttpsJSON,
-		"tcpJSON":            req.TcpJSON,
-		"tlsJSON":            req.TlsJSON,
-		"udpJSON":            req.UdpJSON,
-		"webId":              req.WebId,
-		"reverseProxyJSON":   req.ReverseProxyJSON,
-		"serverGroupIds":     req.ServerGroupIds,
-		"userPlanId":         req.UserPlanId,
-		"nodeClusterId":      req.NodeClusterId,
+		"userId":           req.UserId,
+		"type":             req.Type,
+		"name":             req.Name,
+		"description":      req.Description,
+		"serverNamesJSON":  req.ServerNamesJSON,
+		"httpJSON":         req.HttpJSON,
+		"httpsJSON":        req.HttpsJSON,
+		"tcpJSON":          req.TcpJSON,
+		"tlsJSON":          req.TlsJSON,
+		"udpJSON":          req.UdpJSON,
+		"webId":            req.WebId,
+		"reverseProxyJSON": req.ReverseProxyJSON,
+		"serverGroupIds":   req.ServerGroupIds,
+		"userPlanId":       req.UserPlanId,
+		"nodeClusterId":    req.NodeClusterId,
 	}
 	apiUrl := s.Url + "ServerService/createServer"
 	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
@@ -377,17 +379,17 @@ func (s *cdnService) EditProtocol(ctx context.Context, req v1.ProxyJson, action
 
 func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, error) {
 	formData := map[string]interface{}{
-		"name":                    req.Name,
-		"addr":                    req.Addr,
-		"ossJSON":                 req.OssJSON,
-		"description":             req.Description,
-		"weight":                  req.Weight,
-		"isOn":                    req.IsOn,
-		"domains":                 req.Domains,
-		"certRefJSON":             req.CertRefJSON,
-		"host":                    req.Host,
-		"followPort":              req.FollowPort,
-		"http2Enabled":            req.Http2Enabled,
+		"name":                  req.Name,
+		"addr":                  req.Addr,
+		"ossJSON":               req.OssJSON,
+		"description":           req.Description,
+		"weight":                req.Weight,
+		"isOn":                  req.IsOn,
+		"domains":               req.Domains,
+		"certRefJSON":           req.CertRefJSON,
+		"host":                  req.Host,
+		"followPort":            req.FollowPort,
+		"http2Enabled":          req.Http2Enabled,
 		"tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
 	}
 	apiUrl := s.Url + "OriginService/createOrigin"
@@ -411,12 +413,11 @@ func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, er
 	return res.Data.OriginId, nil
 }
 
-
-func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite,apiType string) error {
+func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error {
 	typeName := apiType + "JSON"
 	formData := map[string]interface{}{
 		"serverId": req.Id,
-		typeName: req.TypeJSON,
+		typeName:   req.TypeJSON,
 	}
 	apiUrl := s.Url + "ServerService/updateServer" + strings.ToUpper(apiType)
 	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
@@ -438,18 +439,18 @@ func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite,apiT
 
 func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
 	formData := map[string]interface{}{
-		"originId":                req.OriginId,
-		"name":                    req.Name,
-		"addr":                    req.Addr,
-		"ossJSON":                 req.OssJSON,
-		"description":             req.Description,
-		"weight":                  req.Weight,
-		"isOn":                    req.IsOn,
-		"domains":                 req.Domains,
-		"certRefJSON":             req.CertRefJSON,
-		"host":                    req.Host,
-		"followPort":              req.FollowPort,
-		"http2Enabled":            req.Http2Enabled,
+		"originId":              req.OriginId,
+		"name":                  req.Name,
+		"addr":                  req.Addr,
+		"ossJSON":               req.OssJSON,
+		"description":           req.Description,
+		"weight":                req.Weight,
+		"isOn":                  req.IsOn,
+		"domains":               req.Domains,
+		"certRefJSON":           req.CertRefJSON,
+		"host":                  req.Host,
+		"followPort":            req.FollowPort,
+		"http2Enabled":          req.Http2Enabled,
 		"tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
 	}
 	apiUrl := s.Url + "OriginService/updateOrigin"
@@ -467,12 +468,11 @@ func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
 	return nil
 }
 
-
 // AddServerOrigin 网站绑定源站
-func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error  {
+func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error {
 	formData := map[string]interface{}{
-		"serverId": serverId,
-		"originId": originId,
+		"serverId":  serverId,
+		"originId":  originId,
 		"isPrimary": true,
 	}
 	apiUrl := s.Url + "ServerService/addServerOrigin"
@@ -491,10 +491,10 @@ func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, origin
 }
 
 // EditOriginIsOn 编辑源站是否开启
-func (s *cdnService) EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error  {
+func (s *cdnService) EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error {
 	formData := map[string]interface{}{
 		"originId": originId,
-		"isOn": isOn,
+		"isOn":     isOn,
 	}
 	apiUrl := s.Url + "OriginService/updateOriginIsOn"
 	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
@@ -512,12 +512,12 @@ func (s *cdnService) EditOriginIsOn(ctx context.Context, originId int64, isOn bo
 }
 
 // EditServerBasic 修改网站基本信息
-func (s *cdnService) EditServerBasic (ctx context.Context, serverId int64,name string) error  {
+func (s *cdnService) EditServerBasic(ctx context.Context, serverId int64, name string) error {
 	formData := map[string]interface{}{
-		"serverId": serverId,
-		"name": name,
-		"nodeClusterId" : 1,
-		"isOn": true,
+		"serverId":      serverId,
+		"name":          name,
+		"nodeClusterId": 1,
+		"isOn":          true,
 	}
 	apiUrl := s.Url + "ServerService/updateServerBasic"
 	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
@@ -535,7 +535,7 @@ func (s *cdnService) EditServerBasic (ctx context.Context, serverId int64,name s
 }
 
 // DelServerOrigin 从网站中删除某个源站
-func (s *cdnService) DelServerOrigin (ctx context.Context,serverId int64, originId int64) error  {
+func (s *cdnService) DelServerOrigin(ctx context.Context, serverId int64, originId int64) error {
 	formData := map[string]interface{}{
 		"serverId": serverId,
 		"originId": originId,
@@ -555,7 +555,7 @@ func (s *cdnService) DelServerOrigin (ctx context.Context,serverId int64, origin
 	return nil
 }
 
-func (s *cdnService) DelServer(ctx context.Context, serverId int64) error  {
+func (s *cdnService) DelServer(ctx context.Context, serverId int64) error {
 	formData := map[string]interface{}{
 		"serverId": serverId,
 	}
@@ -608,11 +608,10 @@ func (s *cdnService) AddSSLCert(ctx context.Context, req v1.SSlCert) (int64, err
 	return res.Data.SslCertId, nil
 }
 
-
 // 修改网站域名
-func (s *cdnService) EditServerName(ctx context.Context, req v1.EditServerNames) error  {
+func (s *cdnService) EditServerName(ctx context.Context, req v1.EditServerNames) error {
 	formData := map[string]interface{}{
-		"serverId": req.ServerId,
+		"serverId":        req.ServerId,
 		"serverNamesJSON": req.ServerNamesJSON,
 	}
 	apiUrl := s.Url + "ServerService/updateServerNames"
@@ -630,7 +629,33 @@ func (s *cdnService) EditServerName(ctx context.Context, req v1.EditServerNames)
 	return nil
 }
 
-func (s *cdnService) AddSSLPolicy(ctx context.Context, sslCertId int64) error  {
+// 添加ssl策略
+func (s *cdnService) AddSSLPolicy(ctx context.Context, req v1.AddSSLPolicy) (int64, error) {
 	formData := map[string]interface{}{
-
-}
+		"http2Enabled":     req.Http2Enabled,
+		"http3Enabled":     req.Http3Enabled,
+		"minVersion":       req.MinVersion,
+		"sslCertsJSON":     req.SslCertsJSON,
+		"hstsJSON":         req.HstsJSON,
+		"clientAuthType":   req.ClientAuthType,
+		"cipherSuites":     req.CipherSuites,
+		"cipherSuitesIsOn": req.CipherSuitesIsOn,
+		"ocspIsOn":         req.OcspIsOn,
+	}
+	apiUrl := s.Url + "SSLPolicyService/createSSLPolicy"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return 0, err
+	}
+	type DataStr struct {
+		SslPolicyId int64 `json:"sslPolicyId" form:"sslPolicyId"`
+	}
+	var res v1.GeneralResponse[DataStr]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return res.Data.SslPolicyId, nil
+}

+ 103 - 112
internal/service/webforwarding.go

@@ -44,14 +44,14 @@ func NewWebForwardingService(
 		wafformatter:            wafformatter,
 		aoDun:                   aoDun,
 		mq:                      mq,
-		gatewayGroupIpRep:        gatewayGroupIpRep,
-		gatewayGroupRep:           gatewayGroupRep,
+		gatewayGroupIpRep:       gatewayGroupIpRep,
+		gatewayGroupRep:         gatewayGroupRep,
 		cdn:                     cdn,
 	}
 }
 
 const (
-	isHttps         = 1
+	isHttps              = 1
 	protocolHttps        = "https"
 	protocolHttp         = "http"
 	defaultNodeClusterId = 1
@@ -66,15 +66,12 @@ type webForwardingService struct {
 	wafformatter            WafFormatterService
 	aoDun                   AoDunService
 	mq                      *rabbitmq.RabbitMQ
-	gatewayGroupIpRep        repository.GateWayGroupIpRepository
-	gatewayGroupRep           repository.GatewayGroupRepository
+	gatewayGroupIpRep       repository.GateWayGroupIpRepository
+	gatewayGroupRep         repository.GatewayGroupRepository
 	cdn                     CdnService
 }
 
-
-
-
-func (s *webForwardingService) require(ctx context.Context,req v1.GlobalRequire) (v1.GlobalRequire, error) {
+func (s *webForwardingService) require(ctx context.Context, req v1.GlobalRequire) (v1.GlobalRequire, error) {
 	var err error
 	var res v1.GlobalRequire
 	g, gCtx := errgroup.WithContext(ctx)
@@ -95,7 +92,7 @@ func (s *webForwardingService) require(ctx context.Context,req v1.GlobalRequire)
 		}
 		return nil
 	})
-	if err 		= g.Wait(); err != nil {
+	if err = g.Wait(); err != nil {
 		return v1.GlobalRequire{}, err
 	}
 	return res, nil
@@ -133,48 +130,43 @@ func (s *webForwardingService) GetWebForwarding(ctx context.Context, req v1.GetF
 	}
 
 	return v1.WebForwardingDataRequest{
-		Id:                  webForwarding.Id,
-		Port:                webForwarding.Port,
-		Domain:              webForwarding.Domain,
-		IsHttps:             webForwarding.IsHttps,
-		Comment:             webForwarding.Comment,
-		BackendList:         backend.BackendList,
-		HttpsKey: 			webForwarding.HttpsKey,
-		HttpsCert: 			webForwarding.HttpsCert,
+		Id:          webForwarding.Id,
+		Port:        webForwarding.Port,
+		Domain:      webForwarding.Domain,
+		IsHttps:     webForwarding.IsHttps,
+		Comment:     webForwarding.Comment,
+		BackendList: backend.BackendList,
+		HttpsKey:    webForwarding.HttpsKey,
+		HttpsCert:   webForwarding.HttpsCert,
 	}, nil
 }
 
-
 // buildWebForwardingModel 辅助函数,用于构建通用的 WebForwarding 模型
 // ruleId 是从 WAF 系统获取的 ID
-func (s *webForwardingService) buildWebForwardingModel(req *v1.WebForwardingDataRequest,ruleId int, require RequireResponse) *model.WebForwarding {
+func (s *webForwardingService) buildWebForwardingModel(req *v1.WebForwardingDataRequest, ruleId int, require RequireResponse) *model.WebForwarding {
 	return &model.WebForwarding{
-		HostId:      require.HostId,
-		CdnWebId:    ruleId,
-		Port:        req.Port,
-		Domain:      req.Domain,
-		IsHttps:     req.IsHttps,
-		Comment:     req.Comment,
-		HttpsCert:   req.HttpsCert,
-		HttpsKey:    req.HttpsKey,
+		HostId:    require.HostId,
+		CdnWebId:  ruleId,
+		Port:      req.Port,
+		Domain:    req.Domain,
+		IsHttps:   req.IsHttps,
+		Comment:   req.Comment,
+		HttpsCert: req.HttpsCert,
+		HttpsKey:  req.HttpsKey,
 		SslCertId: int(req.SslCertId),
 	}
 }
 
 func (s *webForwardingService) buildWebRuleModel(reqData *v1.WebForwardingDataRequest, require RequireResponse, localDbId int, cdnOriginIds map[string]int64) *model.WebForwardingRule {
 	return &model.WebForwardingRule{
-		Uid:         require.Uid,
-		HostId:      require.HostId,
-		WebId:       localDbId,
+		Uid:          require.Uid,
+		HostId:       require.HostId,
+		WebId:        localDbId,
 		CdnOriginIds: cdnOriginIds,
-		BackendList: reqData.BackendList,
+		BackendList:  reqData.BackendList,
 	}
 }
 
-
-
-
-
 // =================================================================
 // 主函数:prepareWafData
 // 职责:协调整个流程,负责获取前置配置和组装最终的 formData。
@@ -201,14 +193,14 @@ func (s *webForwardingService) prepareWafData(ctx context.Context, req *v1.WebFo
 
 	type serverNames struct {
 		ServerNames string `json:"name" form:"name"`
-		Type string `json:"type" form:"type"`
+		Type        string `json:"type" form:"type"`
 	}
 	var serverName []serverNames
 	var serverJson []byte
 	if req.WebForwardingData.Domain != "" {
 		serverName = append(serverName, serverNames{
 			ServerNames: req.WebForwardingData.Domain,
-			Type: "full",
+			Type:        "full",
 		})
 		serverJson, err = json.Marshal(serverName)
 		if err != nil {
@@ -218,14 +210,14 @@ func (s *webForwardingService) prepareWafData(ctx context.Context, req *v1.WebFo
 
 	// 3. 组装最终的 WAF 表单数据
 	formData := v1.Website{
-		UserId:         int64(require.CdnUid),
-		Type:           "httpProxy",
-		Name:           require.Tag,
-		ServerNamesJSON : serverJson,
-		Description:    req.WebForwardingData.Comment,
-		ServerGroupIds: []int64{int64(require.GroupId)},
-		UserPlanId:     int64(require.RuleId),
-		NodeClusterId:  defaultNodeClusterId,
+		UserId:          int64(require.CdnUid),
+		Type:            "httpProxy",
+		Name:            require.Tag,
+		ServerNamesJSON: serverJson,
+		Description:     req.WebForwardingData.Comment,
+		ServerGroupIds:  []int64{int64(require.GroupId)},
+		UserPlanId:      int64(require.RuleId),
+		NodeClusterId:   defaultNodeClusterId,
 	}
 
 	var noSslByteData, _ = json.Marshal(v1.TypeJSON{IsOn: false})
@@ -242,7 +234,6 @@ func (s *webForwardingService) prepareWafData(ctx context.Context, req *v1.WebFo
 	return require, formData, nil
 }
 
-
 // =================================================================
 // 辅助函数:buildProxyJSONConfig
 // 职责:专门负责处理 HTTP/HTTPS 的差异,并生成对应的 JSON 配置。
@@ -258,8 +249,8 @@ func (s *webForwardingService) buildProxyJSONConfig(ctx context.Context, req *v1
 	// 判断协议类型,并处理 HTTPS 的特殊逻辑(证书)
 	if req.WebForwardingData.IsHttps == isHttps {
 		apiType = protocolHttps
-
-		req.WebForwardingData.SslCertId, err = s.cdn.AddSSLCert(ctx, v1.SSlCert{
+		// 添加 SSL 证书
+		sslCertId, err := s.cdn.AddSSLCert(ctx, v1.SSlCert{
 			UserId:       int64(require.CdnUid),
 			Name:         req.WebForwardingData.Domain,
 			Description:  req.WebForwardingData.Comment,
@@ -268,10 +259,36 @@ func (s *webForwardingService) buildProxyJSONConfig(ctx context.Context, req *v1
 			IsSelfSigned: false,
 		})
 		if err != nil {
-			return  nil, fmt.Errorf("添加SSL证书失败: %w", err)
+			return nil, fmt.Errorf("添加SSL证书失败: %w", err)
+		}
+
+		// 添加 SSL 策略
+		if sslCertId != 0 {
+			type sslCerts struct {
+				IsOn   bool  `json:"isOn" form:"isOn"`
+				CertId int64 `json:"certId" form:"certId"`
+			}
+			var sslCertsSlice []sslCerts
+			sslCertsSlice = append(sslCertsSlice, sslCerts{
+				IsOn:   true,
+				CertId: sslCertId,
+			})
+			sslCertsJson, err := json.Marshal(sslCertsSlice)
+			if err != nil {
+				return nil, fmt.Errorf("序列化SSL证书失败: %w", err)
+			}
+
+			sslPolicyId, err := s.cdn.AddSSLPolicy(ctx, v1.AddSSLPolicy{
+				Http2Enabled: true,
+				SslCertsJSON: sslCertsJson,
+				MinVersion:   "TLS 1.1",
+			})
+			if err != nil {
+				return nil, fmt.Errorf("添加SSL策略失败: %w", err)
+			}
+			jsonData.SslPolicyRef.SslPolicyId = sslPolicyId
 		}
 		jsonData.SslPolicyRef.IsOn = true
-		jsonData.SslPolicyRef.SslPolicyId = req.WebForwardingData.SslCertId
 	} else {
 		apiType = protocolHttp
 	}
@@ -291,11 +308,11 @@ func (s *webForwardingService) buildProxyJSONConfig(ctx context.Context, req *v1
 		return nil, fmt.Errorf("序列化WAF配置失败: %w", err)
 	}
 
-	return  byteData, nil
+	return byteData, nil
 }
 
 // 查找两个列表的差异
-func (s webForwardingService) FindDifferenceList (oldList, newList []v1.BackendList) (added, removed []v1.BackendList) {
+func (s webForwardingService) FindDifferenceList(oldList, newList []v1.BackendList) (added, removed []v1.BackendList) {
 	diff := make(map[v1.BackendList]int)
 
 	// 1. 遍历旧列表,为每个元素计数 +1
@@ -323,8 +340,6 @@ func (s webForwardingService) FindDifferenceList (oldList, newList []v1.BackendL
 	return added, removed
 }
 
-
-
 func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.WebForwardingRequest) error {
 	require, formData, err := s.prepareWafData(ctx, req)
 	if err != nil {
@@ -340,7 +355,7 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 		return err
 	}
 	backendList := make(map[string]string)
-	for _,k := range req.WebForwardingData.BackendList {
+	for _, k := range req.WebForwardingData.BackendList {
 		backendList[k.Addr] = k.CustomHost
 	}
 	// 添加源站
@@ -367,7 +382,7 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 		}
 
 		id, err := s.wafformatter.AddOrigin(ctx, v1.WebJson{
-			ApiType:  apiType,
+			ApiType:     apiType,
 			BackendList: addrPunyPort,
 			Host:        v.CustomHost,
 			Comment:     req.WebForwardingData.Comment,
@@ -392,14 +407,11 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 	if err != nil {
 		return err
 	}
-	webRuleModel := s.buildWebRuleModel(&req.WebForwardingData,require, id, cdnOriginIds)
+	webRuleModel := s.buildWebRuleModel(&req.WebForwardingData, require, id, cdnOriginIds)
 	if _, err = s.webForwardingRepository.AddWebForwardingIps(ctx, *webRuleModel); err != nil {
 		return err
 	}
 
-
-
-
 	if req.WebForwardingData.Domain != "" {
 		// 异步任务:将域名添加到白名单
 		doMain, err := s.wafformatter.ConvertToWildcardDomain(ctx, req.WebForwardingData.Domain)
@@ -409,7 +421,7 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 		if len(require.GatewayIps) == 0 {
 			return fmt.Errorf("网关组不存在")
 		}
-		firstIp,err :=  s.GetGatewayFirstIp(ctx, require.HostId)
+		firstIp, err := s.GetGatewayFirstIp(ctx, require.HostId)
 		if err != nil {
 			return err
 		}
@@ -425,15 +437,11 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 			if err != nil {
 				return err
 			}
-			ips = append(ips,ip)
+			ips = append(ips, ip)
 		}
-		go s.wafformatter.PublishIpWhitelistTask(ips, "add","","white")
+		go s.wafformatter.PublishIpWhitelistTask(ips, "add", "", "white")
 	}
 
-
-
-
-
 	return nil
 }
 
@@ -441,7 +449,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 
 	require, formData, err := s.prepareWafData(ctx, req)
 	if err != nil {
-		return  err
+		return err
 	}
 
 	oldData, err := s.webForwardingRepository.GetWebForwarding(ctx, int64(req.WebForwardingData.Id))
@@ -456,7 +464,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 		if req.WebForwardingData.IsHttps == isHttps {
 			typeJson = formData.HttpsJSON
 			apiType = protocolHttps
-		}else {
+		} else {
 			typeJson = formData.HttpJSON
 			apiType = protocolHttp
 		}
@@ -471,7 +479,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 
 	//修改网站域名
 	if oldData.Domain != req.WebForwardingData.Domain {
-		type serverName struct{
+		type serverName struct {
 			Name string `json:"name" form:"name"`
 			Type string `json:"type" form:"type"`
 		}
@@ -486,7 +494,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 			return err
 		}
 		err = s.cdn.EditServerName(ctx, v1.EditServerNames{
-			ServerId: int64(oldData.CdnWebId),
+			ServerId:        int64(oldData.CdnWebId),
 			ServerNamesJSON: serverJson,
 		})
 		if err != nil {
@@ -502,9 +510,6 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 		}
 	}
 
-
-
-
 	// 将域名添加到白名单
 	webData, err := s.webForwardingRepository.GetWebForwarding(ctx, int64(req.WebForwardingData.Id))
 	if err != nil {
@@ -513,7 +518,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 
 	// 异步任务:将域名添加到白名单
 	if webData.Domain != req.WebForwardingData.Domain {
-		firstIp,err :=  s.GetGatewayFirstIp(ctx, req.HostId)
+		firstIp, err := s.GetGatewayFirstIp(ctx, req.HostId)
 		if err != nil {
 			return err
 		}
@@ -565,7 +570,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 	}
 	addedIps, removedIps := s.wafformatter.findIpDifferences(oldIps, newIps)
 	if len(addedIps) > 0 {
-		go s.wafformatter.PublishIpWhitelistTask(addedIps, "add","","white")
+		go s.wafformatter.PublishIpWhitelistTask(addedIps, "add", "", "white")
 	}
 
 	// IP过白
@@ -582,8 +587,6 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 		}
 	}
 
-
-
 	//修改源站
 	addOrigins, delOrigins := s.FindDifferenceList(ipData.BackendList, req.WebForwardingData.BackendList)
 	addedIds := make(map[string]int64)
@@ -591,14 +594,14 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 		var apiType string
 		if v.IsHttps == isHttps {
 			apiType = protocolHttps
-		}else {
+		} else {
 			apiType = protocolHttp
 		}
-		id, err := s.wafformatter.AddOrigin(ctx,v1.WebJson{
-			ApiType: apiType,
+		id, err := s.wafformatter.AddOrigin(ctx, v1.WebJson{
+			ApiType:     apiType,
 			BackendList: v.Addr,
-			Host: v.CustomHost,
-			Comment: req.WebForwardingData.Comment,
+			Host:        v.CustomHost,
+			Comment:     req.WebForwardingData.Comment,
 		})
 		if err != nil {
 			return err
@@ -612,7 +615,6 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 		}
 	}
 
-
 	for k, v := range ipData.CdnOriginIds {
 		for _, ip := range delOrigins {
 			if k == ip.Addr {
@@ -632,7 +634,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 	if err = s.webForwardingRepository.EditWebForwarding(ctx, webModel); err != nil {
 		return err
 	}
-	webRuleModel := s.buildWebRuleModel(&req.WebForwardingData, require, req.WebForwardingData.Id,ipData.CdnOriginIds)
+	webRuleModel := s.buildWebRuleModel(&req.WebForwardingData, require, req.WebForwardingData.Id, ipData.CdnOriginIds)
 	if err = s.webForwardingRepository.EditWebForwardingIps(ctx, *webRuleModel); err != nil {
 		return err
 	}
@@ -651,12 +653,8 @@ func (s *webForwardingService) DeleteWebForwarding(ctx context.Context, Ids []in
 			return err
 		}
 
-
-
-
-
 		// 异步任务:将域名添加到白名单
-		firstIp,err :=  s.GetGatewayFirstIp(ctx, oldData.HostId)
+		firstIp, err := s.GetGatewayFirstIp(ctx, oldData.HostId)
 		if err != nil {
 			return err
 		}
@@ -666,7 +664,7 @@ func (s *webForwardingService) DeleteWebForwarding(ctx context.Context, Ids []in
 			if err != nil {
 				return err
 			}
-			go s.wafformatter.PublishDomainWhitelistTask(doMain,firstIp, "del")
+			go s.wafformatter.PublishDomainWhitelistTask(doMain, firstIp, "del")
 		}
 		// IP过白
 		ipData, err := s.webForwardingRepository.GetWebForwardingIpsByID(ctx, Id)
@@ -695,10 +693,6 @@ func (s *webForwardingService) DeleteWebForwarding(ctx context.Context, Ids []in
 			}
 		}
 
-
-
-
-
 		if err = s.webForwardingRepository.DeleteWebForwarding(ctx, int64(Id)); err != nil {
 			return err
 		}
@@ -752,7 +746,6 @@ func (s *webForwardingService) GetWebForwardingWafWebAllIps(ctx context.Context,
 				return localErr
 			}
 
-
 			// 2. 获取 Backend IP 信息
 			// 注意:这里我们允许 GetWebForwardingIpsByID 可能返回 nil 数据(例如没有规则)而不是错误
 			// 如果它也可能返回错误,则处理方式与上面类似
@@ -807,15 +800,14 @@ func (s *webForwardingService) GetWebForwardingWafWebAllIps(ctx context.Context,
 			return nil, fmt.Errorf("received nil forwarding from goroutine for ID %d", res.Id)
 		}
 
-
 		dataReq := v1.WebForwardingDataRequest{
-			Id:                  res.Forwarding.Id,
-			Port:                res.Forwarding.Port,
-			Domain:              res.Forwarding.Domain,
-			IsHttps:             res.Forwarding.IsHttps,
-			Comment:             res.Forwarding.Comment,
-			HttpsKey:            res.Forwarding.HttpsKey,
-			HttpsCert:           res.Forwarding.HttpsCert,
+			Id:        res.Forwarding.Id,
+			Port:      res.Forwarding.Port,
+			Domain:    res.Forwarding.Domain,
+			IsHttps:   res.Forwarding.IsHttps,
+			Comment:   res.Forwarding.Comment,
+			HttpsKey:  res.Forwarding.HttpsKey,
+			HttpsCert: res.Forwarding.HttpsCert,
 		}
 
 		if res.BackendRule != nil { // 只有当 BackendRule 存在时才填充相关字段
@@ -836,37 +828,36 @@ func (s *webForwardingService) GetGatewayFirstIp(ctx context.Context, hostId int
 		return "", err
 	}
 	if gateWayGroup == nil {
-		return  "",fmt.Errorf("网关组不存在")
+		return "", fmt.Errorf("网关组不存在")
 	}
 	gateWayIps, err := s.gatewayGroupIpRep.GetGateWayGroupFirstIpByGatewayGroupId(ctx, gateWayGroup.Id)
 	if err != nil {
 		return "", err
 	}
 	if len(gateWayIps) == 0 {
-		return  "",fmt.Errorf("网关组IP为空")
+		return "", fmt.Errorf("网关组IP为空")
 	}
 	return gateWayIps, nil
 }
 
-
 // 清洗IP
-func (s *webForwardingService) WashDifferentIp(newIpList []string, oldIpList []string) (addedDenyIps []string,removedDenyIps []string) {
+func (s *webForwardingService) WashDifferentIp(newIpList []string, oldIpList []string) (addedDenyIps []string, removedDenyIps []string) {
 	var newAllowIps []string
 	var oldAllowIps []string
 	if len(oldIpList) > 0 {
 		for _, v := range oldIpList {
-			if net.ParseIP(v) != nil{
+			if net.ParseIP(v) != nil {
 				oldAllowIps = append(oldAllowIps, v)
 			}
 		}
 	}
 	if len(newIpList) > 0 {
 		for _, v := range newIpList {
-			if net.ParseIP(v) != nil{
+			if net.ParseIP(v) != nil {
 				newAllowIps = append(newAllowIps, v)
 			}
 		}
 	}
 	addedDenyIps, removedDenyIps = s.wafformatter.findIpDifferences(oldAllowIps, newAllowIps)
 	return addedDenyIps, removedDenyIps
-}
+}