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

http timeout

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