紫色飞猪的研发之旅--11一本万利的go封装http请求v2

package pkg

import (
        "crypto/tls"
        "errors"
        "io/ioutil"
        "net"
        "net/http"
        "strings"
        "time"
)

type HTTPClient interface {
        Do(req *http.Request) (*http.Response, error)
}

var (
        Client HTTPClient
)

type Request struct {
        Url string
        Body string
        HeaderSet map[string]string
        Method string
        CookieName string
        CookieValue string
}

func init() {
        Client = &http.Client{
                Timeout: 10 * time.Second,
                Transport: &http.Transport{
                        TLSClientConfig:   &tls.Config{InsecureSkipVerify: true},
                        DisableKeepAlives: true,
                        Proxy:             http.ProxyFromEnvironment,
                        DialContext: (&net.Dialer{
                                Timeout:   30 * time.Second, // tcp连接超时时间
                                KeepAlive: 60 * time.Second, // 保持长连接的时间
                                DualStack: true,
                        }).DialContext, // 设置连接的参数
                        MaxIdleConns:          100, // 最大空闲连接
                        MaxConnsPerHost:       100,
                        MaxIdleConnsPerHost:   100,              // 每个host保持的空闲连接数
                        ExpectContinueTimeout: 30 * time.Second, // 等待服务第一响应的超时时间
                        IdleConnTimeout:       60 * time.Second, // 空闲连接的超时时间
                },
        }
}

// CheckRespStatus 状态检查
func CheckRespStatus(resp *http.Response) ([]byte, error) {
        bodyBytes, _ := ioutil.ReadAll(resp.Body)
        if resp.StatusCode >= 200 && resp.StatusCode < 400 {
                return bodyBytes, nil
        }
        return nil, errors.New(string(bodyBytes))
}

// Ask 建立http请求
func Ask(requester Requester) (respStatusCode int, respBytes []byte, err error) {
        request, err := http.NewRequest(requester.Method, requester.Url, strings.NewReader(requester.Body))
        if err != nil {
                return 401, nil, err
        }
        // 添加cookie
        if requester.CookieName != "" && requester.CookieValue != "" {
                cookie := &http.Cookie{Name: requester.CookieName, Value: requester.CookieValue, HttpOnly: true}
                request.AddCookie(cookie)
        }
        // header 添加字段,包含token
        if requester.HeaderSet != nil {
                for k, v := range requester.HeaderSet {
                        request.Header.Set(k, v)
                }
        }
        resp, err := Client.Do(request)
        if err != nil {
                return 401, nil, err
        }
        defer resp.Body.Close()
        // 返回的状态码
        respBytes, err = CheckRespStatus(resp)
        respStatusCode = resp.StatusCode
        return
}