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  }