2023-08-10 14:29:19 +08:00
|
|
|
// Package httpclient ...
|
2022-05-01 21:49:17 +08:00
|
|
|
//
|
|
|
|
// Author: go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Description:
|
|
|
|
//
|
|
|
|
// File: request.go
|
|
|
|
//
|
|
|
|
// Version: 1.0.0
|
|
|
|
//
|
|
|
|
// Date: 2022/05/01 21:25:03
|
2023-08-10 14:29:19 +08:00
|
|
|
package httpclient
|
2022-05-01 21:49:17 +08:00
|
|
|
|
|
|
|
import (
|
2022-05-02 15:17:21 +08:00
|
|
|
"bytes"
|
2022-05-01 22:21:49 +08:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2022-05-01 21:49:17 +08:00
|
|
|
"net/http"
|
|
|
|
"strings"
|
2022-05-02 15:17:21 +08:00
|
|
|
"time"
|
2022-05-01 22:38:31 +08:00
|
|
|
|
|
|
|
"github.com/ddliu/go-httpclient"
|
2022-05-01 21:49:17 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// Request 发送请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:26:02
|
2022-05-01 22:38:31 +08:00
|
|
|
func Request(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-01 21:49:17 +08:00
|
|
|
apiConfig.Method = strings.ToUpper(apiConfig.Method)
|
|
|
|
switch apiConfig.Method {
|
|
|
|
case http.MethodGet:
|
2022-05-01 22:38:31 +08:00
|
|
|
return GET(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodPost:
|
2022-05-01 22:38:31 +08:00
|
|
|
return POST(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodPut:
|
2022-05-01 22:38:31 +08:00
|
|
|
return PUT(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodDelete:
|
2022-05-01 22:38:31 +08:00
|
|
|
return DELETE(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodConnect:
|
2022-05-01 22:38:31 +08:00
|
|
|
return Connect(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodOptions:
|
2022-05-01 22:38:31 +08:00
|
|
|
return OPTION(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodTrace:
|
2022-05-01 22:38:31 +08:00
|
|
|
return Trace(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
case http.MethodPatch:
|
2022-05-01 22:38:31 +08:00
|
|
|
return Patch(apiConfig, header, param)
|
2022-05-01 21:49:17 +08:00
|
|
|
default:
|
|
|
|
return &ApiResponse{
|
2022-05-02 15:17:21 +08:00
|
|
|
RequestConfig: apiConfig,
|
|
|
|
Exception: NewException(RequestMethodNotSupport, map[string]string{"method": apiConfig.Method}),
|
|
|
|
Response: nil,
|
|
|
|
StartRequestTime: time.Now().UnixNano(),
|
|
|
|
FinishRequestTime: time.Now().UnixNano(),
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GET ...
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date: 2022/05/01 21:29:09
|
2022-05-01 22:38:31 +08:00
|
|
|
func GET(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodGet
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// POST post请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:31:36
|
2022-05-01 22:38:31 +08:00
|
|
|
func POST(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodPost
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// PUT put请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:31:52
|
2022-05-01 22:38:31 +08:00
|
|
|
func PUT(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodPut
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// DELETE delete请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:32:08
|
2022-05-01 22:38:31 +08:00
|
|
|
func DELETE(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodDelete
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// OPTION option请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:32:18
|
2022-05-01 22:38:31 +08:00
|
|
|
func OPTION(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodOptions
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Patch patch请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:36:12
|
2022-05-01 22:38:31 +08:00
|
|
|
func Patch(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodPatch
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Trace trace请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:36:24
|
2022-05-01 22:38:31 +08:00
|
|
|
func Trace(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodTrace
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Connect connect请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022/05/01 21:36:39
|
2022-05-01 22:38:31 +08:00
|
|
|
func Connect(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
|
2022-05-02 15:17:21 +08:00
|
|
|
apiConfig.Method = http.MethodConnect
|
|
|
|
buildRequestURLAndParam(apiConfig, header, param)
|
|
|
|
return send(apiConfig, header)
|
2022-05-01 21:49:17 +08:00
|
|
|
}
|
2022-05-01 22:21:49 +08:00
|
|
|
|
2022-05-01 22:38:31 +08:00
|
|
|
// getHttpClient 获取httpclient实例
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 22:27 2022/5/1
|
2022-05-02 15:17:21 +08:00
|
|
|
func getHttpClient(apiConfig *ApiRequestConfig, header map[string]string) *httpclient.HttpClient {
|
2022-05-01 22:38:31 +08:00
|
|
|
fullHeader := make(map[string]string)
|
|
|
|
for name, val := range apiConfig.CommonHeader {
|
|
|
|
fullHeader[name] = val
|
|
|
|
}
|
|
|
|
for name, val := range header {
|
|
|
|
fullHeader[name] = val
|
|
|
|
}
|
2022-05-02 15:30:55 +08:00
|
|
|
if len(apiConfig.ContentType) == 0 {
|
|
|
|
apiConfig.ContentType = ContentTypeDefault
|
|
|
|
}
|
|
|
|
fullHeader["content-type"] = apiConfig.ContentType
|
|
|
|
return httpclient.NewHttpClient().WithHeaders(fullHeader).
|
2023-03-10 16:29:19 +08:00
|
|
|
WithOption(httpclient.OPT_CONNECTTIMEOUT_MS, apiConfig.Timeout.Connect).
|
|
|
|
WithOption(httpclient.OPT_TIMEOUT_MS, apiConfig.Timeout.Read)
|
2022-05-01 22:38:31 +08:00
|
|
|
}
|
|
|
|
|
2022-05-01 22:21:49 +08:00
|
|
|
// buildRequestURLAndParam 构建完整请求URL与请求参数
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 21:55 2022/5/1
|
2022-05-02 15:17:21 +08:00
|
|
|
func buildRequestURLAndParam(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) {
|
2022-05-01 22:21:49 +08:00
|
|
|
apiConfig.Method = strings.ToUpper(apiConfig.Method)
|
2022-05-02 15:30:55 +08:00
|
|
|
if apiConfig.Timeout.Connect == 0 {
|
|
|
|
apiConfig.Timeout.Connect = DefaultConnectTimeout
|
|
|
|
}
|
|
|
|
if apiConfig.Timeout.Read == 0 {
|
|
|
|
apiConfig.Timeout.Read = DefaultConnectTimeout
|
|
|
|
}
|
2022-05-01 22:21:49 +08:00
|
|
|
formatParam := make(map[string]interface{})
|
|
|
|
for paramName, paramValue := range param {
|
|
|
|
uriTemplate := "{" + paramName + "}"
|
|
|
|
if strings.Contains(apiConfig.URI, uriTemplate) {
|
|
|
|
apiConfig.URI = strings.ReplaceAll(apiConfig.URI, uriTemplate, fmt.Sprintf("%v", paramValue))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
formatParam[paramName] = paramValue
|
|
|
|
}
|
|
|
|
apiConfig.Parameter = formatParam
|
|
|
|
paramPair := make([]string, 0)
|
|
|
|
switch apiConfig.Method {
|
|
|
|
case http.MethodPost:
|
|
|
|
apiConfig.Body, _ = json.Marshal(formatParam)
|
|
|
|
default:
|
|
|
|
for paramName, paramValue := range formatParam {
|
|
|
|
paramPair = append(paramPair, fmt.Sprintf("%v=%v", paramName, paramValue))
|
|
|
|
}
|
|
|
|
if len(paramPair) > 0 {
|
|
|
|
apiConfig.URI = apiConfig.URI + "?" + strings.Join(paramPair, "&")
|
|
|
|
}
|
|
|
|
}
|
2023-03-10 16:29:19 +08:00
|
|
|
if strings.HasSuffix(apiConfig.Domain, "/") {
|
|
|
|
apiConfig.Domain = strings.TrimRight(apiConfig.Domain, "/")
|
|
|
|
}
|
|
|
|
if !strings.HasPrefix(apiConfig.URI, "/") {
|
|
|
|
apiConfig.URI = "/" + apiConfig.URI
|
|
|
|
}
|
|
|
|
apiConfig.FullURL = apiConfig.Domain + apiConfig.URI
|
2022-05-02 15:17:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// send 发送请求
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 14:53 2022/5/2
|
|
|
|
func send(apiConfig *ApiRequestConfig, header map[string]string) *ApiResponse {
|
|
|
|
var (
|
|
|
|
client *httpclient.HttpClient
|
|
|
|
err error
|
|
|
|
)
|
2022-05-01 22:21:49 +08:00
|
|
|
|
2022-05-02 15:17:21 +08:00
|
|
|
response := &ApiResponse{
|
|
|
|
RequestConfig: apiConfig,
|
|
|
|
Response: nil,
|
|
|
|
Exception: nil,
|
|
|
|
StartRequestTime: time.Now().UnixNano(),
|
|
|
|
FinishRequestTime: 0,
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
response.FinishRequestTime = time.Now().UnixNano()
|
|
|
|
}()
|
|
|
|
|
|
|
|
client = getHttpClient(apiConfig, header)
|
|
|
|
if response.Response, err = client.Do(apiConfig.Method, apiConfig.FullURL, nil, bytes.NewReader(apiConfig.Body)); nil != err {
|
|
|
|
response.Exception = NewException(SendRequestError, map[string]string{"real_reason": err.Error()})
|
|
|
|
}
|
|
|
|
return response
|
2022-05-01 22:21:49 +08:00
|
|
|
}
|