增加vendor
This commit is contained in:
+361
@@ -0,0 +1,361 @@
|
||||
package xhttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-pay/gopay"
|
||||
"github.com/go-pay/gopay/pkg/util"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
HttpClient *http.Client
|
||||
Transport *http.Transport
|
||||
Header http.Header
|
||||
Timeout time.Duration
|
||||
url string
|
||||
Host string
|
||||
method string
|
||||
requestType RequestType
|
||||
FormString string
|
||||
ContentType string
|
||||
unmarshalType string
|
||||
multipartBodyMap map[string]interface{}
|
||||
jsonByte []byte
|
||||
err error
|
||||
}
|
||||
|
||||
// NewClient , default tls.Config{InsecureSkipVerify: true}
|
||||
func NewClient() (client *Client) {
|
||||
client = &Client{
|
||||
HttpClient: &http.Client{
|
||||
Timeout: 60 * time.Second,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
DisableKeepAlives: true,
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
},
|
||||
},
|
||||
Transport: nil,
|
||||
Header: make(http.Header),
|
||||
requestType: TypeJSON,
|
||||
unmarshalType: string(TypeJSON),
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *Client) SetTransport(transport *http.Transport) (client *Client) {
|
||||
c.Transport = transport
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) SetTLSConfig(tlsCfg *tls.Config) (client *Client) {
|
||||
c.Transport = &http.Transport{TLSClientConfig: tlsCfg, DisableKeepAlives: true, Proxy: http.ProxyFromEnvironment}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) SetTimeout(timeout time.Duration) (client *Client) {
|
||||
c.Timeout = timeout
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) SetHost(host string) (client *Client) {
|
||||
c.Host = host
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Type(typeStr RequestType) (client *Client) {
|
||||
if _, ok := types[typeStr]; ok {
|
||||
c.requestType = typeStr
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Get(url string) (client *Client) {
|
||||
c.method = GET
|
||||
c.url = url
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Post(url string) (client *Client) {
|
||||
c.method = POST
|
||||
c.url = url
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Put(url string) (client *Client) {
|
||||
c.method = PUT
|
||||
c.url = url
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Delete(url string) (client *Client) {
|
||||
c.method = DELETE
|
||||
c.url = url
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) Patch(url string) (client *Client) {
|
||||
c.method = PATCH
|
||||
c.url = url
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) SendStruct(v interface{}) (client *Client) {
|
||||
if v == nil {
|
||||
return c
|
||||
}
|
||||
bs, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
c.err = fmt.Errorf("[%w]: %v, value: %v", gopay.MarshalErr, err, v)
|
||||
return c
|
||||
}
|
||||
switch c.requestType {
|
||||
case TypeJSON:
|
||||
c.jsonByte = bs
|
||||
case TypeXML, TypeUrlencoded, TypeForm, TypeFormData:
|
||||
body := make(map[string]interface{})
|
||||
if err = json.Unmarshal(bs, &body); err != nil {
|
||||
c.err = fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
||||
return c
|
||||
}
|
||||
c.FormString = FormatURLParam(body)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) SendBodyMap(bm map[string]interface{}) (client *Client) {
|
||||
if bm == nil {
|
||||
return c
|
||||
}
|
||||
switch c.requestType {
|
||||
case TypeJSON:
|
||||
bs, err := json.Marshal(bm)
|
||||
if err != nil {
|
||||
c.err = fmt.Errorf("[%w]: %v, value: %v", gopay.MarshalErr, err, bm)
|
||||
return c
|
||||
}
|
||||
c.jsonByte = bs
|
||||
case TypeXML, TypeUrlencoded, TypeForm, TypeFormData:
|
||||
c.FormString = FormatURLParam(bm)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) SendMultipartBodyMap(bm map[string]interface{}) (client *Client) {
|
||||
if bm == nil {
|
||||
return c
|
||||
}
|
||||
switch c.requestType {
|
||||
case TypeJSON:
|
||||
bs, err := json.Marshal(bm)
|
||||
if err != nil {
|
||||
c.err = fmt.Errorf("[%w]: %v, value: %v", gopay.MarshalErr, err, bm)
|
||||
return c
|
||||
}
|
||||
c.jsonByte = bs
|
||||
case TypeXML, TypeUrlencoded, TypeForm, TypeFormData:
|
||||
c.FormString = FormatURLParam(bm)
|
||||
case TypeMultipartFormData:
|
||||
c.multipartBodyMap = bm
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// encodeStr: url.Values.Encode() or jsonBody
|
||||
func (c *Client) SendString(encodeStr string) (client *Client) {
|
||||
switch c.requestType {
|
||||
case TypeJSON:
|
||||
c.jsonByte = []byte(encodeStr)
|
||||
case TypeXML, TypeUrlencoded, TypeForm, TypeFormData:
|
||||
c.FormString = encodeStr
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) EndStruct(ctx context.Context, v interface{}) (res *http.Response, err error) {
|
||||
res, bs, err := c.EndBytes(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return res, fmt.Errorf("StatusCode(%d) != 200", res.StatusCode)
|
||||
}
|
||||
|
||||
switch c.unmarshalType {
|
||||
case string(TypeJSON):
|
||||
err = json.Unmarshal(bs, &v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
||||
}
|
||||
return res, nil
|
||||
case string(TypeXML):
|
||||
err = xml.Unmarshal(bs, &v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
||||
}
|
||||
return res, nil
|
||||
default:
|
||||
return nil, errors.New("unmarshalType Type Wrong")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) EndBytes(ctx context.Context) (res *http.Response, bs []byte, err error) {
|
||||
if c.err != nil {
|
||||
return nil, nil, c.err
|
||||
}
|
||||
var (
|
||||
body io.Reader
|
||||
bw *multipart.Writer
|
||||
)
|
||||
// multipart-form-data
|
||||
if c.requestType == TypeMultipartFormData {
|
||||
body = &bytes.Buffer{}
|
||||
bw = multipart.NewWriter(body.(io.Writer))
|
||||
}
|
||||
|
||||
reqFunc := func() (err error) {
|
||||
switch c.method {
|
||||
case GET:
|
||||
switch c.requestType {
|
||||
case TypeJSON:
|
||||
c.ContentType = types[TypeJSON]
|
||||
case TypeForm, TypeFormData, TypeUrlencoded:
|
||||
c.ContentType = types[TypeForm]
|
||||
case TypeMultipartFormData:
|
||||
c.ContentType = bw.FormDataContentType()
|
||||
case TypeXML:
|
||||
c.ContentType = types[TypeXML]
|
||||
c.unmarshalType = string(TypeXML)
|
||||
default:
|
||||
return errors.New("Request type Error ")
|
||||
}
|
||||
case POST, PUT, DELETE, PATCH:
|
||||
switch c.requestType {
|
||||
case TypeJSON:
|
||||
if c.jsonByte != nil {
|
||||
body = strings.NewReader(string(c.jsonByte))
|
||||
}
|
||||
c.ContentType = types[TypeJSON]
|
||||
case TypeForm, TypeFormData, TypeUrlencoded:
|
||||
body = strings.NewReader(c.FormString)
|
||||
c.ContentType = types[TypeForm]
|
||||
case TypeMultipartFormData:
|
||||
for k, v := range c.multipartBodyMap {
|
||||
// file 参数
|
||||
if file, ok := v.(*util.File); ok {
|
||||
fw, err := bw.CreateFormFile(k, file.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = fw.Write(file.Content)
|
||||
continue
|
||||
}
|
||||
// text 参数
|
||||
vs, ok2 := v.(string)
|
||||
if ok2 {
|
||||
_ = bw.WriteField(k, vs)
|
||||
} else if ss := util.ConvertToString(v); ss != "" {
|
||||
_ = bw.WriteField(k, ss)
|
||||
}
|
||||
}
|
||||
_ = bw.Close()
|
||||
c.ContentType = bw.FormDataContentType()
|
||||
case TypeXML:
|
||||
body = strings.NewReader(c.FormString)
|
||||
c.ContentType = types[TypeXML]
|
||||
c.unmarshalType = string(TypeXML)
|
||||
default:
|
||||
return errors.New("Request type Error ")
|
||||
}
|
||||
default:
|
||||
return errors.New("Only support GET and POST and PUT and DELETE ")
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, c.method, c.url, body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header = c.Header
|
||||
req.Header.Set("Content-Type", c.ContentType)
|
||||
if c.Transport != nil {
|
||||
c.HttpClient.Transport = c.Transport
|
||||
}
|
||||
if c.Host != "" {
|
||||
req.Host = c.Host
|
||||
}
|
||||
if c.Timeout > 0 {
|
||||
c.HttpClient.Timeout = c.Timeout
|
||||
}
|
||||
res, err = c.HttpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
bs, err = ioutil.ReadAll(io.LimitReader(res.Body, int64(5<<20))) // default 5MB change the size you want
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = reqFunc(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return res, bs, nil
|
||||
}
|
||||
|
||||
func FormatURLParam(body map[string]interface{}) (urlParam string) {
|
||||
var (
|
||||
buf strings.Builder
|
||||
keys []string
|
||||
)
|
||||
for k := range body {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
v, ok := body[k].(string)
|
||||
if !ok {
|
||||
v = convertToString(body[k])
|
||||
}
|
||||
if v != "" {
|
||||
buf.WriteString(url.QueryEscape(k))
|
||||
buf.WriteByte('=')
|
||||
buf.WriteString(url.QueryEscape(v))
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
}
|
||||
if buf.Len() <= 0 {
|
||||
return ""
|
||||
}
|
||||
return buf.String()[:buf.Len()-1]
|
||||
}
|
||||
|
||||
func convertToString(v interface{}) (str string) {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
var (
|
||||
bs []byte
|
||||
err error
|
||||
)
|
||||
if bs, err = json.Marshal(v); err != nil {
|
||||
return ""
|
||||
}
|
||||
str = string(bs)
|
||||
return
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package xhttp
|
||||
|
||||
type RequestType string
|
||||
|
||||
const (
|
||||
GET = "GET"
|
||||
POST = "POST"
|
||||
PUT = "PUT"
|
||||
DELETE = "DELETE"
|
||||
PATCH = "PATCH"
|
||||
TypeJSON RequestType = "json"
|
||||
TypeXML RequestType = "xml"
|
||||
TypeUrlencoded RequestType = "urlencoded"
|
||||
TypeForm RequestType = "form"
|
||||
TypeFormData RequestType = "form-data"
|
||||
TypeMultipartFormData RequestType = "multipart-form-data"
|
||||
)
|
||||
|
||||
var types = map[RequestType]string{
|
||||
TypeJSON: "application/json",
|
||||
TypeXML: "application/xml",
|
||||
TypeUrlencoded: "application/x-www-form-urlencoded",
|
||||
TypeForm: "application/x-www-form-urlencoded",
|
||||
TypeFormData: "application/x-www-form-urlencoded",
|
||||
TypeMultipartFormData: "multipart/form-data",
|
||||
}
|
||||
Reference in New Issue
Block a user