优化插件的参数请求

This commit is contained in:
Yun
2024-01-01 14:10:18 +08:00
parent c7c03ab1d3
commit 5159d5d258
6 changed files with 238 additions and 102 deletions
+49 -49
View File
@@ -19,9 +19,20 @@ import (
* Date: 2023年7月12日11:35:01 * Date: 2023年7月12日11:35:01
*/ */
var ( // type DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
// 默认的transport
transport http.Transport = http.Transport{ type Curlx struct {
opts clientOptions
transport *http.Transport
}
func NewCurlx(opts ...Option) *Curlx {
defaultOpts := defaultOptions()
for _, apply := range opts {
apply(&defaultOpts)
}
transport := &http.Transport{
// Dial: func(netw, addr string) (net.Conn, error) { // Dial: func(netw, addr string) (net.Conn, error) {
// // 这里指定域名访问的IP // // 这里指定域名访问的IP
// // if addr == "api.hk.blueoceanpay.com:443" { // // if addr == "api.hk.blueoceanpay.com:443" {
@@ -48,22 +59,16 @@ var (
MaxConnsPerHost: 0, // 每个host的最大连接数量 MaxConnsPerHost: 0, // 每个host的最大连接数量
IdleConnTimeout: time.Second * 2, // 空闲连接超时关闭的时间 IdleConnTimeout: time.Second * 2, // 空闲连接超时关闭的时间
} }
// client = &http.Client{}
) if defaultOpts.InsecureSkipVerify {
transport.TLSClientConfig.InsecureSkipVerify = true
type DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
type Curlx struct {
transport *http.Transport
timeOutSecond int
}
func NewCurlx() *Curlx {
return &Curlx{
transport: &transport,
timeOutSecond: 180,
} }
return &Curlx{
opts: defaultOpts,
transport: transport,
}
} }
/** /**
@@ -72,8 +77,8 @@ func NewCurlx() *Curlx {
*/ */
func (c *Curlx) WithProxySocks5(address string) error { func (c *Curlx) WithProxySocks5(address string) error {
baseDialer := &net.Dialer{ baseDialer := &net.Dialer{
Timeout: 180 * time.Second, // Timeout: 180 * time.Second,
KeepAlive: 180 * time.Second, // KeepAlive: 180 * time.Second,
} }
dialSocksProxy, err := proxy.SOCKS5("tcp", address, nil, baseDialer) dialSocksProxy, err := proxy.SOCKS5("tcp", address, nil, baseDialer)
if err != nil { if err != nil {
@@ -101,30 +106,20 @@ func (c *Curlx) WithProxyHttp(proxyAddr string) error {
return nil return nil
} }
/**
* 不校验HTTPS证书
*/
func (c *Curlx) WithInsecureSkipVerify() {
c.transport.TLSClientConfig.InsecureSkipVerify = true
}
/**
* 设置超时时间,单位秒
*/
func (c *Curlx) WithTimeout(timeout int) {
c.timeOutSecond = timeout
}
// 指定访问的IP // 指定访问的IP
// func(c *curlx) WithIp(ip string) { // 127.0.0.1:8080
// c.transport.Dial func (c *Curlx) WithAddress(ctx context.Context, addr string) {
// } // network tcp/udp
c.transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return net.Dial(network, addr)
}
}
/** /**
* 简单请求 * 简单请求
*/ */
func (c *Curlx) Send(ctx context.Context, p *CurlParams) (res string, httpcode int, err error) { func (c *Curlx) Send(ctx context.Context, p ...Param) (res string, httpcode int, err error) {
response, err := c.sendExec(ctx, p) _, response, err := c.sendExec(ctx, p...)
if err != nil { if err != nil {
return "", -1, err return "", -1, err
} }
@@ -163,27 +158,32 @@ func (c *Curlx) Send(ctx context.Context, p *CurlParams) (res string, httpcode i
* 执行发送 * 执行发送
* 注意:外部使用需要加这一句 defer response.Body.Close() * 注意:外部使用需要加这一句 defer response.Body.Close()
*/ */
func (c *Curlx) sendExec(ctx context.Context, p *CurlParams) (resp *http.Response, err error) { func (c *Curlx) sendExec(ctx context.Context, ps ...Param) (req *http.Request, resp *http.Response, err error) {
client := &http.Client{ client := &http.Client{
Timeout: time.Second * time.Duration(c.timeOutSecond), // 整个请求的超时时间 设置该条连接的超时 Timeout: c.opts.TimeOut, // 整个请求的超时时间 设置该条连接的超时
Transport: c.transport, // Transport: c.transport, //
}
p := defaultParams()
for _, param := range ps {
param(&p)
} }
err = p.parseMethod() err = p.parseMethod()
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// 判断和处理url // 判断和处理url
err = p.parseUrl() err = p.parseUrl()
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// 处理参数 // 处理参数
reqParams, err := p.parseParams() reqParams, err := p.parseParams()
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// 初始化句柄 // 初始化句柄
@@ -193,7 +193,7 @@ func (c *Curlx) sendExec(ctx context.Context, p *CurlParams) (resp *http.Respons
reqParams, reqParams,
) )
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// 这里指定要访问的HOST,到时候服务器获取主机是获取到这个 // 这里指定要访问的HOST,到时候服务器获取主机是获取到这个
@@ -211,16 +211,16 @@ func (c *Curlx) sendExec(ctx context.Context, p *CurlParams) (resp *http.Respons
// 发起请求 // 发起请求
response, err := client.Do(request) response, err := client.Do(request)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// response.StatusCode // response.StatusCode
return response, nil return request, response, nil
} }
/** /**
* 流式请求 * 流式请求
*/ */
func (c *Curlx) SendChan(ctx context.Context, p *CurlParams) (<-chan string, error) { func (c *Curlx) SendChan(ctx context.Context, ps ...Param) (<-chan string, error) {
data := make(chan string, 1000) data := make(chan string, 1000)
@@ -230,7 +230,7 @@ func (c *Curlx) SendChan(ctx context.Context, p *CurlParams) (<-chan string, err
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*30) ctx, cancel := context.WithTimeout(context.Background(), time.Minute*30)
defer cancel() defer cancel()
response, err := c.sendExec(ctx, p) _, response, err := c.sendExec(ctx, ps...)
if err != nil { if err != nil {
return return
} }
+6 -7
View File
@@ -9,11 +9,10 @@ import (
) )
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
p := CurlParams{} resp, code, err := NewCurlx().Send(context.Background(),
p.Url = "http://www.baidu.com" SetUrl("https://www.baidu.com"),
p.Method = "GET" SetMethod(MethodGet),
)
resp, code, err := NewCurlx().Send(context.Background(), &p)
t.Log(resp, code, err) t.Log(resp, code, err)
} }
@@ -37,7 +36,7 @@ func TestForm(t *testing.T) {
}, },
} }
p := &CurlParams{ p := ClientParams{
Url: "http://tech-dev.sealmoo.com/api/material/upload", Url: "http://tech-dev.sealmoo.com/api/material/upload",
Method: "POST", Method: "POST",
Params: s, Params: s,
@@ -46,6 +45,6 @@ func TestForm(t *testing.T) {
}, },
ContentType: ContentTypeForm, ContentType: ContentTypeForm,
} }
resp, code, err := NewCurlx().Send(context.Background(), p) resp, code, err := NewCurlx().Send(context.Background(), SetAll(p))
fmt.Println(resp, code, err) fmt.Println(resp, code, err)
} }
+34
View File
@@ -0,0 +1,34 @@
package curlx
import "time"
type clientOptions struct {
TimeOut time.Duration
InsecureSkipVerify bool
}
func defaultOptions() clientOptions {
return clientOptions{
TimeOut: time.Second * 120, // 默认超时120
}
}
type Option func(*clientOptions)
/**
* 设置超时时间
*/
func SetTimeOut(t time.Duration) Option {
return func(options *clientOptions) {
options.TimeOut = t
}
}
/**
* 不校验HTTPS证书
*/
func SetTLSInsecureSkipVerify() Option {
return func(options *clientOptions) {
options.InsecureSkipVerify = true
}
}
+144
View File
@@ -0,0 +1,144 @@
package curlx
type ClientParams struct {
Url string
Method Method // GET/POST
Params interface{}
Headers map[string]interface{}
Cookies interface{}
ContentType ContentType // FORM,JSON,XML
}
func defaultParams() ClientParams {
return ClientParams{}
}
type Param func(*ClientParams)
func SetAll(cp ClientParams) Param {
return func(param *ClientParams) {
param.Url = cp.Url
param.Method = cp.Method
param.Params = cp.Params
param.Headers = cp.Headers
param.Cookies = cp.Cookies
param.ContentType = cp.ContentType
}
}
/**
* 设置URL
*/
func SetUrl(url string) Param {
return func(param *ClientParams) {
param.Url = url
}
}
/**
* 设置方法
*/
func SetMethod(m Method) Param {
return func(param *ClientParams) {
param.Method = m
}
}
/**
* 设置参数
*/
func SetParams(p interface{}) Param {
return func(param *ClientParams) {
param.Params = p
}
}
/**
* 表单文本参数
*/
func SetParamsFormText(fieldName, fieldValue string) Param {
return func(param *ClientParams) {
fp := param.Params.([]FormParam)
fp = append(fp, FormParam{
FieldName: fieldName,
FieldValue: fieldValue,
FieldType: FieldTypeText,
})
param.Params = fp
}
}
/**
* 表单文件上传
*/
func SetParamsFormFile(fieldName, fileName string, fileBytes []byte) Param {
return func(param *ClientParams) {
fp := param.Params.([]FormParam)
fp = append(fp, FormParam{
FieldName: fieldName,
FieldType: FieldTypeFile,
FileName: fileName,
FileBytes: fileBytes,
})
param.Params = fp
}
}
/**
* 设置请求头
*/
func SetHeaders(h map[string]interface{}) Param {
return func(param *ClientParams) {
param.Headers = h
}
}
/**
* 设置cookies
*/
func SetCookies(c interface{}) Param {
return func(param *ClientParams) {
param.Cookies = c
}
}
/**
* 设置请求方法
*/
func SetContentType(t ContentType) Param {
return func(param *ClientParams) {
param.ContentType = t
}
}
type FieldType string
const (
FieldTypeFile FieldType = "file"
FieldTypeText FieldType = "text"
)
type FormParam struct {
FieldName string `json:"field_name"` // 字段名
FieldValue string `json:"field_value"` // 字段值
FieldType FieldType `json:"field_type"` // 动作(file/text)
FileName string `json:"file_name"` // 文件名
FileBytes []byte `json:"file_bytes"` // 文件内容
}
type ContentType string
const (
ContentTypeForm ContentType = "multipart/form-data"
ContentTypeJson ContentType = "application/json"
ContentTypeXml ContentType = "application/xml"
ContentTypeText ContentType = "text/plain"
ContentTypeUrlEncoded ContentType = "application/x-www-form-urlencoded"
)
type Method string
const (
MethodGet Method = "GET"
MethodPost Method = "POST"
)
+5 -5
View File
@@ -16,7 +16,7 @@ import (
/** /**
* 处理请求类型 * 处理请求类型
*/ */
func (p *CurlParams) parseMethod() error { func (p *ClientParams) parseMethod() error {
if p.Method == "" { if p.Method == "" {
return errors.New("请求类型不能为空") return errors.New("请求类型不能为空")
} }
@@ -26,7 +26,7 @@ func (p *CurlParams) parseMethod() error {
/** /**
* 处理URL * 处理URL
*/ */
func (p *CurlParams) parseUrl() error { func (p *ClientParams) parseUrl() error {
_, err := url.Parse(p.Url) _, err := url.Parse(p.Url)
if err != nil { if err != nil {
return err return err
@@ -37,7 +37,7 @@ func (p *CurlParams) parseUrl() error {
/** /**
* 处理请求头Header * 处理请求头Header
*/ */
func (p *CurlParams) parseHeaders(r *http.Request) { func (p *ClientParams) parseHeaders(r *http.Request) {
if p.Headers != nil { if p.Headers != nil {
if r.Header.Get("User-Agent") == "" { if r.Header.Get("User-Agent") == "" {
r.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0 Send By Golang") r.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0 Send By Golang")
@@ -60,7 +60,7 @@ func (p *CurlParams) parseHeaders(r *http.Request) {
/** /**
* 处理请求参数 * 处理请求参数
*/ */
func (p *CurlParams) parseParams() (str io.Reader, err error) { func (p *ClientParams) parseParams() (str io.Reader, err error) {
err = nil err = nil
// 初始化(如未初始化) // 初始化(如未初始化)
@@ -233,7 +233,7 @@ func (p *CurlParams) parseParams() (str io.Reader, err error) {
/** /**
* 处理Cookie * 处理Cookie
*/ */
func (p *CurlParams) parseCookies(r *http.Request) { func (p *ClientParams) parseCookies(r *http.Request) {
switch p.Cookies.(type) { switch p.Cookies.(type) {
case string: case string:
cookies := p.Cookies.(string) cookies := p.Cookies.(string)
-41
View File
@@ -1,46 +1,5 @@
package curlx package curlx
type FieldType string
const (
FieldTypeFile FieldType = "file"
FieldTypeText FieldType = "text"
)
type FormParam struct {
FieldName string `json:"field_name"` // 字段名
FieldValue string `json:"field_value"` // 字段值
FieldType FieldType `json:"field_type"` // 动作(file/text)
FileName string `json:"file_name"` // 文件名
FileBytes []byte `json:"file_bytes"` // 文件内容
}
type ContentType string
const (
ContentTypeForm ContentType = "multipart/form-data"
ContentTypeJson ContentType = "application/json"
ContentTypeXml ContentType = "application/xml"
ContentTypeText ContentType = "text/plain"
ContentTypeUrlEncoded ContentType = "application/x-www-form-urlencoded"
)
type method string
const (
MethodGet method = "GET"
MethodPost method = "POST"
)
type CurlParams struct {
Url string
Method method // GET/POST
Params interface{}
Headers map[string]interface{}
Cookies interface{}
ContentType ContentType // FORM,JSON,XML
}
type UserAgent string type UserAgent string