优化插件的参数请求
This commit is contained in:
@@ -19,9 +19,20 @@ import (
|
||||
* Date: 2023年7月12日11:35:01
|
||||
*/
|
||||
|
||||
var (
|
||||
// 默认的transport
|
||||
transport http.Transport = http.Transport{
|
||||
// type DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
|
||||
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) {
|
||||
// // 这里指定域名访问的IP
|
||||
// // if addr == "api.hk.blueoceanpay.com:443" {
|
||||
@@ -48,22 +59,16 @@ var (
|
||||
MaxConnsPerHost: 0, // 每个host的最大连接数量
|
||||
IdleConnTimeout: time.Second * 2, // 空闲连接超时关闭的时间
|
||||
}
|
||||
// client = &http.Client{}
|
||||
|
||||
)
|
||||
|
||||
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,
|
||||
if defaultOpts.InsecureSkipVerify {
|
||||
transport.TLSClientConfig.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
return &Curlx{
|
||||
opts: defaultOpts,
|
||||
transport: transport,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,8 +77,8 @@ func NewCurlx() *Curlx {
|
||||
*/
|
||||
func (c *Curlx) WithProxySocks5(address string) error {
|
||||
baseDialer := &net.Dialer{
|
||||
Timeout: 180 * time.Second,
|
||||
KeepAlive: 180 * time.Second,
|
||||
// Timeout: 180 * time.Second,
|
||||
// KeepAlive: 180 * time.Second,
|
||||
}
|
||||
dialSocksProxy, err := proxy.SOCKS5("tcp", address, nil, baseDialer)
|
||||
if err != nil {
|
||||
@@ -101,30 +106,20 @@ func (c *Curlx) WithProxyHttp(proxyAddr string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/**
|
||||
* 不校验HTTPS证书
|
||||
*/
|
||||
func (c *Curlx) WithInsecureSkipVerify() {
|
||||
c.transport.TLSClientConfig.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置超时时间,单位秒
|
||||
*/
|
||||
func (c *Curlx) WithTimeout(timeout int) {
|
||||
c.timeOutSecond = timeout
|
||||
}
|
||||
|
||||
// 指定访问的IP
|
||||
// func(c *curlx) WithIp(ip string) {
|
||||
// c.transport.Dial
|
||||
// }
|
||||
// 127.0.0.1:8080
|
||||
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) {
|
||||
response, err := c.sendExec(ctx, p)
|
||||
func (c *Curlx) Send(ctx context.Context, p ...Param) (res string, httpcode int, err error) {
|
||||
_, response, err := c.sendExec(ctx, p...)
|
||||
if err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
@@ -163,27 +158,32 @@ func (c *Curlx) Send(ctx context.Context, p *CurlParams) (res string, httpcode i
|
||||
* 执行发送
|
||||
* 注意:外部使用需要加这一句 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{
|
||||
Timeout: time.Second * time.Duration(c.timeOutSecond), // 整个请求的超时时间 设置该条连接的超时
|
||||
Transport: c.transport, //
|
||||
Timeout: c.opts.TimeOut, // 整个请求的超时时间 设置该条连接的超时
|
||||
Transport: c.transport, //
|
||||
}
|
||||
|
||||
p := defaultParams()
|
||||
for _, param := range ps {
|
||||
param(&p)
|
||||
}
|
||||
|
||||
err = p.parseMethod()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// 判断和处理url
|
||||
err = p.parseUrl()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// 处理参数
|
||||
reqParams, err := p.parseParams()
|
||||
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,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// 这里指定要访问的HOST,到时候服务器获取主机是获取到这个
|
||||
@@ -211,16 +211,16 @@ func (c *Curlx) sendExec(ctx context.Context, p *CurlParams) (resp *http.Respons
|
||||
// 发起请求
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
// 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)
|
||||
|
||||
@@ -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)
|
||||
defer cancel()
|
||||
|
||||
response, err := c.sendExec(ctx, p)
|
||||
_, response, err := c.sendExec(ctx, ps...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+6
-7
@@ -9,11 +9,10 @@ import (
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
p := CurlParams{}
|
||||
p.Url = "http://www.baidu.com"
|
||||
p.Method = "GET"
|
||||
|
||||
resp, code, err := NewCurlx().Send(context.Background(), &p)
|
||||
resp, code, err := NewCurlx().Send(context.Background(),
|
||||
SetUrl("https://www.baidu.com"),
|
||||
SetMethod(MethodGet),
|
||||
)
|
||||
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",
|
||||
Method: "POST",
|
||||
Params: s,
|
||||
@@ -46,6 +45,6 @@ func TestForm(t *testing.T) {
|
||||
},
|
||||
ContentType: ContentTypeForm,
|
||||
}
|
||||
resp, code, err := NewCurlx().Send(context.Background(), p)
|
||||
resp, code, err := NewCurlx().Send(context.Background(), SetAll(p))
|
||||
fmt.Println(resp, code, err)
|
||||
}
|
||||
|
||||
+34
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -16,7 +16,7 @@ import (
|
||||
/**
|
||||
* 处理请求类型
|
||||
*/
|
||||
func (p *CurlParams) parseMethod() error {
|
||||
func (p *ClientParams) parseMethod() error {
|
||||
if p.Method == "" {
|
||||
return errors.New("请求类型不能为空")
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func (p *CurlParams) parseMethod() error {
|
||||
/**
|
||||
* 处理URL
|
||||
*/
|
||||
func (p *CurlParams) parseUrl() error {
|
||||
func (p *ClientParams) parseUrl() error {
|
||||
_, err := url.Parse(p.Url)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -37,7 +37,7 @@ func (p *CurlParams) parseUrl() error {
|
||||
/**
|
||||
* 处理请求头Header
|
||||
*/
|
||||
func (p *CurlParams) parseHeaders(r *http.Request) {
|
||||
func (p *ClientParams) parseHeaders(r *http.Request) {
|
||||
if p.Headers != nil {
|
||||
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")
|
||||
@@ -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
|
||||
|
||||
// 初始化(如未初始化)
|
||||
@@ -233,7 +233,7 @@ func (p *CurlParams) parseParams() (str io.Reader, err error) {
|
||||
/**
|
||||
* 处理Cookie
|
||||
*/
|
||||
func (p *CurlParams) parseCookies(r *http.Request) {
|
||||
func (p *ClientParams) parseCookies(r *http.Request) {
|
||||
switch p.Cookies.(type) {
|
||||
case string:
|
||||
cookies := p.Cookies.(string)
|
||||
|
||||
@@ -1,46 +1,5 @@
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user