提交 783de9ef authored 作者: mooncake9527's avatar mooncake9527

http timeout

上级 c03f9f0e
...@@ -54,319 +54,313 @@ func New() *Request { ...@@ -54,319 +54,313 @@ func New() *Request {
} }
// Reset set all fields to default value, use at pool // Reset set all fields to default value, use at pool
func (req *Request) Reset() { func (x *Request) Reset() {
req.params = nil x.params = nil
req.reqBody = nil x.reqBody = nil
req.reqBodyJSON = nil x.reqBodyJSON = nil
req.timeout = 0 x.timeout = 0
req.headers = nil x.headers = nil
req.response = nil x.response = nil
req.method = "" x.method = ""
req.err = nil x.err = nil
} }
// SetURL set URL // SetURL set URL
func (req *Request) SetURL(path string) *Request { func (x *Request) SetURL(path string) *Request {
req.url = path x.url = path
return req return x
} }
// SetParams parameters after setting the URL // SetParams parameters after setting the URL
func (req *Request) SetParams(params map[string]interface{}) *Request { func (x *Request) SetParams(params map[string]interface{}) *Request {
if req.params == nil { if x.params == nil {
req.params = params x.params = params
} else { } else {
for k, v := range params { for k, v := range params {
req.params[k] = v x.params[k] = v
} }
} }
return req return x
} }
// SetParam parameters after setting the URL // SetParam parameters after setting the URL
func (req *Request) SetParam(k string, v interface{}) *Request { func (x *Request) SetParam(k string, v interface{}) *Request {
if req.params == nil { if x.params == nil {
req.params = make(map[string]interface{}) x.params = make(map[string]interface{})
} }
req.params[k] = v x.params[k] = v
return req return x
} }
// SetBody set body data, support string and []byte, if it is not string, it will be json marshal. // SetBody set body data, support string and []byte, if it is not string, it will be json marshal.
func (req *Request) SetBody(body interface{}) *Request { func (x *Request) SetBody(body interface{}) *Request {
switch v := body.(type) { switch v := body.(type) {
case string: case string:
req.reqBody = []byte(v) x.reqBody = []byte(v)
case []byte: case []byte:
req.reqBody = v x.reqBody = v
default: default:
req.reqBodyJSON = body x.reqBodyJSON = body
} }
return req return x
} }
// SetTimeout set timeout // SetTimeout set timeout
func (req *Request) SetTimeout(t time.Duration) *Request { func (x *Request) SetTimeout(t time.Duration) *Request {
req.timeout = t x.timeout = t
return req return x
} }
func (req *Request) SetRetry(count uint) *Request { func (x *Request) SetRetry(count uint) *Request {
req.retryCount = count x.retryCount = count
return req return x
} }
// SetContentType set ContentType // SetContentType set ContentType
func (req *Request) SetContentType(a string) *Request { func (x *Request) SetContentType(a string) *Request {
req.SetHeader("Content-Type", a) x.SetHeader("Content-Type", a)
return req return x
} }
// SetHeader set the value of the request header // SetHeader set the value of the request header
func (req *Request) SetHeader(k, v string) *Request { func (x *Request) SetHeader(k, v string) *Request {
if req.headers == nil { if x.headers == nil {
req.headers = make(map[string]string) x.headers = make(map[string]string)
} }
req.headers[k] = v x.headers[k] = v
return req return x
} }
// SetHeaders set the value of Request Headers // SetHeaders set the value of Request Headers
func (req *Request) SetHeaders(headers map[string]string) *Request { func (x *Request) SetHeaders(headers map[string]string) *Request {
if req.headers == nil { if x.headers == nil {
req.headers = make(map[string]string) x.headers = make(map[string]string)
} }
for k, v := range headers { for k, v := range headers {
req.headers[k] = v x.headers[k] = v
} }
return req return x
} }
// GET send a GET request // GET send a GET request
func (req *Request) GET(ctx context.Context) *Request { func (x *Request) GET(ctx context.Context) *Request {
req.method = http.MethodGet x.method = http.MethodGet
req.pull(ctx) x.pull(ctx)
return req return x
} }
// DELETE send a DELETE request // DELETE send a DELETE request
func (req *Request) DELETE(ctx context.Context) *Request { func (x *Request) DELETE(ctx context.Context) *Request {
req.method = http.MethodDelete x.method = http.MethodDelete
req.pull(ctx) x.pull(ctx)
return req return x
} }
// POST send a POST request // POST send a POST request
func (req *Request) POST(ctx context.Context) *Request { func (x *Request) POST(ctx context.Context) *Request {
req.method = http.MethodPost x.method = http.MethodPost
req.push(ctx) x.push(ctx)
return req return x
} }
// PUT send a PUT request // PUT send a PUT request
func (req *Request) PUT(ctx context.Context) *Request { func (x *Request) PUT(ctx context.Context) *Request {
req.method = http.MethodPut x.method = http.MethodPut
req.push(ctx) x.push(ctx)
return req return x
} }
// PATCH send PATCH requests // PATCH send PATCH requests
func (req *Request) PATCH(ctx context.Context) *Request { func (x *Request) PATCH(ctx context.Context) *Request {
req.method = http.MethodPatch x.method = http.MethodPatch
req.push(ctx) x.push(ctx)
return req return x
} }
// Do a request // Do a request
func (req *Request) Do(ctx context.Context, method string, data interface{}) *Request { func (x *Request) Do(ctx context.Context, method string, data interface{}) *Request {
req.method = method x.method = method
switch method { switch method {
case http.MethodGet, http.MethodDelete: case http.MethodGet, http.MethodDelete:
if data != nil { if data != nil {
if params, ok := data.(map[string]interface{}); ok { //nolint if params, ok := data.(map[string]interface{}); ok { //nolint
req.SetParams(params) x.SetParams(params)
} else { } else {
req.err = errors.New("params is not a map[string]interface{}") x.err = errors.New("params is not a map[string]interface{}")
return req return x
} }
} }
req.pull(ctx) x.pull(ctx)
case http.MethodPost, http.MethodPut, http.MethodPatch: case http.MethodPost, http.MethodPut, http.MethodPatch:
if data != nil { if data != nil {
req.SetBody(data) x.SetBody(data)
} }
req.push(ctx) x.push(ctx)
default: default:
req.err = errors.New("unknow method " + method) x.err = errors.New("unknow method " + method)
} }
return req return x
} }
func (req *Request) pull(ctx context.Context) { func (x *Request) pull(ctx context.Context) {
val := "" val := ""
if len(req.params) > 0 { if len(x.params) > 0 {
values := url.Values{} values := url.Values{}
for k, v := range req.params { for k, v := range x.params {
values.Add(k, fmt.Sprintf("%v", v)) values.Add(k, fmt.Sprintf("%v", v))
} }
val += values.Encode() val += values.Encode()
} }
if val != "" { if val != "" {
if strings.Contains(req.url, "?") { if strings.Contains(x.url, "?") {
req.url += "&" + val x.url += "&" + val
} else { } else {
req.url += "?" + val x.url += "?" + val
} }
} }
req.send(ctx) x.send(ctx)
} }
func (req *Request) push(ctx context.Context) { func (x *Request) push(ctx context.Context) {
if req.reqBodyJSON != nil { if x.reqBodyJSON != nil {
body, err := json.Marshal(req.reqBodyJSON) body, err := json.Marshal(x.reqBodyJSON)
if err != nil { if err != nil {
req.err = err x.err = err
return return
} }
req.reqBody = body x.reqBody = body
} }
req.send(ctx) x.send(ctx)
} }
func (req *Request) send(ctx context.Context) { func (x *Request) send(ctx context.Context) {
bodyBuf := bytes.NewBuffer(req.reqBody) bodyBuf := bytes.NewBuffer(x.reqBody)
var request *http.Request var req *http.Request
request, req.err = http.NewRequest(req.method, req.url, bodyBuf) req, x.err = http.NewRequest(x.method, x.url, bodyBuf)
if req.err != nil { if x.err != nil {
return return
} }
if req.reqBody != nil { if x.reqBody != nil {
if c, _ := ctxUtils.GetGinCtx(ctx); c != nil { if c, _ := ctxUtils.GetGinCtx(ctx); c != nil {
entity.SetCopyApiReq(c, bodyBuf) entity.SetCopyApiReq(c, bodyBuf)
} }
} }
if req.headers != nil { if x.headers != nil {
for k, v := range req.headers { for k, v := range x.headers {
request.Header.Add(k, v) req.Header.Add(k, v)
} }
} }
request.Header.Add(ctxUtils.HeaderXRequestIDKey, ctxUtils.CtxRequestID(ctx)) req.Header.Add(ctxUtils.HeaderXRequestIDKey, ctxUtils.CtxRequestID(ctx))
if req.timeout < 1 { if x.timeout < 1 {
req.timeout = defaultTimeout x.timeout = defaultTimeout
} }
ctx, cancel := context.WithTimeout(ctx, req.timeout) ctx, cancel := context.WithTimeout(ctx, x.timeout)
defer cancel() defer cancel()
req.request.WithContext(ctx) x.request.WithContext(ctx)
logger.Info("[httpCli] req", logger.Info("[httpCli] req",
logger.Any("method", req.method), logger.Any("method", x.method),
logger.Any("url", req.url), logger.Any("url", x.url),
logger.Any("header", request.Header), logger.Any("header", req.Header),
logger.Any("body", bodyBuf.String()), logger.Any("body", bodyBuf.String()),
ctxUtils.CtxTraceIDField(ctx)) ctxUtils.CtxTraceIDField(ctx))
req.request = request x.request = req
if req.retryCount > 0 { if x.retryCount > 0 {
_ = retry.Retry(func() error { x.err = retry.Retry(func() error {
req.pushDo(ctx) x.pushDo(ctx)
return req.err return x.err
}, },
retry.RetryTimes(req.retryCount), retry.RetryTimes(x.retryCount),
retry.RetryWithLinearBackoff(8*time.Second), retry.RetryWithLinearBackoff(8*time.Second),
retry.Context(ctx), retry.Context(ctx),
) )
} else { } else {
req.pushDo(ctx) x.pushDo(ctx)
} }
var rspHeader map[string][]string
var rspBodyStr string
if req.response != nil {
rspHeader = req.response.Header
if len(req.response.body) > 0 {
rspBodyStr = bytes.NewBuffer(req.response.body).String()
}
}
logger.Info("[httpCli] rsp", logger.Info("[httpCli] rsp",
logger.Any("method", req.method), logger.Any("method", x.method),
logger.Any("status", req.response.Status), logger.Any("status", x.response.Status),
logger.Any("url", req.url), logger.Any("url", x.url),
logger.Any("header", rspHeader), logger.Any("header", x.Response().Header),
logger.Any("body", rspBodyStr), logger.Any("body", x.RespBodyString()),
ctxUtils.CtxTraceIDField(ctx)) ctxUtils.CtxTraceIDField(ctx))
} }
func (req *Request) pushDo(ctx context.Context) { func (x *Request) pushDo(ctx context.Context) {
client := http.Client{Timeout: req.timeout} client := http.Client{Timeout: x.timeout}
response, e := client.Do(req.request) var response *http.Response
if e != nil { response, x.err = client.Do(x.request)
req.request = nil if x.err != nil {
req.err = e x.request = nil
return return
} }
if response != nil { if response != nil {
req.response.Status = response.Status x.response.Status = response.Status
req.response.Header = response.Header x.response.Header = response.Header
ctxUtils.SetApiCost(ctx, req.response.Header) x.response.StatusCode = response.StatusCode
req.response.StatusCode = response.StatusCode ctxUtils.SetApiCost(ctx, x.response.Header)
if response.Body != nil { if response.Body != nil {
defer response.Body.Close() defer response.Body.Close()
req.response.body, req.err = io.ReadAll(response.Body) x.response.body, x.err = io.ReadAll(response.Body)
if req.err != nil { if x.err != nil {
req.request = nil x.request = nil
return return
} }
if len(req.response.body) > 0 { if len(x.response.body) > 0 {
if c, _ := ctxUtils.GetGinCtx(ctx); c != nil { if c, _ := ctxUtils.GetGinCtx(ctx); c != nil {
entity.SetCopyApiRsp(c, bytes.NewBuffer(req.response.body)) entity.SetCopyApiRsp(c, x.response.BodyBuf())
} }
//req.response.Body = io.NopCloser(bytes.NewBuffer(req.rspBody))
} }
} }
} }
req.request = nil x.request = nil
} }
// ----------------------------------- Response ----------------------------------- // ----------------------------------- Response -----------------------------------
func (req *Request) Err() error { func (x *Request) Err() error {
return req.err return x.err
} }
// BodyString returns the body data of the HttpResponse // RespBodyString returns the body data of the HttpResponse
func (req *Request) BodyString() string { func (x *Request) RespBodyString() string {
if len(req.response.body) == 0 { if len(x.response.body) == 0 {
return "" return ""
} }
return string(req.response.body) return string(x.response.body)
}
func (x *Request) Response() *Response {
return x.response
} }
func (req *Request) Response() *Response { func (x *Response) BodyBuf() *bytes.Buffer {
return req.response return bytes.NewBuffer(x.body)
} }
func (req *Request) ReadRspBody() ([]byte, error) { func (x *Request) ReadRspBody() ([]byte, error) {
if req.err != nil { if x.err != nil {
return []byte{}, req.err return []byte{}, x.err
} }
if req.response.body == nil { if x.response.body == nil {
return []byte{}, errors.New("nil") return []byte{}, errors.New("nil")
} }
return req.response.body, nil return x.response.body, nil
} }
// BindJSON parses the response's body as JSON // BindJSON parses the response's body as JSON
func (req *Request) BindJSON(v interface{}) *Request { func (x *Request) BindJSON(v interface{}) *Request {
if req.err != nil { if x.err != nil {
return req return x
} }
if err := json.Unmarshal(req.response.body, v); err != nil { if err := json.Unmarshal(x.response.body, v); err != nil {
req.err = err x.err = err
} }
return req return x
} }
// ----------------------------------- Request way 2 ----------------------------------- // ----------------------------------- Request way 2 -----------------------------------
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论