再次修改options的使用

This commit is contained in:
Yun
2026-03-01 23:06:20 +08:00
parent d6e1229961
commit 3e96b1ada6
2 changed files with 81 additions and 47 deletions
+19 -28
View File
@@ -3,7 +3,7 @@ package curlx
import ( import (
"bufio" "bufio"
"context" "context"
"fmt" "errors"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
@@ -20,7 +20,7 @@ import (
// type DialContext func(ctx context.Context, network, addr string) (net.Conn, error) // type DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
type Curlx struct { type Curlx struct {
opts clientOptions opts ClientOptions
transport *http.Transport transport *http.Transport
} }
@@ -31,31 +31,13 @@ func NewCurlx(opts ...Option) *Curlx {
} }
transport := &http.Transport{ transport := &http.Transport{
// Dial: func(netw, addr string) (net.Conn, error) { DisableKeepAlives: false, // 启用keep-alive连接复用
// // 这里指定域名访问的IP MaxIdleConns: defaultOpts.MaxIdleConns,
// // if addr == "api.hk.blueoceanpay.com:443" { MaxIdleConnsPerHost: defaultOpts.MaxIdleConnsPerHost,
// // addr = "47.56.200.21:443" MaxConnsPerHost: defaultOpts.MaxConnsPerHost,
// // } IdleConnTimeout: defaultOpts.IdleConnTimeout,
// conn, err := net.DialTimeout(netw, addr, time.Second*time.Duration(timeOut)) // 设置建立连接超时 ExpectContinueTimeout: 1 * time.Second,
// if err != nil { TLSHandshakeTimeout: 10 * time.Second,
// return nil, err
// }
// // conn.RemoteAddr().String()
// conn.SetDeadline(time.Now().Add(time.Second * time.Duration(timeOut))) // 设置发送接收数据超时
// return conn, nil
// },
// DialContext: (&net.Dialer{
// Timeout: 3 * time.Second, // 建立TCP链接的超时时间
// KeepAlive: 30 * time.Second, // TCP keepalive超时时间
// }).DialContext,
// TLSHandshakeTimeout: time.Second * 10, // TLS握手超时
// ResponseHeaderTimeout: time.Second * 10, // 接收响应头的超时时间
// ExpectContinueTimeout: time.Second * 10, // 发送请求头超时时间 100-continue状态码超时时间
DisableKeepAlives: false, // 短连接(默认是使用长连接,连接过多时会造成服务器拒绝服务问题)
MaxIdleConns: 0, // 所有host的连接池最大连接数量,默认无穷大
MaxIdleConnsPerHost: 5, // 每个host的连接池最大空闲连接收,默认2
MaxConnsPerHost: 0, // 每个host的最大连接数量
IdleConnTimeout: time.Second * 2, // 空闲连接超时关闭的时间
} }
if defaultOpts.InsecureSkipVerify { if defaultOpts.InsecureSkipVerify {
@@ -84,7 +66,7 @@ func (c *Curlx) WithProxySocks5(address string) error {
} }
dialSocksProxy, err := proxy.SOCKS5("tcp", address, nil, baseDialer) dialSocksProxy, err := proxy.SOCKS5("tcp", address, nil, baseDialer)
if err != nil { if err != nil {
fmt.Println("proxy.SOCKS5 err", err) c.opts.Logger.Errorf(context.Background(), "proxy.SOCKS5 err: %v", err)
return err return err
} }
dialContext := (baseDialer).DialContext dialContext := (baseDialer).DialContext
@@ -102,6 +84,7 @@ func (c *Curlx) WithProxySocks5(address string) error {
func (c *Curlx) WithProxyHttp(proxyAddr string) error { func (c *Curlx) WithProxyHttp(proxyAddr string) error {
proxy, err := url.Parse(proxyAddr) proxy, err := url.Parse(proxyAddr)
if err != nil { if err != nil {
c.opts.Logger.Errorf(context.Background(), "proxy.HTTP/HTTPS err: %v", err)
return err return err
} }
c.transport.Proxy = http.ProxyURL(proxy) c.transport.Proxy = http.ProxyURL(proxy)
@@ -182,6 +165,14 @@ func (c *Curlx) exec(ctx context.Context, ps ...Param) Response {
Transport: c.transport, // Transport: c.transport, //
} }
// 在http.Client中添加CheckRedirect函数 实现重定向控制
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if len(via) >= 10 { // 限制重定向次数
return errors.New("stopped after 10 redirects")
}
return nil
}
p := defaultParams() p := defaultParams()
for _, param := range ps { for _, param := range ps {
param(&p) param(&p)
+56 -13
View File
@@ -6,37 +6,55 @@ import (
"time" "time"
) )
type clientOptions struct { type ClientOptions struct {
TimeOut time.Duration TimeOut time.Duration
InsecureSkipVerify bool InsecureSkipVerify bool
Logger OptionLogger Logger OptionLogger
LoggerLength int // 日志输出长度 LoggerLength int // 日志输出长度
CertFingerprint string // 证书指纹验证
// 连接池配置
MaxIdleConns int
MaxIdleConnsPerHost int
MaxConnsPerHost int
IdleConnTimeout time.Duration
} }
func defaultOptions() clientOptions { func defaultOptions() ClientOptions {
return clientOptions{ return ClientOptions{
TimeOut: time.Second * 120, // 默认超时120 TimeOut: time.Second * 120, // 默认超时120
Logger: defaultLogger{}, Logger: defaultLogger{},
LoggerLength: 100, LoggerLength: 100,
MaxIdleConns: 100, // 默认连接池大小
MaxIdleConnsPerHost: 10, // 每主机默认空闲连接数
MaxConnsPerHost: 50, // 每主机最大连接数
IdleConnTimeout: 90 * time.Second, // 空闲连接超时
} }
} }
type Option func(*clientOptions) type Option func(*ClientOptions)
/** /**
* 设置超时时间 * 设置超时时间
*/ */
func SetOptionTimeOut(t time.Duration) Option { func WithOptionTimeOut(t time.Duration) Option {
return func(options *clientOptions) { return func(options *ClientOptions) {
options.TimeOut = t options.TimeOut = t
} }
} }
// 添加证书指纹验证选项
func WithOptionTLSPin(certFingerprint string) Option {
return func(options *ClientOptions) {
options.CertFingerprint = certFingerprint
}
}
/** /**
* 不校验HTTPS证书 * 不校验HTTPS证书
*/ */
func SetOptionTLSInsecureSkipVerify() Option { func WithOptionTLSInsecureSkipVerify() Option {
return func(options *clientOptions) { return func(options *ClientOptions) {
options.InsecureSkipVerify = true options.InsecureSkipVerify = true
} }
} }
@@ -44,8 +62,8 @@ func SetOptionTLSInsecureSkipVerify() Option {
/** /**
* 设置日志输出 * 设置日志输出
*/ */
func SetOptionLog(log OptionLogger) Option { func WithOptionLog(log OptionLogger) Option {
return func(options *clientOptions) { return func(options *ClientOptions) {
options.Logger = log options.Logger = log
} }
} }
@@ -53,12 +71,37 @@ func SetOptionLog(log OptionLogger) Option {
/** /**
* 设置日志输出长度 * 设置日志输出长度
*/ */
func WithLoggerLength(length int) Option { func WithOptionLoggerLength(length int) Option {
return func(options *clientOptions) { return func(options *ClientOptions) {
options.LoggerLength = length options.LoggerLength = length
} }
} }
// 连接池配置选项
func WithMaxIdleConns(maxIdleConns int) Option {
return func(options *ClientOptions) {
options.MaxIdleConns = maxIdleConns
}
}
func WithMaxIdleConnsPerHost(maxIdleConnsPerHost int) Option {
return func(options *ClientOptions) {
options.MaxIdleConnsPerHost = maxIdleConnsPerHost
}
}
func WithMaxConnsPerHost(maxConnsPerHost int) Option {
return func(options *ClientOptions) {
options.MaxConnsPerHost = maxConnsPerHost
}
}
func WithIdleConnTimeout(timeout time.Duration) Option {
return func(options *ClientOptions) {
options.IdleConnTimeout = timeout
}
}
type OptionLogger interface { type OptionLogger interface {
Infof(ctx context.Context, format string, args ...any) Infof(ctx context.Context, format string, args ...any)
Errorf(ctx context.Context, format string, args ...any) Errorf(ctx context.Context, format string, args ...any)