You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.3 KiB
Go

package s2s
import (
"bytes"
"context"
"joybuywork/internal/config"
"joybuywork/internal/plugins/jsonm"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dao"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/utils"
"joybuywork/internal/utils/logic"
"joybuywork/internal/utils/merr"
"fmt"
"io"
"net/http"
"net/url"
"time"
"github.com/valyala/fasthttp"
)
var delaySecMap = map[int32]int{
0: 15, 1: 15,
2: 30,
3: 180,
4: 600,
5: 1200,
6: 1800, 7: 1800, 8: 1800,
9: 3600,
10: 3600 * 3, 11: 3600 * 3, 12: 3600 * 3,
13: 3600 * 6, 14: 3600 * 6,
}
const (
successCode = 200
)
const (
OldCertToken = iota
NewCertToken
)
const (
prefixToken = "Token"
prefixBearer = "Bearer"
)
const (
timeOut = 10 * time.Second
)
const (
ContentTypeJson = "application/json"
)
type S2S struct {
logic.Context
url *model.NotifyURL
project *model.Project
tokenStr string
header http.Header
start time.Time
}
func (s *S2S) init(ctx context.Context, ProjectId, UrlId int64, opts ...Option) (err error) {
s.Context.Init(ctx, dao.Q, merr.NewBE(ctx))
for _, opt := range opts {
opt(s)
}
s.url, err = cache.NewNotifyURL(ctx).FindById(UrlId)
if err != nil {
err = s.BE().CacheError(err)
return
}
s.project, err = cache.NewProject(ctx).FindById(ProjectId)
if err != nil {
err = s.BE().CacheError(err)
return
}
return
}
func (s *S2S) request(id int64, body []byte, lang, prefix string, certToken int8) (respBody string, code int32, err error) {
cli := &http.Client{
Timeout: timeOut,
}
// 走代理
if s.project.PushLadder == mtype.Yes {
var proxyURL *url.URL
proxyURL, err = url.Parse(config.Config.Server.LadderHost)
if err != nil {
err = s.BE().VerifyError(fmt.Sprintf("无法解析代理 URL: %v", err))
return
}
cli.Transport = &http.Transport{
Proxy: http.ProxyURL(proxyURL),
}
}
// 创建请求
req, err := http.NewRequest("POST", s.url.URL, bytes.NewBuffer(body))
if err != nil {
err = s.BE().VerifyError(fmt.Sprintf("创建请求失败: %v", err))
return
}
req.Header.Set(fasthttp.HeaderContentType, ContentTypeJson)
req.Header.Set("X-Message-Id", fmt.Sprint(id))
req.Header.Set("X-Lang", lang)
req.Header.Set(fasthttp.HeaderAuthorization, fmt.Sprintf("%s %s", prefix, s.token(body, certToken)))
for _, h := range s.url.GetHeaders() {
switch h.Mark {
case mtype.NotifyUrlHeaderMarkLang:
req.Header.Set(h.Key, lang)
default:
req.Header.Set(h.Key, h.Val)
}
}
s.header = req.Header.Clone()
// 发送请求
resp, err := cli.Do(req)
if err != nil {
err = s.BE().VerifyError(fmt.Sprintf("请求失败: %v", err))
return
}
defer resp.Body.Close()
// 可以通过 resp.Body 获取响应内容
data, _ := io.ReadAll(resp.Body)
return string(data), int32(resp.StatusCode), nil
}
func (s *S2S) token(body []byte, certToken int8) string {
switch certToken {
case OldCertToken:
s.tokenStr = s.project.NotifyToken
default:
s.tokenStr = utils.Md5String(s.project.ThirdSecret + " " + utils.Md5(body))
}
return s.tokenStr
}
func (s *S2S) GetUrl() string {
return s.url.URL
}
func (s *S2S) GetToken() string {
return s.tokenStr
}
func (s *S2S) GetHeader() (header string) {
header, _ = jsonm.MarshalToString(s.header)
return
}