github.com/jtzjtz/kit@v1.0.2/http/http_request.go (about) 1 package http 2 3 import ( 4 "crypto/tls" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "github.com/gin-gonic/gin" 9 "io/ioutil" 10 "net/http" 11 "net/url" 12 "strings" 13 "time" 14 ) 15 16 var TRACEID = "Eagleeye-Traceid" 17 18 type ExtParams struct { 19 Headers map[string]string //请求头 20 RetryCount int //失败重试次数 21 TimeOut time.Duration //超时时间 22 } 23 24 //处理map到encode字符串 25 func handleMapToEncodeStr(params map[string]interface{}) string { 26 paramStr := "" 27 if params != nil && len(params) > 0 { 28 i := 0 29 for k, v := range params { 30 val := fmt.Sprintf("%v", v) 31 if i == 0 { 32 paramStr += fmt.Sprintf("%v=%v", k, url.QueryEscape(val)) 33 } else { 34 paramStr += fmt.Sprintf("&%v=%v", k, url.QueryEscape(val)) 35 } 36 i++ 37 } 38 } 39 return paramStr 40 } 41 42 //发起GET请求 43 func GetRequest(ctx *gin.Context, reqUrl string, params map[string]interface{}, timeOut time.Duration, extParams ExtParams) (resBody string, resStatus int, resErr error) { 44 if strings.Contains(reqUrl, "?") == false && params != nil && len(params) > 0 { 45 reqUrl += "?" 46 } 47 reqUrl += handleMapToEncodeStr(params) 48 return DoRequest(ctx, reqUrl, "", "GET", timeOut, extParams) 49 } 50 51 //发起POST请求 52 func PostRequest(ctx *gin.Context, reqUrl string, params map[string]interface{}, timeOut time.Duration, extParams ExtParams) (resBody string, resStatus int, resErr error) { 53 if extParams.Headers == nil || len(extParams.Headers) == 0 { 54 extParams.Headers = map[string]string{} 55 } 56 if _, ok := extParams.Headers["Content-Type"]; !ok { 57 extParams.Headers["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8" 58 } 59 return DoRequest(ctx, reqUrl, handleMapToEncodeStr(params), "POST", timeOut, extParams) 60 } 61 62 //POST发送json数据 63 func PostJsonRequest(ctx *gin.Context, reqUrl string, params map[string]interface{}, timeOut time.Duration, extParams ExtParams) (resBody string, resStatus int, resErr error) { 64 if extParams.Headers == nil || len(extParams.Headers) == 0 { 65 extParams.Headers = map[string]string{} 66 extParams.Headers["Content-Type"] = "application/json;charset=UTF-8" 67 } else { 68 extParams.Headers["Content-Type"] = "application/json;charset=UTF-8" 69 } 70 jsonParams, err := json.Marshal(params) 71 if err != nil { 72 return "", 0, errors.New("json解析错误:" + err.Error()) 73 } 74 return DoRequest(ctx, reqUrl, string(jsonParams), "POST", timeOut, extParams) 75 } 76 77 //POST发送json数据 78 func PostJson(reqUrl string, params map[string]interface{}, extParams *ExtParams, ctx *gin.Context) (resBody string, resStatus int, resErr error) { 79 var timeOut time.Duration 80 if extParams != nil { 81 if extParams.Headers == nil || len(extParams.Headers) == 0 { 82 extParams.Headers = map[string]string{} 83 extParams.Headers["Content-Type"] = "application/json;charset=UTF-8" 84 } else { 85 extParams.Headers["Content-Type"] = "application/json;charset=UTF-8" 86 } 87 timeOut = extParams.TimeOut 88 } 89 90 jsonParams, err := json.Marshal(params) 91 if err != nil { 92 return "", 0, errors.New("json解析错误:" + err.Error()) 93 } 94 return DoRequest(ctx, reqUrl, string(jsonParams), "POST", timeOut, *extParams) 95 } 96 97 //发起Http请求 98 func DoRequest(ctx *gin.Context, reqUrl string, params string, method string, timeOut time.Duration, extParams ExtParams) (resBody string, resStatus int, resErr error) { 99 reqTimeOut := timeOut 100 retryCount := extParams.RetryCount 101 if reqTimeOut <= 0 { 102 reqTimeOut = 30 * time.Second //默认30秒超时 103 } 104 105 //添加常用http请求直接close链接,防止占用描述符链接资源 106 if extParams.Headers == nil { 107 extParams.Headers = map[string]string{ 108 "Connection": "close", 109 } 110 } else { 111 if _, ok := extParams.Headers["Connection"]; !ok { 112 extParams.Headers["Connection"] = "close" 113 } 114 } 115 tr := &http.Transport{ 116 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 117 //MaxIdleConnsPerHost: 20, 118 //DisableKeepAlives:false, 119 } 120 client := &http.Client{ 121 Timeout: reqTimeOut, 122 Transport: tr, 123 } 124 var res *http.Response 125 var req *http.Request 126 var err error 127 for i := 0; i <= retryCount; i++ { 128 req, err = http.NewRequest(method, reqUrl, strings.NewReader(params)) 129 if err != nil { 130 if res != nil { 131 _ = res.Body.Close() 132 } 133 continue 134 } 135 if ctx != nil { 136 if ctx.GetHeader(TRACEID) != "" { 137 req.Header.Set(TRACEID, ctx.GetHeader(TRACEID)) 138 } 139 } 140 if extParams.Headers != nil && len(extParams.Headers) > 0 { 141 for k, v := range extParams.Headers { 142 req.Header.Set(k, v) 143 } 144 } 145 res, err = client.Do(req) 146 if err != nil { 147 if res != nil { 148 _ = res.Body.Close() 149 } 150 continue 151 } else { 152 break 153 } 154 } 155 statusCode := 0 //响应状态码 156 if res != nil { 157 statusCode = res.StatusCode 158 } 159 if err != nil { 160 //请求异常 161 return "", statusCode, err 162 } 163 164 defer func() { 165 if res != nil { 166 _ = res.Body.Close() 167 } 168 }() 169 170 body, err := ioutil.ReadAll(res.Body) 171 if err != nil { 172 //解析数据异常 173 return "", statusCode, err 174 } 175 176 return string(body), statusCode, nil 177 } 178 func GetTraceId(ctx *gin.Context) string { 179 if len(ctx.GetHeader("TraceId")) > 0 { 180 return ctx.GetHeader("TraceId") 181 } else if len(ctx.GetHeader("Eagleeye-Traceid")) > 0 { 182 return ctx.GetHeader("Eagleeye-Traceid") 183 } else if len(ctx.GetHeader("X-B3-Traceid")) > 0 { 184 return ctx.GetHeader("X-B3-Traceid") 185 } 186 return "" 187 }