forked from all_user/stat_center
109 lines
2.9 KiB
Go
109 lines
2.9 KiB
Go
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var once sync.Once
|
|
var _client *http.Client
|
|
|
|
func GetHttpClient() *http.Client {
|
|
once.Do(func() {
|
|
_client = &http.Client{
|
|
Timeout: time.Minute * 1, //设置超时时间
|
|
Transport: &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
DialContext: (&net.Dialer{
|
|
Timeout: 30 * time.Second,
|
|
KeepAlive: 30 * time.Second,
|
|
}).DialContext,
|
|
TLSHandshakeTimeout: 10 * time.Second, //限制 TLS握手的时间
|
|
ResponseHeaderTimeout: 10 * time.Second, //限制读取response header的时间,默认 timeout + 5*time.Second
|
|
ExpectContinueTimeout: 1 * time.Second, //限制client在发送包含 Expect: 100-continue的header到收到继续发送body的response之间的时间等待。
|
|
MaxIdleConns: 100, //所有host的连接池最大连接数量,默认无穷大
|
|
MaxIdleConnsPerHost: 30, //每个host的连接池最大空闲连接数,默认2
|
|
MaxConnsPerHost: 10, //每个host的最大连接数量
|
|
IdleConnTimeout: 3 * time.Minute, //how long an idle connection is kept in the connection pool.
|
|
},
|
|
}
|
|
})
|
|
return _client
|
|
}
|
|
|
|
func getBytes(request interface{}) ([]byte, error) {
|
|
var body []byte
|
|
switch t := request.(type) {
|
|
case []byte:
|
|
body = t
|
|
case string:
|
|
body = []byte(t)
|
|
default:
|
|
var err error
|
|
body, err = json.Marshal(request)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return body, nil
|
|
}
|
|
|
|
type OnHttpResponse func(res *http.Response) error
|
|
|
|
func HttpRequest(req *http.Request, onResponse OnHttpResponse) error {
|
|
client := GetHttpClient()
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer res.Body.Close()
|
|
if onResponse != nil {
|
|
err = onResponse(res)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func HttpMethod(url, method string, header http.Header, body io.Reader, onResponse OnHttpResponse) error {
|
|
req, err := http.NewRequest(method, url, body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if header != nil {
|
|
req.Header = header
|
|
}
|
|
return HttpRequest(req, onResponse)
|
|
}
|
|
|
|
func HttpGet(url string, header http.Header, body io.Reader, onResponse OnHttpResponse) error {
|
|
return HttpMethod(url, http.MethodGet, header, body, onResponse)
|
|
}
|
|
|
|
func HttpPost(url string, header http.Header, body io.Reader, onResponse OnHttpResponse) error {
|
|
return HttpMethod(url, http.MethodPost, header, body, onResponse)
|
|
}
|
|
|
|
func HttpPostRequestJson(url string, request interface{}, resp interface{}) error {
|
|
header := make(http.Header)
|
|
header.Set("Content-Type", "application/json")
|
|
body, err := getBytes(request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return HttpPost(url, header, bytes.NewReader(body), func(res *http.Response) error {
|
|
if res.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("http request (%s) error %s", url, res.Status)
|
|
}
|
|
content, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(content, resp)
|
|
})
|
|
}
|