Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
package httputil
import (
"errors"
"io"
"net"
"net/http"
"net/url"
"strconv"
"sync"
"time"
)
const defaultTimeOut = 10
var (
defaultClient *http.Client
httpClientMap sync.Map
errProxyNil = errors.New("proxy is nil")
)
func init() {
defaultClient = &http.Client{
Timeout: time.Second * time.Duration(defaultTimeOut),
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: time.Second * 30,
KeepAlive: time.Second * 30,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: time.Second * 90,
TLSHandshakeTimeout: time.Second * 10,
ExpectContinueTimeout: time.Second,
},
}
}
// 传入参数单位秒
func getClientByTimeoutSet(connTimeout int) *http.Client {
if connTimeout == defaultTimeOut {
return defaultClient
}
client, _ := httpClientMap.LoadOrStore(connTimeout, &http.Client{
Timeout: time.Duration(connTimeout) * time.Second,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: time.Second * 30,
KeepAlive: time.Second * 30,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: time.Second * 90,
TLSHandshakeTimeout: time.Second * 10,
ExpectContinueTimeout: time.Second,
},
})
return client.(*http.Client)
}
type ProxyCfg struct {
Host string
Timeout int //秒
Source string
IsActive bool //是否开启代理
}
func (p *ProxyCfg) Build(rawurl string, rawHeaders map[string]string) (string, map[string]string, error) {
if !p.IsActive {
return rawurl, rawHeaders, nil
}
u, err := url.Parse(rawurl)
if err != nil {
return "", nil, err
}
target := url.URL{Scheme: u.Scheme, Host: u.Host}
u.Host = p.Host
u.Scheme = "http"
m := make(map[string]string)
m["X-Proxy-Target-Host"] = target.String()
m["X-Proxy-Source"] = "ys"
if p.Timeout > 0 {
m["X-Proxy-Timeout"] = strconv.Itoa(p.Timeout)
}
if len(rawHeaders) > 0 {
for k, v := range rawHeaders {
m[k] = v
}
}
return u.String(), m, nil
}
// 提供关闭函数以防止内存泄露
func IgnoreResp(resp *http.Response) {
_, _ = io.Copy(io.Discard, resp.Body)
resp.Body.Close()
}
+175
View File
@@ -0,0 +1,175 @@
package httputil
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
)
func ClientGet(connTimeout int, url string, headers map[string]string, params ...any) (*http.Response, error) {
for _, p := range params {
url = addParams(url, toUrlValues(p))
}
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
for k, v := range headers {
req.Header.Set(k, v)
}
cl := getClientByTimeoutSet(connTimeout)
return cl.Do(req)
}
func DefaultClientGet(url string, headers map[string]string, params ...any) (*http.Response, error) {
return ClientGet(defaultTimeOut, url, headers, params...)
}
func ClientGetBytes(connTimeout int, url string, headers map[string]string, params ...any) (int, []byte, error) {
resp, err := ClientGet(connTimeout, url, headers, params...)
if err != nil {
return 0, nil, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, nil, err
}
return resp.StatusCode, ct, nil
}
func DefaultClientGetBytes(url string, headers map[string]string, params ...any) (int, []byte, error) {
return ClientGetBytes(defaultTimeOut, url, headers, params...)
}
func ClientGetBytesWithProxy(connTimeout int, p *ProxyCfg, url string, headers map[string]string, params ...any) (int, []byte, error) {
if p == nil {
return 0, nil, errProxyNil
}
pUrl, pHeaders, err := p.Build(url, headers)
if err != nil {
return 0, nil, err
}
return ClientGetBytes(connTimeout, pUrl, pHeaders, params...)
}
func ClientGetWithRespWithProxy(connTimeout int, p *ProxyCfg, bind any, url string, headers map[string]string, params ...any) (int, error) {
code, bts, err := ClientGetBytesWithProxy(connTimeout, p, url, headers, params...)
if err != nil {
return code, err
}
return code, json.Unmarshal(bts, &bind)
}
func DefaultClientGetWithRespWithProxy(p *ProxyCfg, bind any, url string, headers map[string]string, params ...any) (int, error) {
return ClientGetWithRespWithProxy(defaultTimeOut, p, bind, url, headers, params...)
}
func ClientGetWithResp(bind any, connTimeout int, url string, headers map[string]string, params ...any) (int, error) {
code, ct, err := ClientGetBytes(connTimeout, url, headers, params...)
if err != nil {
return code, err
}
return code, json.Unmarshal(ct, &bind)
}
func DefaultClientGetWithResp(bind any, url string, headers map[string]string, params ...any) (int, error) {
return ClientGetWithResp(bind, defaultTimeOut, url, headers, params...)
}
func ClientGetWithRespWithCtx(ctx context.Context, bind any, connTimeout int, url string, headers map[string]string, params ...any) (int, error) {
code, ct, err := ClientGetBytesWithCtx(ctx, connTimeout, url, headers, params...)
if err != nil {
return code, err
}
return code, json.Unmarshal(ct, &bind)
}
func DefaultClientGetWithRespWithCtx(ctx context.Context, bind any, url string, headers map[string]string, params ...any) (int, error) {
code, ct, err := ClientGetBytesWithCtx(ctx, defaultTimeOut, url, headers, params...)
if err != nil {
return code, err
}
return code, json.Unmarshal(ct, &bind)
}
func ClientGetWithCtx(ctx context.Context, connTimeout int, url string, headers map[string]string, params ...any) (*http.Response, error) {
for _, p := range params {
url = addParams(url, toUrlValues(p))
}
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
for k, v := range headers {
req.Header.Add(k, v)
}
req = req.WithContext(ctx)
cl := getClientByTimeoutSet(connTimeout)
return cl.Do(req)
}
func DefaultClientGetWithCtx(ctx context.Context, url string, headers map[string]string, params ...any) (*http.Response, error) {
return ClientGetWithCtx(ctx, defaultTimeOut, url, headers, params...)
}
func ClientGetBytesWithCtx(ctx context.Context, connTimeout int, url string, headers map[string]string, params ...any) (int, []byte, error) {
resp, err := ClientGetWithCtx(ctx, connTimeout, url, headers, params...)
if err != nil {
return 0, nil, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, nil, err
}
return resp.StatusCode, ct, nil
}
func DefaultClientGetBytesWithCtx(ctx context.Context, url string, headers map[string]string, params ...any) (int, []byte, error) {
return ClientGetBytesWithCtx(ctx, defaultTimeOut, url, headers, params...)
}
func toUrlValues(v interface{}) url.Values {
switch t := v.(type) {
case url.Values:
return t
case map[string][]string:
return url.Values(t)
case map[string]string:
rst := make(url.Values)
for k, v := range t {
rst.Add(k, v)
}
return rst
case map[string]interface{}:
rst := make(url.Values)
for k, v := range t {
rst.Add(k, fmt.Sprintf("%v", v))
}
return rst
case nil:
return make(url.Values)
default:
panic("Invalid value")
}
}
func addParams(url_ string, params url.Values) string {
if len(params) == 0 {
return url_
}
if !strings.Contains(url_, "?") {
url_ += "?"
}
if strings.HasSuffix(url_, "?") || strings.HasSuffix(url_, "&") {
url_ += params.Encode()
} else {
url_ += "&" + params.Encode()
}
return url_
}
+198
View File
@@ -0,0 +1,198 @@
package httputil
import (
"bytes"
"context"
"encoding/json"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
)
func ClientPost(connTimeout int, url string, headers map[string]string, data any) (*http.Response, error) {
req, err := getPostRequest(url, headers, data)
if err != nil {
return nil, err
}
cl := getClientByTimeoutSet(connTimeout)
return cl.Do(req)
}
func DefaultClientPost(url string, headers map[string]string, data any) (*http.Response, error) {
return ClientPost(defaultTimeOut, url, headers, data)
}
func ClientPostWithCtx(ctx context.Context, connTimeout int, url string, headers map[string]string, data any) (*http.Response, error) {
req, err := getPostRequest(url, headers, data)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
cl := getClientByTimeoutSet(connTimeout)
return cl.Do(req)
}
func DefaultClientPostWithCtx(ctx context.Context, url string, headers map[string]string, data any) (*http.Response, error) {
return ClientPostWithCtx(ctx, defaultTimeOut, url, headers, data)
}
func ClientPostWithProxy(connTimeout int, p *ProxyCfg, url string, headers map[string]string, data any) (*http.Response, error) {
if p == nil {
return nil, errProxyNil
}
pUrl, pHeaders, err := p.Build(url, headers)
if err != nil {
return nil, err
}
return ClientPost(connTimeout, pUrl, pHeaders, data)
}
func ClientPostWithResp(connTimeout int, bind any, url string, headers map[string]string, data any) (int, error) {
resp, err := ClientPost(connTimeout, url, headers, data)
if err != nil {
return 0, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, err
}
return resp.StatusCode, json.Unmarshal(ct, &bind)
}
func DefaultClientPostWithResp(bind any, url string, headers map[string]string, data any) (int, error) {
return ClientPostWithResp(defaultTimeOut, bind, url, headers, data)
}
func ClientPostWithRespWithCtx(ctx context.Context, connTimeout int, bind any, url string, headers map[string]string, data any) (int, error) {
resp, err := ClientPostWithCtx(ctx, connTimeout, url, headers, data)
if err != nil {
return 0, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, err
}
return resp.StatusCode, json.Unmarshal(ct, &bind)
}
func DefaultClientPostWithRespWithCtx(ctx context.Context, bind any, url string, headers map[string]string, data any) (int, error) {
return ClientPostWithRespWithCtx(ctx, defaultTimeOut, bind, url, headers, data)
}
func ClientPostWithRespWithProxy(connTimeout int, p *ProxyCfg, bind any, url string, headers map[string]string, data any) (int, error) {
resp, err := ClientPostWithProxy(connTimeout, p, url, headers, data)
if err != nil {
return 0, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, err
}
return resp.StatusCode, json.Unmarshal(ct, &bind)
}
func DefaultClientPostWithRespWithProxy(p *ProxyCfg, bind any, url string, headers map[string]string, data any) (int, error) {
return ClientPostWithRespWithProxy(defaultTimeOut, p, &bind, url, headers, data)
}
func getPostRequest(url string, headers map[string]string, data any) (*http.Request, error) {
switch data.(type) {
case []byte, string, *bytes.Reader, *bytes.Buffer:
req, err := http.NewRequest(http.MethodPost, url, toReader(data))
if err != nil {
return nil, err
}
for k, v := range headers {
req.Header.Set(k, v)
}
return req, nil
default:
}
paramsValues := toUrlValues(data)
if checkParamFile(paramsValues) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
for k, v := range paramsValues {
for _, vv := range v {
// is file
if k[0] == '@' {
if err := addFormFile(writer, k[1:], vv); err != nil {
return nil, err
}
continue
}
_ = writer.WriteField(k, vv)
}
}
req, err := http.NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, err
}
for k, v := range headers {
req.Header.Set(k, v)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
if err = writer.Close(); err != nil {
return nil, err
}
return req, nil
}
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(paramsValues.Encode()))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
for k, v := range headers {
req.Header.Set(k, v)
}
return req, nil
}
func toReader(v interface{}) *bytes.Reader {
switch t := v.(type) {
case []byte:
return bytes.NewReader(t)
case string:
return bytes.NewReader([]byte(t))
case *bytes.Buffer:
return bytes.NewReader(t.Bytes())
case *bytes.Reader:
return t
case nil:
return bytes.NewReader(nil)
default:
panic("Invalid value")
}
}
// Does the params contain a file?
func checkParamFile(params url.Values) bool {
for k := range params {
if k[0] == '@' {
return true
}
}
return false
}
// Add a file to a multipart writer.
func addFormFile(writer *multipart.Writer, name, path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
part, err := writer.CreateFormFile(name, filepath.Base(path))
if err != nil {
return err
}
_, err = io.Copy(part, file)
return err
}
+135
View File
@@ -0,0 +1,135 @@
package httputil
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
)
func ClientPostJson(connTimeout int, url string, headers map[string]string, data any) (*http.Response, error) {
body, err := dataToJsonReader(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
for k, v := range headers {
req.Header.Set(k, v)
}
cl := getClientByTimeoutSet(connTimeout)
return cl.Do(req)
}
func DefaultClientPostJson(url string, headers map[string]string, data any) (*http.Response, error) {
return ClientPostJson(defaultTimeOut, url, headers, data)
}
func ClientPostJsonWithProxy(connTimeout int, p *ProxyCfg, url string, headers map[string]string, params any) (*http.Response, error) {
if p == nil {
return nil, errProxyNil
}
pUrl, pHeaders, err := p.Build(url, headers)
if err != nil {
return nil, err
}
return ClientPostJson(connTimeout, pUrl, pHeaders, params)
}
func DefaultClientPostJsonWithProxy(p *ProxyCfg, url string, headers map[string]string, params any) (*http.Response, error) {
return ClientPostJsonWithProxy(defaultTimeOut, p, url, headers, params)
}
func ClientPostJsonWithRespWithProxy(connTimeout int, p *ProxyCfg, bind any, url string, headers map[string]string, data any) (int, error) {
resp, err := ClientPostJsonWithProxy(connTimeout, p, url, headers, data)
if err != nil {
return 0, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, err
}
return resp.StatusCode, json.Unmarshal(ct, &bind)
}
func DefaultClientPostJsonWithRespWithProxy(p *ProxyCfg, bind any, url string, headers map[string]string, data any) (int, error) {
return ClientPostJsonWithRespWithProxy(defaultTimeOut, p, bind, url, headers, data)
}
func ClientPostJsonWithResp(connTimeout int, bind any, url string, headers map[string]string, data any) (int, error) {
resp, err := ClientPostJson(connTimeout, url, headers, data)
if err != nil {
return 0, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, err
}
return resp.StatusCode, json.Unmarshal(ct, &bind)
}
func DefaultClientPostJsonWithResp(bind any, url string, headers map[string]string, data any) (int, error) {
return ClientPostJsonWithResp(defaultTimeOut, bind, url, headers, data)
}
func ClientPostJsonWithCtx(ctx context.Context, connTimeout int, url string, headers map[string]string, data any) (*http.Response, error) {
cl := getClientByTimeoutSet(connTimeout)
body, err := dataToJsonReader(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
for k, v := range headers {
req.Header.Set(k, v)
}
req = req.WithContext(ctx)
return cl.Do(req)
}
func DefaultClientPostJsonWithCtx(ctx context.Context, url string, headers map[string]string, data any) (*http.Response, error) {
return ClientPostJsonWithCtx(ctx, defaultTimeOut, url, headers, data)
}
func ClientPostJsonWithRespWithCtx(ctx context.Context, bind any, connTimeout int, url string, headers map[string]string, data any) (int, error) {
resp, err := ClientPostJsonWithCtx(ctx, connTimeout, url, headers, data)
if err != nil {
return 0, err
}
ct, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return resp.StatusCode, err
}
return resp.StatusCode, json.Unmarshal(ct, &bind)
}
func DefaultClientPostJsonWithRespWithCtx(ctx context.Context, bind any, url string, headers map[string]string, data any) (int, error) {
return ClientPostJsonWithRespWithCtx(ctx, bind, defaultTimeOut, url, headers, data)
}
func dataToJsonReader(data any) (*bytes.Reader, error) {
var body []byte
switch t := data.(type) {
case []byte:
body = t
case string:
body = []byte(t)
default:
var err error
body, err = json.Marshal(data)
if err != nil {
return nil, err
}
}
return bytes.NewReader(body), nil
}
+282
View File
@@ -0,0 +1,282 @@
package httputil
import (
"91porn-server/common/log"
"91porn-server/middleware/requestid"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/ddliu/go-httpclient"
"io"
"net/http"
"strconv"
)
// HTTPClient htttp客户端
type HTTPClient struct {
client *httpclient.HttpClient
}
func NewHTTPClient(client *httpclient.HttpClient) *HTTPClient {
return &HTTPClient{client}
}
type httpClientPool struct {
cliPool map[string]*httpclient.HttpClient
poolSize int
offset int
}
// HTTPResponse http响应
type HTTPResponse struct {
StatusCode int `json:"statusCode"`
Body *httpclient.Response `json:"boby"`
}
var httpCliPool = httpClientPool{cliPool: map[string]*httpclient.HttpClient{}, poolSize: 50}
func New() *HTTPClient {
h := httpclient.NewHttpClient().WithOptions(httpclient.Map{
httpclient.OPT_CONNECTTIMEOUT: 5,
httpclient.OPT_TIMEOUT: 10,
})
return &HTTPClient{client: h}
}
func NewCtx(ctx context.Context) *HTTPClient {
reqID, _ := ctx.Value(requestid.ContextKey).(string)
h := httpclient.NewHttpClient().WithOptions(httpclient.Map{
httpclient.OPT_CONNECTTIMEOUT: 5,
httpclient.OPT_TIMEOUT: 10,
httpclient.OPT_CONTEXT: ctx,
}).WithHeader(requestid.HeaderKey, reqID)
return &HTTPClient{client: h.Begin()}
}
// GetHTTPClient 获取httpclient
func Client() *HTTPClient {
cliID := "CLIENT-ID-"
if len(httpCliPool.cliPool) < httpCliPool.poolSize {
h := httpclient.NewHttpClient().Defaults(httpclient.Map{
httpclient.OPT_CONNECTTIMEOUT: 5,
})
cliID = cliID + strconv.FormatInt(int64(len(httpCliPool.cliPool)+1), 10)
httpCliPool.cliPool[cliID] = h
httpCliPool.offset = httpCliPool.poolSize
return &HTTPClient{client: h}
}
if httpCliPool.offset == httpCliPool.poolSize+1 {
httpCliPool.offset = 1
}
cliID = cliID + strconv.FormatInt(int64(httpCliPool.offset), 10)
httpCliPool.offset = httpCliPool.offset + 1
h, ok := httpCliPool.cliPool[cliID]
if !ok || h == nil {
h = httpclient.NewHttpClient().WithOption(httpclient.OPT_CONNECTTIMEOUT, 10)
httpCliPool.cliPool[cliID] = h
return &HTTPClient{client: h}
}
return &HTTPClient{client: h}
}
func jsonUnmarshalResp(bind interface{}, resp *HTTPResponse) error {
if bind == nil { //传入空表示只执行 defer
return nil
}
b, err := resp.Body.ReadAll()
if err != nil {
log.Error("httputil jsonUnmarshalResp readall err", log.E(err))
return err
}
err = json.Unmarshal(b, bind)
if err != nil {
log.Error("httputil jsonUnmarshalResp Unmarshal err", log.E(err))
}
return err
}
// Get Get方法
func (h *HTTPClient) Get(url string, headers map[string]string, params ...interface{}) (*HTTPResponse, error) {
h.client.WithHeaders(headers)
response, err := h.client.Get(url, params...)
if err != nil {
log.Error(fmt.Sprintf("http client Get method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
func (h *HTTPClient) PGet(p *ProxyCfg, url string, headers map[string]string, params ...interface{}) (*HTTPResponse, error) {
purl, pheaders, err := p.Build(url, headers)
if err != nil {
return nil, err
}
return h.Get(purl, pheaders, params)
}
// Get GetBytes
func (h *HTTPClient) GetBytes(url string, headers map[string]string, params ...interface{}) ([]byte, error) {
h.client.WithHeaders(headers)
response, err := h.client.Get(url, params...)
if err != nil {
log.Error(fmt.Sprintf("http client Get method failed %+v:", err))
return nil, err
}
if response.StatusCode != http.StatusOK {
log.Error("http client Get method status code not ok", log.Any("url", url), log.Any("headers", headers), log.Any("params", params), log.Any("res", response))
return nil, errors.New("http response satus code not ok statusCoe:" + response.Status)
}
data, err := response.ReadAll()
if err != nil {
log.ZapLog.Error("resp readAll errror", log.Any("Error", err))
return data, err
}
return data, nil
}
// GetWithJResp 结果json.Unmarshal到bind中
func (h *HTTPClient) GetWithJResp(bind interface{}, url string, headers map[string]string, params ...interface{}) (int, error) {
resp, err := h.Get(url, headers, params...)
if err != nil {
return 0, err
}
defer func() { _ = resp.Body.Body.Close() }()
if resp.StatusCode == http.StatusOK {
err = jsonUnmarshalResp(bind, resp)
}
return resp.StatusCode, err
}
func (h *HTTPClient) PGetWithJResp(p *ProxyCfg, bind interface{}, url string, headers map[string]string, params ...interface{}) (int, error) {
purl, pheaders, err := p.Build(url, headers)
if err != nil {
return 0, err
}
return h.GetWithJResp(bind, purl, pheaders, params...)
}
// Post Post方法
func (h *HTTPClient) Post(url string, headers map[string]string, params interface{}) (*HTTPResponse, error) {
h.client.WithHeaders(headers)
response, err := h.client.Post(url, params)
if err != nil {
log.Error(fmt.Sprintf("http client Post method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
func (h *HTTPClient) PPost(p *ProxyCfg, bind interface{}, url string, headers map[string]string, params interface{}) (*HTTPResponse, error) {
purl, pheaders, err := p.Build(url, headers)
if err != nil {
return nil, err
}
return h.Post(purl, pheaders, params)
}
// POSTJson PostJson方法
func (h *HTTPClient) POSTJson(url string, headers map[string]string, data interface{}) (*HTTPResponse, error) {
h.client.WithHeaders(headers)
response, err := h.client.PostJson(url, data)
if err != nil {
log.Error(fmt.Sprintf("http client POSTJson method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
// POSTJson PostJson方法, bind json.Unmarshal
func (h *HTTPClient) POSTJsonWithJResp(bind interface{}, url string, headers map[string]string, data interface{}) (int, error) {
resp, err := h.POSTJson(url, headers, data)
if err != nil {
log.Error("POSTJsonWithResp err", log.E(err))
return 0, err
}
defer resp.Body.Body.Close()
if resp.StatusCode == http.StatusOK {
err = jsonUnmarshalResp(bind, resp)
}
return resp.StatusCode, err
}
func (h *HTTPClient) PPOSTJsonWithJResp(p *ProxyCfg, bind interface{}, url string, headers map[string]string, data interface{}) (int, error) {
if p == nil {
return 0, fmt.Errorf("ProxyCfg is nil")
}
purl, pheaders, err := p.Build(url, headers)
if err != nil {
return 0, err
}
return h.POSTJsonWithJResp(bind, purl, pheaders, data)
}
// PostMultipart PostMultipart 上传文件
func (h *HTTPClient) PostMultipart(url string, headers map[string]string, params interface{}) (*HTTPResponse, error) {
h.client.WithHeaders(headers)
response, err := h.client.PostMultipart(url, params)
if err != nil {
log.Error(fmt.Sprintf("http client PostMultipart method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
// Put 流式传输 可用于上传文件
func (h *HTTPClient) Put(url string, headers map[string]string, body io.Reader) (*HTTPResponse, error) {
h.client.WithHeaders(headers)
response, err := h.client.Put(url, body)
if err != nil {
log.Error(fmt.Sprintf("http client PostMultipart method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
// PutJSON PutJSON方法
func (h *HTTPClient) PutJSON(url string, headers map[string]string, data interface{}) (*HTTPResponse, error) {
h.client.WithHeaders(headers)
response, err := h.client.PutJson(url, data)
if err != nil {
log.Error(fmt.Sprintf("http client PostMultipart method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
// Header Header
func (h *HTTPClient) Header(url string) (*HTTPResponse, error) {
response, err := h.client.Head(url)
if err != nil {
log.Error(fmt.Sprintf("http client PostMultipart method failed %+v:", err))
return nil, err
}
return &HTTPResponse{StatusCode: response.StatusCode, Body: response}, nil
}
// POSTWithJResp 结果json.Unmarshal到bind中 用于上传文件, content-type :"application/x-www-form-urlencoded" 如参数以@开头 则为上传文件
func (h *HTTPClient) POSTWithJResp(bind interface{}, url string, headers map[string]string, params interface{}) (int, error) {
resp, err := h.Post(url, headers, params)
if err != nil {
return 0, err
}
defer resp.Body.Body.Close()
if resp.StatusCode == http.StatusOK {
err = jsonUnmarshalResp(bind, resp)
}
return resp.StatusCode, err
}
// PPOSTWithJResp 结果json.Unmarshal到bind中 用于上传文件, content-type :"application/x-www-form-urlencoded" 如参数以@开头 则为上传文件
func (h *HTTPClient) PPOSTWithJResp(p *ProxyCfg, bind interface{}, url string, headers map[string]string, params interface{}) (int, error) {
resp, err := h.PPost(p, bind, url, headers, params)
if err != nil {
return 0, err
}
defer resp.Body.Body.Close()
if resp.StatusCode == http.StatusOK {
err = jsonUnmarshalResp(bind, resp)
}
return resp.StatusCode, err
}