cdn.go 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. package flexCdn
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  7. "github.com/go-nunu/nunu-layout-advanced/api/v1/cdn"
  8. "github.com/go-nunu/nunu-layout-advanced/internal/repository/api/flexCdn"
  9. "github.com/go-nunu/nunu-layout-advanced/internal/service"
  10. "github.com/spf13/viper"
  11. "strings"
  12. )
  13. type CdnService interface {
  14. // GetToken 获取token
  15. GetToken(ctx context.Context) (string, error)
  16. // AddUser 注册用户
  17. AddUser(ctx context.Context, req v1.User) (int64, error)
  18. CreateGroup(ctx context.Context, req v1.Group) (int64, error)
  19. BindPlan(ctx context.Context, req v1.Plan) (int64, error)
  20. // 续费套餐
  21. RenewPlan(ctx context.Context, req v1.RenewalPlan) error
  22. CreateWebsite(ctx context.Context, req v1.WebsiteSend) (int64, error)
  23. EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error
  24. EditProtocol(ctx context.Context, req v1.ProxyJson, action string) error
  25. CreateOrigin(ctx context.Context, req v1.Origin) (int64, error)
  26. EditOrigin(ctx context.Context, req v1.Origin) error
  27. AddServerOrigin(ctx context.Context, serverId int64, originId int64) error
  28. EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error
  29. // 修改网站基本信息
  30. EditServerBasic(ctx context.Context, serverId int64, name string,nodeId int64) error
  31. // 从网站中删除某个源站
  32. DelServerOrigin(ctx context.Context, serverId int64, originId int64) error
  33. // 删除网站
  34. DelServer(ctx context.Context, serverId int64) error
  35. // 添加ssl证书
  36. AddSSLCert(ctx context.Context, req v1.SSlCert) (int64, error)
  37. // 修改网站域名
  38. EditServerName(ctx context.Context, req v1.EditServerNames) error
  39. // 添加ssl策略
  40. AddSSLPolicy(ctx context.Context, req v1.AddSSLPolicy) (int64, error)
  41. DelSSLCert(ctx context.Context, sslCertId int64) error
  42. EditSSLCert(ctx context.Context, req v1.SSlCert) error
  43. EditSSLPolicy(ctx context.Context, req v1.SSLPolicy) error
  44. // 修改反向代理
  45. EditProxy(ctx context.Context, req v1.Proxy) error
  46. // 修改日志
  47. EditWebLog(ctx context.Context,webId int64, req v1.WebLog) error
  48. // 修改CC配置
  49. EditCcConfig(ctx context.Context,webId int64, req v1.CcConfig) error
  50. // 添加webSocket
  51. AddWebSockets(ctx context.Context, req v1.WebSocket) (int64,error)
  52. // 修改webSocket
  53. EditWebSockets(ctx context.Context, req v1.WebSocket) error
  54. // 启用webSocket
  55. EditHTTPWebWebsocket(ctx context.Context,websocketId int64,websocketJSON []byte) error
  56. // 启用/禁用网站
  57. EditWebIsOn(ctx context.Context,serverId int64,isOn bool) error
  58. // 删除已购套餐
  59. DelUserPlan(ctx context.Context,planId int64) error
  60. // 删除网站分组
  61. DelServerGroup(ctx context.Context,serverId int64) error
  62. // 删除IP
  63. DelIpItem(ctx context.Context,ipitemId int64,value string,ipFrom string,ipTo string,ipListId int64) error
  64. // 创建空防火墙策略
  65. AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int64, error)
  66. // 更改防火墙设置
  67. EditHTTPWebFirewal(ctx context.Context,httpWebId int64,FirewallJSON v1.Firewall) error
  68. // 创建IP列表
  69. AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error)
  70. // 添加IP
  71. AddIpItem(ctx context.Context, req v1.AddIpItem) error
  72. // 修改IP
  73. EditIpItem(ctx context.Context, req v1.AddIpItem) error
  74. // 获取访问日志
  75. GetAccessLog(ctx context.Context, req cdn.Request) (cdn.Data, error)
  76. }
  77. func NewCdnService(
  78. service *service.Service,
  79. conf *viper.Viper,
  80. request service.RequestService,
  81. cdnRepository flexCdn.CdnRepository,
  82. ) CdnService {
  83. return &cdnService{
  84. Service: service,
  85. Url: conf.GetString("flexCdn.Url"),
  86. AccessKeyID: conf.GetString("flexCdn.AccessKeyID"),
  87. AccessKeySecret: conf.GetString("flexCdn.AccessKeySecret"),
  88. request: request,
  89. cdnRepository: cdnRepository,
  90. maxRetryCount: 3, // 可以配置最大重试次数
  91. retryDelaySeconds: 2, // 可以配置重试间隔
  92. }
  93. }
  94. type cdnService struct {
  95. *service.Service
  96. Url string
  97. AccessKeyID string
  98. AccessKeySecret string
  99. request service.RequestService
  100. cdnRepository flexCdn.CdnRepository
  101. maxRetryCount int
  102. retryDelaySeconds int
  103. }
  104. // SendData 是一个通用的请求发送方法,它封装了 token 过期重试的逻辑
  105. func (s *cdnService) sendDataWithTokenRetry(ctx context.Context, formData map[string]interface{}, apiUrl string) ([]byte, error) {
  106. var resBody []byte
  107. for i := 0; i < s.maxRetryCount; i++ {
  108. token, err := s.Token(ctx) // 确保使用最新的 token
  109. if err != nil {
  110. return nil, fmt.Errorf("获取或刷新 token 失败: %w", err)
  111. }
  112. resBody, err = s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", token)
  113. if err != nil {
  114. // 检查错误是否是由于 token 无效引起的
  115. if s.isTokenInvalidError(resBody, err) { // 判断是否是 token 无效错误
  116. _, getTokenErr := s.GetToken(ctx)
  117. if getTokenErr != nil {
  118. return nil, fmt.Errorf("刷新 token 失败: %w", getTokenErr)
  119. }
  120. continue // 继续下一次循环,使用新的 token
  121. }
  122. return nil, fmt.Errorf("请求失败: %w", err)
  123. }
  124. // 成功获取到响应,处理响应体
  125. var generalResponse v1.GeneralResponse[any]
  126. if err := json.Unmarshal(resBody, &generalResponse); err != nil {
  127. return nil, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  128. }
  129. // 检查 API 返回的 code 和 message
  130. if generalResponse.Code == 400 && generalResponse.Message == "invalid access token" {
  131. fmt.Printf("尝试 %d/%d:API 返回无效 token 错误,准备刷新并重试...\n", i+1, s.maxRetryCount)
  132. _, getTokenErr := s.GetToken(ctx)
  133. if getTokenErr != nil {
  134. return nil, fmt.Errorf("刷新 token 失败: %w", getTokenErr)
  135. }
  136. continue // 继续下一次循环,使用新的 token
  137. }
  138. // 成功处理,返回结果
  139. return resBody, nil
  140. }
  141. // 如果循环结束仍未成功,则返回最终错误
  142. return nil, fmt.Errorf("达到最大重试次数后请求仍然失败")
  143. }
  144. // isTokenInvalidError 是一个辅助函数,用于判断错误是否是由于 token 无效引起的。
  145. // 你需要根据你的 request.Request 实现来具体实现这个函数。
  146. // 例如,你可以检查 resBody 是否包含特定的错误信息。
  147. func (s *cdnService) isTokenInvalidError(resBody []byte, err error) bool {
  148. // 示例:如果请求本身就返回了非 200 的错误,并且响应体中有特定信息
  149. if err != nil {
  150. // 尝试从 resBody 中解析出错误信息,判断是否是 token 无效
  151. var generalResponse v1.GeneralResponse[any]
  152. if parseErr := json.Unmarshal(resBody, &generalResponse); parseErr == nil {
  153. if generalResponse.Code == 400 && generalResponse.Message == "invalid access token" {
  154. return true
  155. }
  156. }
  157. // 或者检查 err 本身是否有相关的错误信息
  158. // if strings.Contains(err.Error(), "invalid access token") {
  159. // return true
  160. // }
  161. }
  162. return false
  163. }
  164. func (s *cdnService) GetToken(ctx context.Context) (string, error) {
  165. formData := map[string]interface{}{
  166. "type": "admin",
  167. "accessKeyId": s.AccessKeyID,
  168. "accessKey": s.AccessKeySecret,
  169. }
  170. apiUrl := s.Url + "APIAccessTokenService/getAPIAccessToken"
  171. resBody, err := s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", "")
  172. if err != nil {
  173. return "", err
  174. }
  175. var res v1.GeneralResponse[v1.FlexCdnTokenResponse]
  176. if err := json.Unmarshal(resBody, &res); err != nil {
  177. return "", fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  178. }
  179. if res.Code != 200 {
  180. return "", fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  181. }
  182. err = s.cdnRepository.PutToken(ctx, res.Data.Token)
  183. if err != nil {
  184. return "", err
  185. }
  186. return res.Data.Token, nil
  187. }
  188. func (s *cdnService) Token(ctx context.Context) (string, error) {
  189. token, err := s.cdnRepository.GetToken(ctx)
  190. if err != nil {
  191. return "", err
  192. }
  193. if token == "" {
  194. token, err = s.GetToken(ctx)
  195. if err != nil {
  196. return "", err
  197. }
  198. }
  199. return token, nil
  200. }
  201. // 注册用户
  202. func (s *cdnService) AddUser(ctx context.Context, req v1.User) (int64, error) {
  203. formData := map[string]interface{}{
  204. "id": req.ID,
  205. "username": req.Username,
  206. "password": "a7fKiKujgAzzsJ6", // 这个密码应该被妥善管理,而不是硬编码
  207. "fullname": req.Fullname,
  208. "mobile": req.Mobile,
  209. "tel": req.Tel,
  210. "email": req.Email,
  211. "remark": req.Remark,
  212. "source": req.Source,
  213. "nodeClusterId": 2,
  214. }
  215. apiUrl := s.Url + "UserService/createUser"
  216. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  217. if err != nil {
  218. return 0, err
  219. }
  220. type DataStr struct {
  221. UserId int64 `json:"userId" form:"userId"`
  222. }
  223. var res v1.GeneralResponse[DataStr]
  224. if err := json.Unmarshal(resBody, &res); err != nil {
  225. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  226. }
  227. if res.Code != 200 {
  228. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  229. }
  230. if res.Data.UserId == 0 {
  231. return 0, fmt.Errorf("添加用户失败")
  232. }
  233. return res.Data.UserId, nil
  234. }
  235. // 创建规则分组
  236. func (s *cdnService) CreateGroup(ctx context.Context, req v1.Group) (int64, error) {
  237. formData := map[string]interface{}{
  238. "name": req.Name,
  239. }
  240. apiUrl := s.Url + "ServerGroupService/createServerGroup"
  241. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  242. if err != nil {
  243. return 0, err
  244. }
  245. type DataStr struct {
  246. ServerGroupId int64 `json:"serverGroupId" form:"serverGroupId"`
  247. }
  248. var res v1.GeneralResponse[DataStr]
  249. if err := json.Unmarshal(resBody, &res); err != nil {
  250. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  251. }
  252. if res.Code != 200 {
  253. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  254. }
  255. if res.Data.ServerGroupId == 0 {
  256. return 0, fmt.Errorf("创建规则分组失败")
  257. }
  258. return res.Data.ServerGroupId, nil
  259. }
  260. // 分配套餐
  261. func (s *cdnService) BindPlan(ctx context.Context, req v1.Plan) (int64, error) {
  262. formData := map[string]interface{}{
  263. "userId": req.UserId,
  264. "planId": req.PlanId,
  265. "dayTo": req.DayTo,
  266. "period": req.Period,
  267. "countPeriod": req.CountPeriod,
  268. "name": req.Name,
  269. "isFree": req.IsFree,
  270. "periodDayTo": req.PeriodDayTo,
  271. }
  272. apiUrl := s.Url + "UserPlanService/buyUserPlan"
  273. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  274. if err != nil {
  275. return 0, err
  276. }
  277. type DataStr struct {
  278. UserPlanId int64 `json:"userPlanId" form:"userPlanId"`
  279. }
  280. var res v1.GeneralResponse[DataStr]
  281. if err := json.Unmarshal(resBody, &res); err != nil {
  282. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  283. }
  284. if res.Code != 200 {
  285. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  286. }
  287. if res.Data.UserPlanId == 0 {
  288. return 0, fmt.Errorf("分配套餐失败")
  289. }
  290. return res.Data.UserPlanId, nil
  291. }
  292. // 续费套餐
  293. func (s *cdnService) RenewPlan(ctx context.Context, req v1.RenewalPlan) error {
  294. formData := map[string]interface{}{
  295. "userPlanId": req.UserPlanId,
  296. "dayTo": req.DayTo,
  297. "period": req.Period,
  298. "countPeriod": req.CountPeriod,
  299. "isFree": req.IsFree,
  300. "periodDayTo": req.PeriodDayTo,
  301. }
  302. apiUrl := s.Url + "UserPlanService/renewUserPlan"
  303. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  304. if err != nil {
  305. return err
  306. }
  307. var res v1.GeneralResponse[any]
  308. if err := json.Unmarshal(resBody, &res); err != nil {
  309. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  310. }
  311. if res.Code != 200 {
  312. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  313. }
  314. return nil
  315. }
  316. // 创建网站
  317. func (s *cdnService) CreateWebsite(ctx context.Context, req v1.WebsiteSend) (int64, error) {
  318. formData := map[string]interface{}{
  319. "userId": req.UserId,
  320. "type": req.Type,
  321. "name": req.Name,
  322. "description": req.Description,
  323. "serverNamesJSON": req.ServerNamesJSON,
  324. "httpJSON": req.HttpJSON,
  325. "httpsJSON": req.HttpsJSON,
  326. "tcpJSON": req.TcpJSON,
  327. "tlsJSON": req.TlsJSON,
  328. "udpJSON": req.UdpJSON,
  329. "webId": req.WebId,
  330. "reverseProxyJSON": req.ReverseProxyJSON,
  331. "serverGroupIds": req.ServerGroupIds,
  332. "userPlanId": req.UserPlanId,
  333. "nodeClusterId": req.NodeClusterId,
  334. }
  335. apiUrl := s.Url + "ServerService/createServer"
  336. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  337. if err != nil {
  338. return 0, err
  339. }
  340. type DataStr struct {
  341. ServerId int64 `json:"serverId" form:"serverId"`
  342. }
  343. var res v1.GeneralResponse[DataStr]
  344. if err := json.Unmarshal(resBody, &res); err != nil {
  345. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  346. }
  347. if res.Code != 200 {
  348. return 0, fmt.Errorf("创建网站API 错误: code %d, msg '%s'", res.Code, res.Message)
  349. }
  350. if res.Data.ServerId == 0 {
  351. return 0, fmt.Errorf("创建网站失败")
  352. }
  353. return res.Data.ServerId, nil
  354. }
  355. func (s *cdnService) EditProtocol(ctx context.Context, req v1.ProxyJson, action string) error {
  356. formData := map[string]interface{}{
  357. "serverId": req.ServerId,
  358. }
  359. var apiUrl string
  360. switch action {
  361. case "tcp":
  362. formData["tcpJSON"] = req.JSON
  363. apiUrl = s.Url + "ServerService/updateServerTCP"
  364. case "tls":
  365. formData["tlsJSON"] = req.JSON
  366. apiUrl = s.Url + "ServerService/updateServerTLS"
  367. case "udp":
  368. formData["udpJSON"] = req.JSON
  369. apiUrl = s.Url + "ServerService/updateServerUDP"
  370. case "http":
  371. formData["httpJSON"] = req.JSON
  372. apiUrl = s.Url + "ServerService/updateServerHTTP"
  373. case "https":
  374. formData["httpsJSON"] = req.JSON
  375. apiUrl = s.Url + "ServerService/updateServerHTTPS"
  376. default:
  377. return fmt.Errorf("不支持的协议类型")
  378. }
  379. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  380. if err != nil {
  381. return err
  382. }
  383. var res v1.GeneralResponse[any]
  384. if err := json.Unmarshal(resBody, &res); err != nil {
  385. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  386. }
  387. if res.Code != 200 {
  388. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  389. }
  390. return nil
  391. }
  392. func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, error) {
  393. formData := map[string]interface{}{
  394. "name": req.Name,
  395. "addr": req.Addr,
  396. "ossJSON": req.OssJSON,
  397. "description": req.Description,
  398. "weight": req.Weight,
  399. "isOn": req.IsOn,
  400. "domains": req.Domains,
  401. "certRefJSON": req.CertRefJSON,
  402. "host": req.Host,
  403. "followPort": req.FollowPort,
  404. "http2Enabled": req.Http2Enabled,
  405. "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
  406. }
  407. apiUrl := s.Url + "OriginService/createOrigin"
  408. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  409. if err != nil {
  410. return 0, err
  411. }
  412. type DataStr struct {
  413. OriginId int64 `json:"originId" form:"originId"`
  414. }
  415. var res v1.GeneralResponse[DataStr]
  416. if err := json.Unmarshal(resBody, &res); err != nil {
  417. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  418. }
  419. if res.Code != 200 {
  420. return 0, fmt.Errorf("添加源站API 错误: code %d, msg '%s'", res.Code, res.Message)
  421. }
  422. if res.Data.OriginId == 0 {
  423. return 0, fmt.Errorf("创建源站失败")
  424. }
  425. return res.Data.OriginId, nil
  426. }
  427. func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error {
  428. typeName := apiType + "JSON"
  429. formData := map[string]interface{}{
  430. "serverId": req.Id,
  431. typeName: req.TypeJSON,
  432. }
  433. apiUrl := s.Url + "ServerService/updateServer" + strings.ToUpper(apiType)
  434. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  435. if err != nil {
  436. return err
  437. }
  438. var res v1.GeneralResponse[any]
  439. if err := json.Unmarshal(resBody, &res); err != nil {
  440. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  441. }
  442. if res.Code != 200 {
  443. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  444. }
  445. return nil
  446. }
  447. // EditOrigin 编辑源站
  448. func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
  449. formData := map[string]interface{}{
  450. "originId": req.OriginId,
  451. "name": req.Name,
  452. "addr": req.Addr,
  453. "ossJSON": req.OssJSON,
  454. "description": req.Description,
  455. "weight": req.Weight,
  456. "isOn": req.IsOn,
  457. "domains": req.Domains,
  458. "certRefJSON": req.CertRefJSON,
  459. "host": req.Host,
  460. "followPort": req.FollowPort,
  461. "http2Enabled": req.Http2Enabled,
  462. "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
  463. }
  464. apiUrl := s.Url + "OriginService/updateOrigin"
  465. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  466. if err != nil {
  467. return err
  468. }
  469. var res v1.GeneralResponse[any]
  470. if err := json.Unmarshal(resBody, &res); err != nil {
  471. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  472. }
  473. if res.Code != 200 {
  474. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  475. }
  476. return nil
  477. }
  478. // AddServerOrigin 网站绑定源站
  479. func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error {
  480. formData := map[string]interface{}{
  481. "serverId": serverId,
  482. "originId": originId,
  483. "isPrimary": true,
  484. }
  485. apiUrl := s.Url + "ServerService/addServerOrigin"
  486. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  487. if err != nil {
  488. return err
  489. }
  490. var res v1.GeneralResponse[any]
  491. if err := json.Unmarshal(resBody, &res); err != nil {
  492. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  493. }
  494. if res.Code != 200 {
  495. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  496. }
  497. return nil
  498. }
  499. // EditOriginIsOn 编辑源站是否开启
  500. func (s *cdnService) EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error {
  501. formData := map[string]interface{}{
  502. "originId": originId,
  503. "isOn": isOn,
  504. }
  505. apiUrl := s.Url + "OriginService/updateOriginIsOn"
  506. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  507. if err != nil {
  508. return err
  509. }
  510. var res v1.GeneralResponse[any]
  511. if err := json.Unmarshal(resBody, &res); err != nil {
  512. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  513. }
  514. if res.Code != 200 {
  515. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  516. }
  517. return nil
  518. }
  519. // EditServerBasic 修改网站基本信息
  520. func (s *cdnService) EditServerBasic(ctx context.Context, serverId int64, name string,nodeId int64) error {
  521. formData := map[string]interface{}{
  522. "serverId": serverId,
  523. "name": name,
  524. "nodeClusterId": nodeId,
  525. "isOn": true,
  526. }
  527. apiUrl := s.Url + "ServerService/updateServerBasic"
  528. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  529. if err != nil {
  530. return err
  531. }
  532. var res v1.GeneralResponse[any]
  533. if err := json.Unmarshal(resBody, &res); err != nil {
  534. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  535. }
  536. if res.Code != 200 {
  537. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  538. }
  539. return nil
  540. }
  541. // DelServerOrigin 从网站中删除某个源站
  542. func (s *cdnService) DelServerOrigin(ctx context.Context, serverId int64, originId int64) error {
  543. formData := map[string]interface{}{
  544. "serverId": serverId,
  545. "originId": originId,
  546. }
  547. apiUrl := s.Url + "ServerService/deleteServerOrigin"
  548. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  549. if err != nil {
  550. return err
  551. }
  552. var res v1.GeneralResponse[any]
  553. if err := json.Unmarshal(resBody, &res); err != nil {
  554. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  555. }
  556. if res.Code != 200 {
  557. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  558. }
  559. return nil
  560. }
  561. func (s *cdnService) DelServer(ctx context.Context, serverId int64) error {
  562. formData := map[string]interface{}{
  563. "serverId": serverId,
  564. }
  565. apiUrl := s.Url + "ServerService/deleteServer"
  566. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  567. if err != nil {
  568. return err
  569. }
  570. var res v1.GeneralResponse[any]
  571. if err := json.Unmarshal(resBody, &res); err != nil {
  572. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  573. }
  574. if res.Code != 200 {
  575. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  576. }
  577. return nil
  578. }
  579. // AddSSLCert 添加证书
  580. func (s *cdnService) AddSSLCert(ctx context.Context, req v1.SSlCert) (int64, error) {
  581. formData := map[string]interface{}{
  582. "isOn": req.IsOn,
  583. "userId": req.UserId,
  584. "name": req.Name,
  585. "serverName": req.ServerName,
  586. "description": req.Description,
  587. "isCA": req.IsCA,
  588. "certData": req.CertData,
  589. "keyData": req.KeyData,
  590. "timeBeginAt": req.TimeBeginAt,
  591. "timeEndAt": req.TimeEndAt,
  592. "dnsNames": req.DnsNames,
  593. "commonNames": req.CommonNames,
  594. "isSelfSigned": req.IsSelfSigned,
  595. }
  596. apiUrl := s.Url + "SSLCertService/createSSLCert"
  597. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  598. if err != nil {
  599. return 0, err
  600. }
  601. type DataStr struct {
  602. SslCertId int64 `json:"sslCertId" form:"sslCertId"`
  603. }
  604. var res v1.GeneralResponse[DataStr]
  605. if err := json.Unmarshal(resBody, &res); err != nil {
  606. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  607. }
  608. if res.Code != 200 {
  609. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  610. }
  611. return res.Data.SslCertId, nil
  612. }
  613. // 修改网站域名
  614. func (s *cdnService) EditServerName(ctx context.Context, req v1.EditServerNames) error {
  615. formData := map[string]interface{}{
  616. "serverId": req.ServerId,
  617. "serverNamesJSON": req.ServerNamesJSON,
  618. }
  619. apiUrl := s.Url + "ServerService/updateServerNames"
  620. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  621. if err != nil {
  622. return err
  623. }
  624. var res v1.GeneralResponse[any]
  625. if err := json.Unmarshal(resBody, &res); err != nil {
  626. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  627. }
  628. if res.Code != 200 {
  629. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  630. }
  631. return nil
  632. }
  633. // 添加ssl策略
  634. func (s *cdnService) AddSSLPolicy(ctx context.Context, req v1.AddSSLPolicy) (int64, error) {
  635. formData := map[string]interface{}{
  636. "http2Enabled": req.Http2Enabled,
  637. "http3Enabled": req.Http3Enabled,
  638. "minVersion": req.MinVersion,
  639. "sslCertsJSON": req.SslCertsJSON,
  640. "hstsJSON": req.HstsJSON,
  641. "clientAuthType": req.ClientAuthType,
  642. "cipherSuites": req.CipherSuites,
  643. "cipherSuitesIsOn": req.CipherSuitesIsOn,
  644. "ocspIsOn": req.OcspIsOn,
  645. }
  646. apiUrl := s.Url + "SSLPolicyService/createSSLPolicy"
  647. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  648. if err != nil {
  649. return 0, err
  650. }
  651. type DataStr struct {
  652. SslPolicyId int64 `json:"sslPolicyId" form:"sslPolicyId"`
  653. }
  654. var res v1.GeneralResponse[DataStr]
  655. if err := json.Unmarshal(resBody, &res); err != nil {
  656. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  657. }
  658. if res.Code != 200 {
  659. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  660. }
  661. return res.Data.SslPolicyId, nil
  662. }
  663. func (s *cdnService) DelSSLCert(ctx context.Context, sslCertId int64) error {
  664. formData := map[string]interface{}{
  665. "sslCertId": sslCertId,
  666. }
  667. apiUrl := s.Url + "SSLCertService/deleteSSLCert"
  668. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  669. if err != nil {
  670. return err
  671. }
  672. var res v1.GeneralResponse[any]
  673. if err := json.Unmarshal(resBody, &res); err != nil {
  674. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  675. }
  676. if res.Code != 200 {
  677. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  678. }
  679. return nil
  680. }
  681. func (s *cdnService) GetSSLPolicy(ctx context.Context, sslPolicyId int64) (v1.SSLPolicy, error) {
  682. formData := map[string]interface{}{
  683. "sslPolicyId": sslPolicyId,
  684. "ignoreData": true,
  685. }
  686. apiUrl := s.Url + "SSLPolicyService/findEnabledSSLPolicyConfig"
  687. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  688. if err != nil {
  689. return v1.SSLPolicy{}, err
  690. }
  691. var res v1.GeneralResponse[v1.SSLPolicy]
  692. if err := json.Unmarshal(resBody, &res); err != nil {
  693. return v1.SSLPolicy{}, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  694. }
  695. if res.Code != 200 {
  696. return v1.SSLPolicy{}, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  697. }
  698. return res.Data, nil
  699. }
  700. func (s *cdnService) EditSSLCert(ctx context.Context, req v1.SSlCert) error {
  701. formData := map[string]interface{}{
  702. "sslCertId": req.SslCertId,
  703. "userId": req.UserId,
  704. "isOn": req.IsOn,
  705. "name": req.Name,
  706. "description": req.Description,
  707. "isCA": req.IsCA,
  708. "certData": req.CertData,
  709. "keyData": req.KeyData,
  710. "timeBeginAt": req.TimeBeginAt,
  711. "timeEndAt": req.TimeEndAt,
  712. "dnsNames": req.DnsNames,
  713. "commonNames": req.CommonNames,
  714. "isSelfSigned": req.IsSelfSigned,
  715. }
  716. apiUrl := s.Url + "SSLCertService/updateSSLCert"
  717. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  718. if err != nil {
  719. return err
  720. }
  721. var res v1.GeneralResponse[any]
  722. if err := json.Unmarshal(resBody, &res); err != nil {
  723. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  724. }
  725. if res.Code != 200 {
  726. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  727. }
  728. return nil
  729. }
  730. func (s *cdnService) EditSSLPolicy(ctx context.Context, req v1.SSLPolicy) error {
  731. formData := map[string]interface{}{
  732. "sslPolicyId": req.SslPolicyId,
  733. "http2Enabled": req.Http2Enabled,
  734. "http3Enabled": req.Http3Enabled,
  735. "minVersion": req.MinVersion,
  736. "sslCertsJSON": req.SslCertsJSON,
  737. "hstsJSON": req.HstsJSON,
  738. "clientAuthType": req.ClientAuthType,
  739. "cipherSuites": req.CipherSuites,
  740. "cipherSuitesIsOn": req.CipherSuitesIsOn,
  741. }
  742. apiUrl := s.Url + "SSLPolicyService/updateSSLPolicy"
  743. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  744. if err != nil {
  745. return err
  746. }
  747. var res v1.GeneralResponse[any]
  748. if err := json.Unmarshal(resBody, &res); err != nil {
  749. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  750. }
  751. if res.Code != 200 {
  752. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  753. }
  754. return nil
  755. }
  756. // 修改反向代理
  757. func (s *cdnService) EditProxy(ctx context.Context, req v1.Proxy) error {
  758. formData := map[string]interface{}{
  759. "reverseProxyId" : req.ReverseProxyId,
  760. "requestHostType" : req.RequestHostType,
  761. "requestHost" : req.RequestHost,
  762. "requestHostExcludingPort" : req.RequestHostExcludingPort,
  763. "requestURI" : req.RequestURI,
  764. "stripPrefix" : req.StripPrefix,
  765. "autoFlush" : req.AutoFlush,
  766. "addHeaders" : req.AddHeaders,
  767. "proxyProtocolJSON": req.ProxyProtocolJSON,
  768. "followRedirects" : req.FollowRedirects,
  769. "retry50X" : req.Retry50X,
  770. "retry40X" : req.Retry40X,
  771. }
  772. apiUrl := s.Url + "ReverseProxyService/updateReverseProxy"
  773. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  774. if err != nil {
  775. return err
  776. }
  777. var res v1.GeneralResponse[any]
  778. if err := json.Unmarshal(resBody, &res); err != nil {
  779. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  780. }
  781. if res.Code != 200 {
  782. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  783. }
  784. return nil
  785. }
  786. // 修改网站日志配置
  787. func (s *cdnService) EditWebLog(ctx context.Context,webId int64, req v1.WebLog) error {
  788. reqJson, err := json.Marshal(req)
  789. if err != nil {
  790. return err
  791. }
  792. formData := map[string]interface{}{
  793. "httpWebId": webId,
  794. "accessLogJSON": reqJson,
  795. }
  796. apiUrl := s.Url + "HTTPWebService/updateHTTPWebAccessLog"
  797. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  798. if err != nil {
  799. return err
  800. }
  801. var res v1.GeneralResponse[any]
  802. if err := json.Unmarshal(resBody, &res); err != nil {
  803. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  804. }
  805. if res.Code != 200 {
  806. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  807. }
  808. return nil
  809. }
  810. // 修改网站CC配置
  811. func (s *cdnService) EditCcConfig(ctx context.Context,webId int64, req v1.CcConfig) error {
  812. reqJson, err := json.Marshal(req)
  813. if err != nil {
  814. return err
  815. }
  816. formData := map[string]interface{}{
  817. "httpWebId": webId,
  818. "ccJSON": reqJson,
  819. }
  820. apiUrl := s.Url + "HTTPWebService/updateHTTPWebCC"
  821. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  822. if err != nil {
  823. return err
  824. }
  825. var res v1.GeneralResponse[any]
  826. if err := json.Unmarshal(resBody, &res); err != nil {
  827. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  828. }
  829. if res.Code != 200 {
  830. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  831. }
  832. return nil
  833. }
  834. // 创建websockets配置
  835. func (s *cdnService) AddWebSockets(ctx context.Context, req v1.WebSocket) (int64,error) {
  836. formData := map[string]interface{}{
  837. "handshakeTimeoutJSON": req.HandshakeTimeoutJSON,
  838. "allowAllOrigins" : req.AllowAllOrigins,
  839. "allowedOrigins" : req.AllowedOrigins,
  840. "requestSameOrigin" : req.RequestSameOrigin,
  841. "requestOrigin" : req.RequestOrigin,
  842. }
  843. apiUrl := s.Url + "HTTPWebsocketService/createHTTPWebsocket"
  844. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  845. if err != nil {
  846. return 0,err
  847. }
  848. type WebSocket struct {
  849. WebSocketId int64 `json:"websocketId"`
  850. }
  851. var res v1.GeneralResponse[WebSocket]
  852. if err := json.Unmarshal(resBody, &res); err != nil {
  853. return 0,fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  854. }
  855. if res.Code != 200 {
  856. return 0,fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  857. }
  858. return res.Data.WebSocketId,nil
  859. }
  860. func (s *cdnService) EditWebSockets(ctx context.Context,req v1.WebSocket) error {
  861. formData := map[string]interface{}{
  862. "websocketId" : req.WebsocketId,
  863. "handshakeTimeoutJSON": req.HandshakeTimeoutJSON,
  864. "allowAllOrigins" : req.AllowAllOrigins,
  865. "allowedOrigins" : req.AllowedOrigins,
  866. "requestSameOrigin" : req.RequestSameOrigin,
  867. "requestOrigin" : req.RequestOrigin,
  868. }
  869. apiUrl := s.Url + "HTTPWebsocketService/updateHTTPWebsocket"
  870. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  871. if err != nil {
  872. return err
  873. }
  874. var res v1.GeneralResponse[any]
  875. if err := json.Unmarshal(resBody, &res); err != nil {
  876. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  877. }
  878. if res.Code != 200 {
  879. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  880. }
  881. return nil
  882. }
  883. // 启用/禁用websockets
  884. func (s *cdnService) EditHTTPWebWebsocket(ctx context.Context,websocketId int64,websocketJSON []byte) error {
  885. formData := map[string]interface{}{
  886. "httpWebId" : websocketId,
  887. "websocketJSON": websocketJSON,
  888. }
  889. apiUrl := s.Url + "HTTPWebService/updateHTTPWebWebsocket"
  890. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  891. if err != nil {
  892. return err
  893. }
  894. var res v1.GeneralResponse[any]
  895. if err := json.Unmarshal(resBody, &res); err != nil {
  896. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  897. }
  898. if res.Code != 200 {
  899. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  900. }
  901. return nil
  902. }
  903. // 启用/禁用网站
  904. func (s *cdnService) EditWebIsOn(ctx context.Context,serverId int64,isOn bool) error {
  905. formData := map[string]interface{}{
  906. "serverId": serverId,
  907. "isOn": isOn,
  908. }
  909. apiUrl := s.Url + "ServerService/updateServerIsOn"
  910. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  911. if err != nil {
  912. return err
  913. }
  914. var res v1.GeneralResponse[any]
  915. if err := json.Unmarshal(resBody, &res); err != nil {
  916. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  917. }
  918. if res.Code != 200 {
  919. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  920. }
  921. return nil
  922. }
  923. // 删除已购套餐
  924. func (s *cdnService) DelUserPlan(ctx context.Context,planId int64) error {
  925. formData := map[string]interface{}{
  926. "userPlanId": planId,
  927. }
  928. apiUrl := s.Url + "UserPlanService/deleteUserPlan"
  929. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  930. if err != nil {
  931. return err
  932. }
  933. var res v1.GeneralResponse[any]
  934. if err := json.Unmarshal(resBody, &res); err != nil {
  935. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  936. }
  937. if res.Code != 200 {
  938. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  939. }
  940. return nil
  941. }
  942. // 删除网站分组
  943. func (s *cdnService) DelServerGroup(ctx context.Context,serverId int64) error {
  944. formData := map[string]interface{}{
  945. "serverId": serverId,
  946. }
  947. apiUrl := s.Url + "ServerService/deleteServer"
  948. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  949. if err != nil {
  950. return err
  951. }
  952. var res v1.GeneralResponse[any]
  953. if err := json.Unmarshal(resBody, &res); err != nil {
  954. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  955. }
  956. if res.Code != 200 {
  957. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  958. }
  959. return nil
  960. }
  961. // 删除IP
  962. func (s *cdnService) DelIpItem(ctx context.Context,ipitemId int64,value string,ipFrom string,ipTo string,ipListId int64) error {
  963. formData := map[string]interface{}{
  964. "ipitemId": ipitemId,
  965. "value": value,
  966. "ipFrom": ipFrom,
  967. "ipTo": ipTo,
  968. "ipListId": ipListId,
  969. }
  970. apiUrl := s.Url + "IPItemService/deleteIPItem"
  971. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  972. if err != nil {
  973. return err
  974. }
  975. var res v1.GeneralResponse[any]
  976. if err := json.Unmarshal(resBody, &res); err != nil {
  977. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  978. }
  979. if res.Code != 200 {
  980. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  981. }
  982. return nil
  983. }
  984. // 创建空防火墙策略
  985. func (s *cdnService) AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int64, error) {
  986. formData := map[string]interface{}{
  987. "isOn": req.IsOn,
  988. "name" : req.Name,
  989. "description" : req.Description,
  990. "serverId" : req.ServerId,
  991. "serverGroupId" : req.ServerGroupId,
  992. }
  993. apiUrl := s.Url + "HTTPFirewallPolicyService/createEmptyHTTPFirewallPolicy"
  994. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  995. if err != nil {
  996. return 0, err
  997. }
  998. var res v1.GeneralResponse[map[string]int64]
  999. if err := json.Unmarshal(resBody, &res); err != nil {
  1000. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1001. }
  1002. if res.Code != 200 {
  1003. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1004. }
  1005. if res.Data["httpFirewallPolicyId"] == 0 {
  1006. return 0, fmt.Errorf("创建空防火墙策略失败")
  1007. }
  1008. return res.Data["httpFirewallPolicyId"], nil
  1009. }
  1010. // 更改防火墙设置
  1011. func (s *cdnService) EditHTTPWebFirewal(ctx context.Context,httpWebId int64,FirewallJSON v1.Firewall) error {
  1012. frireWallJson,err := json.Marshal(FirewallJSON)
  1013. if err != nil {
  1014. return err
  1015. }
  1016. formData := map[string]interface{}{
  1017. "httpWebId" : httpWebId,
  1018. "firewallJSON" : frireWallJson,
  1019. }
  1020. apiUrl := s.Url + "HTTPWebService/updateHTTPWebFirewall"
  1021. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1022. if err != nil {
  1023. return err
  1024. }
  1025. var res v1.GeneralResponse[any]
  1026. if err := json.Unmarshal(resBody, &res); err != nil {
  1027. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1028. }
  1029. if res.Code != 200 {
  1030. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1031. }
  1032. return nil
  1033. }
  1034. // 创建IP列表
  1035. func (s *cdnService) AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error) {
  1036. formData := map[string]interface{}{
  1037. "type": req.Type,
  1038. "name": req.Name,
  1039. "code": req.Code,
  1040. "timeoutJSON": req.TimeoutJSON,
  1041. "isPublic": req.IsPublic,
  1042. "description": req.Description,
  1043. "isGlobal": req.IsGlobal,
  1044. "serverId": req.ServerId,
  1045. }
  1046. apiUrl := s.Url + "IPListService/createIPList"
  1047. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1048. if err != nil {
  1049. return 0, err
  1050. }
  1051. var res v1.GeneralResponse[int64]
  1052. if err := json.Unmarshal(resBody, &res); err != nil {
  1053. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1054. }
  1055. if res.Code != 200 {
  1056. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1057. }
  1058. return res.Data, nil
  1059. }
  1060. // 创建IP
  1061. func (s *cdnService) AddIpItem(ctx context.Context, req v1.AddIpItem) error {
  1062. formData := map[string]interface{}{
  1063. "ipListId": req.IpListId,
  1064. "value": req.Value,
  1065. "ipFrom": req.IpFrom,
  1066. "ipTo": req.IpTo,
  1067. "expiredAt": req.ExpiredAt,
  1068. "reason": req.Reason,
  1069. "type": req.Type,
  1070. "eventLevel": req.EventLevel,
  1071. "nodeId": req.NodeId,
  1072. "serverId": req.ServerId,
  1073. "sourceNodeId": req.SourceNodeId,
  1074. "sourceServerId": req.SourceServerId,
  1075. "sourceHTTPFirewallPolicyId": req.SourceHTTPFirewallPolicyId,
  1076. "sourceHTTPFirewallRuleGroupId": req.SourceHTTPFirewallRuleGroupId,
  1077. "sourceHTTPFirewallRuleSetId": req.SourceHTTPFirewallRuleSetId,
  1078. "sourceURL": req.SourceURL,
  1079. "sourceUserAgent": req.SourceUserAgent,
  1080. "sourceCategory": req.SourceCategory,
  1081. }
  1082. apiUrl := s.Url + "IPItemService/createIPItem"
  1083. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1084. if err != nil {
  1085. return err
  1086. }
  1087. var res v1.GeneralResponse[any]
  1088. if err := json.Unmarshal(resBody, &res); err != nil {
  1089. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1090. }
  1091. if res.Code != 200 {
  1092. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1093. }
  1094. return nil
  1095. }
  1096. // 修改IP
  1097. func (s *cdnService) EditIpItem(ctx context.Context, req v1.AddIpItem) error {
  1098. formData := map[string]interface{}{
  1099. "ipItemId": req.IpItemId,
  1100. "value": req.Value,
  1101. "reason" : req.Reason,
  1102. "type" : req.Type,
  1103. "eventLevel" : req.EventLevel,
  1104. }
  1105. apiUrl := s.Url + "IPItemService/updateIPItem"
  1106. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1107. if err != nil {
  1108. return err
  1109. }
  1110. var res v1.GeneralResponse[any]
  1111. if err := json.Unmarshal(resBody, &res); err != nil {
  1112. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1113. }
  1114. if res.Code != 200 {
  1115. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1116. }
  1117. return nil
  1118. }
  1119. // 获取访问日志
  1120. func (s *cdnService) GetAccessLog(ctx context.Context, req cdn.Request) (cdn.Data, error) {
  1121. formData := map[string]interface{}{
  1122. "serverId": req.ServerID,
  1123. "size": req.Size,
  1124. "day" : req.Day,
  1125. "ip": req.Ip,
  1126. "domain": req.Domain,
  1127. "hasError": &req.HasError,
  1128. "hourFrom": req.HourFrom,
  1129. "hourTo": req.HourTo,
  1130. "reverse" : req.Reverse,
  1131. "requestId": req.RequestId,
  1132. "keyword" : req.Keyword,
  1133. }
  1134. apiUrl := s.Url + "HTTPAccessLogService/listHTTPAccessLogs"
  1135. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1136. if err != nil {
  1137. return cdn.Data{}, err
  1138. }
  1139. var res v1.GeneralResponse[cdn.Data]
  1140. if err := json.Unmarshal(resBody, &res); err != nil {
  1141. return cdn.Data{}, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1142. }
  1143. if res.Code != 200 {
  1144. return cdn.Data{}, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1145. }
  1146. return res.Data, nil
  1147. }