1 Star 0 Fork 0

fkil555/gin-extend

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ghttp.go 4.82 KB
一键复制 编辑 原始数据 按行查看 历史
fkil555 提交于 2024-05-08 15:27 . add helper
package ghttp
import (
"context"
"io"
"net/http"
"net/url"
"strings"
"sync"
"time"
"gitee.com/fkil555/gin-extend/helpers/urlhelper"
)
// 默认超时时间
const DEFAULT_TIMEOUT = 3000
const CTX_TRACEDATA_KEY = "tracedata"
const CAT_POST_LEN_LIMIT = 200
// 请求配置
type HttpConfig struct {
Timeout int `toml:"timeout"` // 连接超时时间
Header map[string]string
Cookie []*http.Cookie
}
// 默认http配置
var defaultHttpConfig = &HttpConfig{
Timeout: DEFAULT_TIMEOUT,
}
// 请求链路元数据
type TraceData struct {
Host string // 正在发起HTTP调用客户端的DOMAIN
RequestURI string // 正在发起HTTP调用的客户端URL
TraceStr string // X-Trace-Str
TraceID string // X-Request-Id
}
// 初始化http配置
func InitHttpClient(config *HttpConfig) (err error) {
if config != nil && config.Timeout > 0 {
defaultHttpConfig.Timeout = config.Timeout
}
return
}
// 设置请求配置默认值
func setDefaultHttpConfig(userConfig *HttpConfig) (mergedConfig *HttpConfig) {
// 用户没传, 采用默认配置
if userConfig == nil {
mergedConfig = defaultHttpConfig
return
}
// 复制用户参数, 进行默认值覆盖
mergedConfig = &HttpConfig{}
*mergedConfig = *userConfig
if mergedConfig.Timeout <= 0 {
mergedConfig.Timeout = defaultHttpConfig.Timeout
}
return
}
// 通用请求(参考标准库Do方法),但是支持CAT以及部分通用的请求配置项
func Do(ctx context.Context, rawRequest *http.Request, config *HttpConfig) (rawResponse *http.Response, err error) {
var req *Request
if req, err = NewDoRequest(rawRequest, config); err != nil {
return
}
var resp *Response
if resp, err = doRequest(ctx, req); err != nil {
return
}
rawResponse = resp.RawResp
return
}
// GET请求
func Get(ctx context.Context, reqUrl string, query *url.Values, config *HttpConfig) (response *Response, err error) {
var req *Request
if req, err = NewGetRequest(reqUrl, query, config); err != nil {
return
}
return doRequest(ctx, req)
}
// POST表单
func Post(ctx context.Context, reqUrl string, query *url.Values, form *url.Values, config *HttpConfig) (response *Response, err error) {
var req *Request
if req, err = NewPostRequest(reqUrl, query, form, config); err != nil {
return
}
return doRequest(ctx, req)
}
// POST JSON
func PostJson(ctx context.Context, reqUrl string, query *url.Values, json []byte, config *HttpConfig) (response *Response, err error) {
var req *Request
if req, err = NewPostJsonRequest(reqUrl, query, json, config); err != nil {
return
}
return doRequest(ctx, req)
}
// POST FILE
func PostFile(ctx context.Context, reqUrl string, query *url.Values, form *url.Values, files map[string]io.Reader, config *HttpConfig) (response *Response, err error) {
var req *Request
if req, err = NewPostFileRequest(reqUrl, query, form, files, config); err != nil {
return
}
return doRequest(ctx, req)
}
// 并发调用
func MultiRequest(ctx context.Context, reqList []*Request) (respList []*Response, err error) {
wg := sync.WaitGroup{}
respList = make([]*Response, len(reqList))
for i := range respList {
respList[i] = &Response{}
// 关闭追踪
reqList[i].isMulti = true
// 协程并发
wg.Add(1)
go func(c context.Context, wg *sync.WaitGroup, idx int) {
respList[idx], _ = doRequest(c, reqList[idx])
wg.Done()
}(ctx, &wg, i)
}
wg.Wait()
return
}
// 封装网络请求(该函数返回值resp永不为空)
func doRequest(context context.Context, req *Request) (resp *Response, err error) {
resp = &Response{}
defer func() {
resp.Err = err
}()
config := setDefaultHttpConfig(req.Config)
client := &http.Client{
Timeout: time.Duration(config.Timeout) * time.Millisecond, //设置默认超时时间
}
rawReq := req.RawReq.WithContext(context)
// 增加自定义header
if config.Header != nil {
for key, value := range config.Header {
rawReq.Header.Set(key, value)
}
}
// 增加自定义cookie
if config.Cookie != nil {
for _, cookie := range config.Cookie {
rawReq.AddCookie(cookie)
}
}
// TODO: cron情况下没有metadata,导致无法trace parent
{ // 请求携带链路header
if traceData, ok := context.Value(CTX_TRACEDATA_KEY).(*TraceData); ok {
rawReq.Header.Set("X-Request-Id", traceData.TraceID)
rawReq.Header.Set("X-Trace-Str", traceData.TraceStr)
parts := strings.Split(traceData.RequestURI, "?")
cleanUrl := urlhelper.ReplaceURI(parts[0])
rawReq.Header.Set("_catCallerDomain", traceData.Host)
rawReq.Header.Set("_catCallerMethod", cleanUrl)
rawReq.Header.Set("_catCallFromMethod", cleanUrl)
}
}
var rawResp *http.Response
if rawResp, err = client.Do(rawReq); err != nil {
return
}
// 应答内容
var respBody []byte
if !req.doOnly {
defer rawResp.Body.Close()
if respBody, err = io.ReadAll(rawResp.Body); err != nil {
return
}
}
resp.RawResp = rawResp
resp.Body = respBody
return
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/fkil555/gin-extend.git
git@gitee.com:fkil555/gin-extend.git
fkil555
gin-extend
gin-extend
v0.1.3

搜索帮助