This commit is contained in:
gospider
2025-08-19 10:08:50 +08:00
parent e75d44e5dd
commit d941aad1a2
6 changed files with 104 additions and 122 deletions

View File

@@ -287,8 +287,8 @@ func (obj *OrderData) parseForm(ctx context.Context, boundary string) (io.Reader
stop := context.AfterFunc(ctx, func() {
pw.CloseWithError(ctx.Err())
})
defer stop()
pw.CloseWithError(obj.formWriteMain(writer))
stop()
}()
return pr, true, nil
}

134
dial.go
View File

@@ -95,7 +95,7 @@ func newDialer(dialOption *DialOption) dialer {
dialer.dialer.SetMultipathTCP(true)
return &dialer
}
func (obj *Dialer) dialContext(ctx *Response, network string, addr Address, isProxy bool) (net.Conn, error) {
func (obj *Dialer) dialContext(ctx *Response, network string, addr Address) (net.Conn, error) {
var err error
if addr.Port == 0 {
return nil, errors.New("port is nil")
@@ -104,72 +104,49 @@ func (obj *Dialer) dialContext(ctx *Response, network string, addr Address, isPr
addr.IP, err = obj.loadHost(ctx.Context(), addr.Host, ctx.option.DialOption)
}
if ctx.option != nil && ctx.option.Logger != nil {
if isProxy {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_ProxyDNSLookup,
Msg: addr.Host,
})
} else {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_DNSLookup,
Msg: addr.Host,
})
}
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_DNSLookup,
Msg: addr.Host,
})
}
if err != nil {
return nil, err
}
con, err := newDialer(ctx.option.DialOption).DialContext(ctx.Context(), network, addr.String())
if ctx.option != nil && ctx.option.Logger != nil {
if isProxy {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_ProxyTCPConnect,
Msg: addr,
})
} else {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_TCPConnect,
Msg: addr,
})
}
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_TCPConnect,
Msg: addr,
})
}
if err != nil && con != nil {
con.Close()
}
return con, err
}
func (obj *Dialer) DialContext(ctx *Response, network string, addr Address) (net.Conn, error) {
conn, err := obj.dialContext(ctx, network, addr, false)
if err != nil {
err = tools.WrapError(err, "DialContext error")
}
return conn, err
}
func (obj *Dialer) ProxyDialContext(ctx *Response, network string, addr Address) (net.Conn, error) {
conn, err := obj.dialContext(ctx, network, addr, true)
if err != nil {
err = tools.WrapError(err, "ProxyDialContext error")
}
return conn, err
}
func (obj *Dialer) DialProxyContext(ctx *Response, network string, proxyTlsConfig *tls.Config, proxyUrls ...Address) (net.PacketConn, net.Conn, error) {
proxyLen := len(proxyUrls)
if proxyLen < 2 {
if proxyLen < 1 {
return nil, nil, errors.New("proxyUrls is nil")
}
var conn net.Conn
var err error
if proxyLen == 1 {
conn, err = obj.dialContext(ctx, network, proxyUrls[0])
return nil, conn, err
}
var packCon net.PacketConn
for index := range proxyLen - 1 {
oneProxy := proxyUrls[index]
remoteUrl := proxyUrls[index+1]
if index == 0 {
if conn, err = obj.dialProxyContext(ctx, network, oneProxy); err != nil {
_, conn, err = obj.DialProxyContext(ctx, network, nil, oneProxy)
if err != nil {
break
}
}
@@ -188,11 +165,13 @@ func (obj *Dialer) DialProxyContext(ctx *Response, network string, proxyTlsConfi
}
return packCon, conn, err
}
func (obj *Dialer) dialProxyContext(ctx *Response, network string, proxyUrl Address) (net.Conn, error) {
return obj.ProxyDialContext(ctx, network, proxyUrl)
}
func (obj *Dialer) verifySSH(ctx *Response, conn net.Conn, proxyAddress Address, remoteAddress Address) (net.Conn, error) {
func (obj *Dialer) verifySSH(ctx *Response, conn net.Conn, proxyAddress Address, remoteAddress Address) (sshConn net.Conn, err error) {
defer func() {
if err != nil {
conn.Close()
}
}()
if proxyAddress.User == "" || proxyAddress.Password == "" {
return conn, errors.New("ssh proxy user or password is nil")
}
@@ -213,20 +192,20 @@ func (obj *Dialer) verifySSH(ctx *Response, conn net.Conn, proxyAddress Address,
}
func (obj *Dialer) verifyProxyToRemote(ctx *Response, conn net.Conn, proxyTlsConfig *tls.Config, proxyAddress Address, remoteAddress Address, isLast bool, forceHttp1 bool) (net.PacketConn, net.Conn, error) {
var err error
var packCon net.PacketConn
if proxyAddress.Scheme == "https" {
if conn, err = obj.addTls(ctx.Context(), conn, proxyAddress.Host, proxyTlsConfig, forceHttp1); err != nil {
return packCon, conn, err
return nil, conn, err
}
if ctx.option.Logger != nil {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_ProxyTLSHandshake,
Type: LogType_TLSHandshake,
Msg: proxyAddress.String(),
})
}
}
var packCon net.PacketConn
done := make(chan struct{})
go func() {
switch proxyAddress.Scheme {
@@ -242,7 +221,6 @@ func (obj *Dialer) verifyProxyToRemote(ctx *Response, conn net.Conn, proxyTlsCon
}
case "ssh":
conn, err = obj.verifySSH(ctx, conn, proxyAddress, remoteAddress)
// log.Print("verify ssh", remoteAddress.String(), err)
case "socks5":
if isLast && ctx.option.ForceHttp3 {
packCon, err = obj.verifyUDPSocks5(ctx, conn, proxyAddress, remoteAddress)
@@ -262,6 +240,7 @@ func (obj *Dialer) verifyProxyToRemote(ctx *Response, conn net.Conn, proxyTlsCon
}()
select {
case <-ctx.Context().Done():
conn.Close()
return packCon, conn, context.Cause(ctx.Context())
case <-done:
if err != nil {
@@ -393,17 +372,24 @@ func (obj *Dialer) verifySocks5(ctx *Response, conn net.Conn, network string, pr
}
func (obj *Dialer) verifyTCPSocks5(ctx *Response, conn net.Conn, proxyAddr Address, remoteAddr Address) (err error) {
_, err = obj.verifySocks5(ctx, conn, "tcp", proxyAddr, remoteAddr)
if err != nil {
conn.Close()
}
return
}
func (obj *Dialer) verifyUDPSocks5(ctx *Response, conn net.Conn, proxyAddr Address, remoteAddr Address) (wrapConn net.PacketConn, err error) {
remoteAddr.NetWork = "udp"
proxyAddress, err := obj.verifySocks5(ctx, conn, "udp", proxyAddr, remoteAddr)
if err != nil {
conn.Close()
return
}
var listener net.ListenConfig
wrapConn, err = listener.ListenPacket(ctx.Context(), "udp", ":0")
if err != nil {
if wrapConn != nil {
wrapConn.Close()
}
return
}
wrapConn = NewUDPConn(conn, wrapConn, &net.UDPAddr{IP: proxyAddress.IP, Port: proxyAddress.Port}, remoteAddr)
@@ -487,15 +473,11 @@ func (obj *Dialer) addTls(ctx context.Context, conn net.Conn, host string, tlsCo
func (obj *Dialer) addJa3Tls(ctx context.Context, conn net.Conn, host string, spec *ja3.Spec, tlsConfig *utls.Config, forceHttp1 bool) (*utls.UConn, error) {
return specClient.Client(ctx, conn, spec, tlsConfig, gtls.GetServerName(host), forceHttp1)
}
func (obj *Dialer) Socks5TcpProxy(ctx *Response, proxyAddr Address, remoteAddr Address) (conn net.Conn, err error) {
if conn, err = obj.DialContext(ctx, "tcp", proxyAddr); err != nil {
return
func (obj *Dialer) Socks5TcpProxy(ctx *Response, proxyAddr Address, remoteAddr Address) (net.Conn, error) {
_, conn, err := obj.DialProxyContext(ctx, "tcp", nil, proxyAddr)
if err != nil {
return conn, err
}
defer func() {
if err != nil && conn != nil {
conn.Close()
}
}()
didVerify := make(chan struct{})
go func() {
defer close(didVerify)
@@ -503,27 +485,19 @@ func (obj *Dialer) Socks5TcpProxy(ctx *Response, proxyAddr Address, remoteAddr A
}()
select {
case <-ctx.Context().Done():
conn.Close()
return conn, context.Cause(ctx.Context())
case <-didVerify:
return
return conn, err
}
}
func (obj *Dialer) Socks5UdpProxy(ctx *Response, proxyAddress Address, remoteAddress Address) (udpConn net.PacketConn, err error) {
conn, err := obj.ProxyDialContext(ctx, "tcp", proxyAddress)
func (obj *Dialer) Socks5UdpProxy(ctx *Response, proxyAddress Address, remoteAddress Address) (net.PacketConn, error) {
_, conn, err := obj.DialProxyContext(ctx, "tcp", nil, proxyAddress)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
if conn != nil {
conn.Close()
}
if udpConn != nil {
udpConn.Close()
}
}
}()
didVerify := make(chan struct{})
var udpConn net.PacketConn
go func() {
defer close(didVerify)
udpConn, err = obj.verifyUDPSocks5(ctx, conn, proxyAddress, remoteAddress)
@@ -538,12 +512,18 @@ func (obj *Dialer) Socks5UdpProxy(ctx *Response, proxyAddress Address, remoteAdd
}()
select {
case <-ctx.Context().Done():
conn.Close()
return udpConn, context.Cause(ctx.Context())
case <-didVerify:
return
return udpConn, err
}
}
func (obj *Dialer) clientVerifyHttps(ctx context.Context, conn net.Conn, proxyAddress Address, remoteAddress Address) (err error) {
defer func() {
if err != nil {
conn.Close()
}
}()
hdr := make(http.Header)
if proxyAddress.User != "" && proxyAddress.Password != "" {
hdr.Set("Proxy-Authorization", "Basic "+tools.Base64Encode(proxyAddress.User+":"+proxyAddress.Password))

7
go.mod
View File

@@ -8,7 +8,7 @@ require (
github.com/gospider007/bar v0.0.0-20250815030902-4f5b5d6312cf
github.com/gospider007/bs4 v0.0.0-20250815030800-a352d3ad57ee
github.com/gospider007/gson v0.0.0-20250815030832-fa016f03a353
github.com/gospider007/gtls v0.0.0-20250818024401-0d7bcb040679
github.com/gospider007/gtls v0.0.0-20250818100212-f466fa4cc860
github.com/gospider007/http1 v0.0.0-20250817122009-0b953c2c8efa
github.com/gospider007/http2 v0.0.0-20250817122534-76043412544d
github.com/gospider007/http3 v0.0.0-20250817123336-07d66db6dbb3
@@ -28,6 +28,7 @@ require (
)
require (
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/PuerkitoBio/goquery v1.10.3 // indirect
github.com/STARRY-S/zip v0.2.3 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
@@ -61,7 +62,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nwaples/rardecode/v2 v2.1.1 // indirect
github.com/onsi/ginkgo/v2 v2.23.4 // indirect
github.com/onsi/ginkgo/v2 v2.24.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
@@ -76,7 +77,7 @@ require (
github.com/zeebo/blake3 v0.2.4 // indirect
go.mongodb.org/mongo-driver v1.17.4 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/mock v0.5.2 // indirect
go.uber.org/mock v0.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.uber.org/zap/exp v0.3.0 // indirect

14
go.sum
View File

@@ -17,6 +17,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
github.com/STARRY-S/zip v0.2.3 h1:luE4dMvRPDOWQdeDdUxUoZkzUIpTccdKdhHHsQJ1fm4=
@@ -112,8 +114,8 @@ github.com/gospider007/bs4 v0.0.0-20250815030800-a352d3ad57ee h1:XKhfmuJ/lGYMN0n
github.com/gospider007/bs4 v0.0.0-20250815030800-a352d3ad57ee/go.mod h1:AU9FRb74CELvy5vhGAP/4GDw5SgGxxIj7SI5X0AoPe0=
github.com/gospider007/gson v0.0.0-20250815030832-fa016f03a353 h1:jrqXuLs1QzMZcl8mMoBLTaag6JaLY1eh/toCyDWC8GY=
github.com/gospider007/gson v0.0.0-20250815030832-fa016f03a353/go.mod h1:nxA7Mekk0TdS1W+ycauVr8vW25mMXf9rxCGcGHNE28w=
github.com/gospider007/gtls v0.0.0-20250818024401-0d7bcb040679 h1:Rky2kfy1qNbmR88IMUEPjRahXza1Szi1NVGYwy40OI0=
github.com/gospider007/gtls v0.0.0-20250818024401-0d7bcb040679/go.mod h1:Np1+9Lmsm3g1LtDl3C8OOsMXfHRdOwyd7olW8YJMGLo=
github.com/gospider007/gtls v0.0.0-20250818100212-f466fa4cc860 h1:1+GNYHU9fFkIGk67Ssgc9xDdY8X1DbbCNek++XA6B/c=
github.com/gospider007/gtls v0.0.0-20250818100212-f466fa4cc860/go.mod h1:Np1+9Lmsm3g1LtDl3C8OOsMXfHRdOwyd7olW8YJMGLo=
github.com/gospider007/http1 v0.0.0-20250817122009-0b953c2c8efa h1:SJPg55yHMzcrprjvBA2YBMYCmIRauhFtQGL6QVTManM=
github.com/gospider007/http1 v0.0.0-20250817122009-0b953c2c8efa/go.mod h1:2KmewDOljCqfLfbSiIzuohAHvivZwj9pSd25pGEVvfE=
github.com/gospider007/http2 v0.0.0-20250817122534-76043412544d h1:PShVXqSaKS0mOpkvYEyrSDRtUQokcBMDinKvLVs5w4M=
@@ -175,8 +177,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nwaples/rardecode/v2 v2.1.1 h1:OJaYalXdliBUXPmC8CZGQ7oZDxzX1/5mQmgn0/GASew=
github.com/nwaples/rardecode/v2 v2.1.1/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/ginkgo/v2 v2.24.0 h1:obZz8LAnHicNdbBqvG3ytAFx8fgza+i1IDpBVcHT2YE=
github.com/onsi/ginkgo/v2 v2.24.0/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
@@ -256,8 +258,8 @@ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=

View File

@@ -14,15 +14,14 @@ import (
type LogType string
const (
LogType_DNSLookup LogType = "DNSLookup"
LogType_TCPConnect LogType = "TCPConnect"
LogType_TLSHandshake LogType = "TLSHandshake"
LogType_ProxyDNSLookup LogType = "ProxyDNSLookup"
LogType_ProxyTCPConnect LogType = "ProxyTCPConnect"
LogType_ProxyTLSHandshake LogType = "ProxyTLSHandshake"
LogType_DNSLookup LogType = "DNSLookup"
LogType_TCPConnect LogType = "TCPConnect"
LogType_TLSHandshake LogType = "TLSHandshake"
LogType_ProxyConnectRemote LogType = "ProxyConnectRemote"
LogType_ResponseHeader LogType = "ResponseHeader"
LogType_ResponseBody LogType = "ResponseBody"
LogType_ResponseHeader LogType = "ResponseHeader"
LogType_ResponseBody LogType = "ResponseBody"
)
type Log struct {

View File

@@ -100,6 +100,9 @@ func (obj *roundTripper) http3Dial(ctx *Response, remtoeAddress Address, proxyAd
} else {
udpConn, err = net.ListenUDP("udp", nil)
}
if err != nil && udpConn != nil {
udpConn.Close()
}
return
}
func (obj *roundTripper) ghttp3Dial(ctx *Response, remoteAddress Address, proxyAddress ...Address) (conn http1.Conn, err error) {
@@ -195,13 +198,9 @@ func (obj *roundTripper) dial(ctx *Response) (conn http1.Conn, err error) {
arch = proxys[len(proxys)-1].Compression
_, rawNetConn, err = obj.dialer.DialProxyContext(ctx, "tcp", ctx.option.TlsConfig.Clone(), append(proxys, remoteAddress)...)
} else {
var remoteAddress Address
remoteAddress, err = GetAddressWithUrl(ctx.request.URL)
if err != nil {
return nil, err
}
rawNetConn, err = obj.dialer.DialContext(ctx, "tcp", remoteAddress)
_, rawNetConn, err = obj.dialer.DialProxyContext(ctx, "tcp", nil, remoteAddress)
}
if err != nil {
if rawNetConn != nil {
rawNetConn.Close()
@@ -211,30 +210,10 @@ func (obj *roundTripper) dial(ctx *Response) (conn http1.Conn, err error) {
var h2 bool
var rawConn net.Conn
if ctx.request.URL.Scheme == "https" {
if ctx.option.TlsHandshakeTimeout > 0 {
tlsCtx, tlsCnl := context.WithTimeout(ctx.Context(), ctx.option.TlsHandshakeTimeout)
rawConn, h2, err = obj.dialAddTls(tlsCtx, ctx.option, ctx.request, rawNetConn)
tlsCnl()
} else {
rawConn, h2, err = obj.dialAddTls(ctx.Context(), ctx.option, ctx.request, rawNetConn)
}
if ctx.option.Logger != nil {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_TLSHandshake,
Msg: fmt.Sprintf("host:%s, h2:%t", getHost(ctx.request), h2),
})
}
rawConn, h2, err = obj.dialAddTlsWithResponse(ctx, rawNetConn)
} else {
rawConn = rawNetConn
}
if err != nil {
if rawConn != nil {
rawConn.Close()
}
return nil, err
}
if arch != "" {
rawConn, err = NewCompressionConn(rawConn, arch)
}
@@ -258,6 +237,27 @@ func (obj *roundTripper) dialConnecotr(ctx *Response, rawCon net.Conn, h2 bool)
}
return
}
func (obj *roundTripper) dialAddTlsWithResponse(ctx *Response, rawNetConn net.Conn) (tlsConn net.Conn, h2 bool, err error) {
if ctx.option.TlsHandshakeTimeout > 0 {
tlsCtx, tlsCnl := context.WithTimeout(ctx.Context(), ctx.option.TlsHandshakeTimeout)
tlsConn, h2, err = obj.dialAddTls(tlsCtx, ctx.option, ctx.request, rawNetConn)
tlsCnl()
} else {
tlsConn, h2, err = obj.dialAddTls(ctx.Context(), ctx.option, ctx.request, rawNetConn)
}
if ctx.option.Logger != nil {
ctx.option.Logger(Log{
Id: ctx.requestId,
Time: time.Now(),
Type: LogType_TLSHandshake,
Msg: fmt.Sprintf("host:%s, h2:%t", getHost(ctx.request), h2),
})
}
if err != nil && tlsConn != nil {
tlsConn.Close()
}
return tlsConn, h2, err
}
func (obj *roundTripper) dialAddTls(ctx context.Context, option *RequestOption, req *http.Request, netConn net.Conn) (net.Conn, bool, error) {
if option.gospiderSpec != nil && option.gospiderSpec.TLSSpec != nil {
if tlsConn, err := obj.dialer.addJa3Tls(ctx, netConn, getHost(req), option.gospiderSpec.TLSSpec, option.UtlsConfig.Clone(), option.ForceHttp1); err != nil {