From 955b0c967c3bcd490e7e80e6676f49dd2f872034 Mon Sep 17 00:00:00 2001 From: gospider <2216403312@qq.com> Date: Tue, 7 Jan 2025 18:04:20 +0800 Subject: [PATCH] sync --- dial.go | 18 +- go.mod | 20 +- go.sum | 55 ++-- option.go | 327 +++++++++++------------ requests.go | 7 +- roundTripper.go | 19 +- test/cookies/setCookies_test.go | 13 +- test/dns_test.go | 10 +- test/fingerprint/http2_test.go | 4 +- test/fingerprint/ja3_test.go | 15 +- test/fingerprint/ja4_test.go | 11 +- test/fingerprint/quic_test.go | 28 +- test/logger/logger_test.go | 9 +- test/middleware/errCallBack_test.go | 23 +- test/middleware/optionltCallBack_test.go | 9 +- test/middleware/redirectCallBack_test.go | 13 +- test/middleware/requestCallback_test.go | 15 +- test/middleware/resultCallBack_test.go | 15 +- test/middleware/try_test.go | 17 +- test/protocol/http1_test.go | 17 +- test/protocol/http3_test.go | 5 +- test/proxy/chain_proxy_test.go | 17 +- test/proxy/disProxy_test.go | 5 +- test/proxy/http3_proxy_test.go | 30 ++- test/proxy/proxy_test.go | 2 +- test/response/request/localAddr_test.go | 8 +- test/response/request/stream_test.go | 6 +- test/session_test.go | 2 +- 28 files changed, 410 insertions(+), 310 deletions(-) diff --git a/dial.go b/dial.go index 0a0a067..ca40f7b 100644 --- a/dial.go +++ b/dial.go @@ -394,25 +394,25 @@ func (obj *Dialer) lookupIPAddr(ips []net.IPAddr, addrType gtls.AddrType) (net.I } return nil, errors.New("dns parse host error") } -func (obj *Dialer) addTls(ctx context.Context, conn net.Conn, host string, forceHttp1 bool, tlsConfig *tls.Config) (*tls.Conn, error) { +func (obj *Dialer) addTls(ctx context.Context, conn net.Conn, host string, h2 bool, tlsConfig *tls.Config) (*tls.Conn, error) { var tlsConn *tls.Conn tlsConfig.ServerName = gtls.GetServerName(host) - if forceHttp1 { - tlsConfig.NextProtos = []string{"http/1.1"} - } else { + if h2 { tlsConfig.NextProtos = []string{"h2", "http/1.1"} + } else { + tlsConfig.NextProtos = []string{"http/1.1"} } tlsConn = tls.Client(conn, tlsConfig) return tlsConn, tlsConn.HandshakeContext(ctx) } -func (obj *Dialer) addJa3Tls(ctx context.Context, conn net.Conn, host string, forceHttp1 bool, ja3Spec ja3.Ja3Spec, tlsConfig *utls.Config) (*utls.UConn, error) { +func (obj *Dialer) addJa3Tls(ctx context.Context, conn net.Conn, host string, h2 bool, spec ja3.Spec, tlsConfig *utls.Config) (*utls.UConn, error) { tlsConfig.ServerName = gtls.GetServerName(host) - if forceHttp1 { - tlsConfig.NextProtos = []string{"http/1.1"} - } else { + if h2 { tlsConfig.NextProtos = []string{"h2", "http/1.1"} + } else { + tlsConfig.NextProtos = []string{"http/1.1"} } - return ja3.NewClient(ctx, conn, ja3Spec, forceHttp1, tlsConfig) + return ja3.NewClient(ctx, conn, spec, h2, tlsConfig) } func (obj *Dialer) Socks5TcpProxy(ctx context.Context, ctxData *RequestOption, proxyAddr Address, remoteAddr Address) (conn net.Conn, err error) { if conn, err = obj.DialContext(ctx, ctxData, "tcp", proxyAddr); err != nil { diff --git a/go.mod b/go.mod index 25dead6..3a8e09f 100644 --- a/go.mod +++ b/go.mod @@ -9,16 +9,16 @@ require ( github.com/gospider007/gtls v0.0.0-20250102091721-c5d429cea809 github.com/gospider007/http2 v0.0.0-20241222151842-034aa1d46e9d github.com/gospider007/http3 v0.0.0-20250102093206-281d03368c89 - github.com/gospider007/ja3 v0.0.0-20241216123149-83352be79439 - github.com/gospider007/proxy v0.0.0-20241224001512-8d6d724b8ca3 + github.com/gospider007/ja3 v0.0.0-20250107091445-e294e50de314 + github.com/gospider007/proxy v0.0.0-20250103020907-1a1fa54066e4 github.com/gospider007/re v0.0.0-20241216142712-efbef8d55ea2 - github.com/gospider007/tools v0.0.0-20241216141313-4a832f55a843 - github.com/gospider007/websocket v0.0.0-20241216130619-89829336d9a6 + github.com/gospider007/tools v0.0.0-20250107090942-5b406ab8a72b + github.com/gospider007/websocket v0.0.0-20250107091829-c78035a103b2 github.com/quic-go/quic-go v0.48.2 github.com/refraction-networking/uquic v0.0.6 github.com/refraction-networking/utls v1.6.7 - golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 - golang.org/x/net v0.33.0 + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 + golang.org/x/net v0.34.0 ) require ( @@ -50,7 +50,7 @@ require ( github.com/klauspost/pgzip v1.2.6 // indirect github.com/libdns/libdns v0.2.2 // indirect github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/mholt/archives v0.0.0-20241226194006-fc8400ac3529 // indirect + github.com/mholt/archives v0.1.0 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -72,11 +72,11 @@ require ( go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.32.0 // indirect golang.org/x/image v0.23.0 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.28.0 // indirect + golang.org/x/tools v0.29.0 // indirect ) diff --git a/go.sum b/go.sum index 471d5af..9f41ae4 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,9 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= @@ -93,8 +94,8 @@ github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAx github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gospider007/bar v0.0.0-20241205091858-06f3c7e16dd9 h1:mKDRxvZNftY8msmyonqGLlTAbCUYTJNYbX5Ha0REwzs= github.com/gospider007/bar v0.0.0-20241205091858-06f3c7e16dd9/go.mod h1:dZ50Fil3qVmYCGGR9hne3RwgZRfZj+NZQE7NaKBNdPI= github.com/gospider007/blog v0.0.0-20241205091827-6bcaf48620d4 h1:MA0vcRGiy5JPlQYPU9wg7reG4dZkW3v5Q/DVtAUJ6yQ= @@ -109,20 +110,20 @@ github.com/gospider007/http2 v0.0.0-20241222151842-034aa1d46e9d h1:HJv2HOsvZ+7yf github.com/gospider007/http2 v0.0.0-20241222151842-034aa1d46e9d/go.mod h1:b8VbmpEUTyGR8B8h4MGY2E/5klXqs/WziEgTZx5kU3I= github.com/gospider007/http3 v0.0.0-20250102093206-281d03368c89 h1:385FtT3O5xBn8jd5a817beXoMUuvpzAbFDIQkcq/p+w= github.com/gospider007/http3 v0.0.0-20250102093206-281d03368c89/go.mod h1:SxK+7jYxg+eqFL5I5jQsKpagfR1u1YySI0LTCcagCbo= -github.com/gospider007/ja3 v0.0.0-20241216123149-83352be79439 h1:zDuskJWFKk7JMs7XkX22XSrcbEDLe0rHs1baHSYCH3c= -github.com/gospider007/ja3 v0.0.0-20241216123149-83352be79439/go.mod h1:AZIKhClKQolSI8o6ixFKIVGOC4lWOdsrF4fshR5axO4= +github.com/gospider007/ja3 v0.0.0-20250107091445-e294e50de314 h1:HAdIVngGI5Hj7tSF5nV0YCze+G24ck+9qGf5H/VT4hw= +github.com/gospider007/ja3 v0.0.0-20250107091445-e294e50de314/go.mod h1:LyhufzO6wrBlxeilbUJElfEdDNdD+1v9fB5p30pDAjE= github.com/gospider007/kinds v0.0.0-20240929092451-8f867acde255 h1:X+AM/mgmh/EfyQUjKZp1VFc9TSlrhkwS0eSYeo5fMs4= github.com/gospider007/kinds v0.0.0-20240929092451-8f867acde255/go.mod h1:yZx7Zfp1I4P6CO3TcDyDY5SuXQYr0bZjzT9zG0XrJAI= github.com/gospider007/net v0.0.0-20241216130419-175071962ced h1:vQfZkebsHLjxDk9Wg3neaIsgtyARNmkgrHsh+WroAVY= github.com/gospider007/net v0.0.0-20241216130419-175071962ced/go.mod h1:GrNK3zEmo7N9nuAcOOu4GFw+kvfkYaOMiRSOm38CH7o= -github.com/gospider007/proxy v0.0.0-20241224001512-8d6d724b8ca3 h1:lc25EnLnhcXk0hmBvmHYh+pOAJoWvdTFVAVG/JWDSiw= -github.com/gospider007/proxy v0.0.0-20241224001512-8d6d724b8ca3/go.mod h1:Zwwc4Sxsy2MIh9V3Bvpj9JXnqJKkLz6TRyJRKIUgqDg= +github.com/gospider007/proxy v0.0.0-20250103020907-1a1fa54066e4 h1:wawLXebVhD2694M7fsw1B70Ocnm5TOuTr9una1mJkIk= +github.com/gospider007/proxy v0.0.0-20250103020907-1a1fa54066e4/go.mod h1:xn8FKZw+YH6rd+aOZiE3PRPKFzW+bdCMKzIcG8L1C78= github.com/gospider007/re v0.0.0-20241216142712-efbef8d55ea2 h1:ixXFS1DqP0NnHna+b0JKaPqMRYRmahzUADZn7PawQq0= github.com/gospider007/re v0.0.0-20241216142712-efbef8d55ea2/go.mod h1:kr9bUaC42FS019Ak23fSctbTRB2JpfPPg/pSVjQmsws= -github.com/gospider007/tools v0.0.0-20241216141313-4a832f55a843 h1:Q5judZjpY0p9Qui/ovk2vpvunc1wGkk0wgc8ApbTi3U= -github.com/gospider007/tools v0.0.0-20241216141313-4a832f55a843/go.mod h1:ADvKi8S7EkQleFhauAIzW5xnYVU9sKDSLpZ8mSo3yE4= -github.com/gospider007/websocket v0.0.0-20241216130619-89829336d9a6 h1:GlEpnVq3W5SbDUGydFnQUavyZeNEXGWz08XsMRokNjs= -github.com/gospider007/websocket v0.0.0-20241216130619-89829336d9a6/go.mod h1:7Q66Huzk5NiXzJXSlUG41uWSSjZMDGXljjWoSVDz3kc= +github.com/gospider007/tools v0.0.0-20250107090942-5b406ab8a72b h1:iiAxiufROgDsuQInI6dAx1CG3m7nMMj3C0SAE84oY7g= +github.com/gospider007/tools v0.0.0-20250107090942-5b406ab8a72b/go.mod h1:mTtocamaDuVtgdEXu72OGw6uOhDIOCr98zcvZyBLiro= +github.com/gospider007/websocket v0.0.0-20250107091829-c78035a103b2 h1:hp8IZHhmq4tAkJRFZ3QXRoRwwNyvAeYyqecV/JvFPYc= +github.com/gospider007/websocket v0.0.0-20250107091829-c78035a103b2/go.mod h1:0DHN5ImV48fYE0NkMKynEQLTo+CxMUMCqvIMUE8qUQI= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -153,8 +154,8 @@ github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= -github.com/mholt/archives v0.0.0-20241226194006-fc8400ac3529 h1:XsFbmbdHgEXRCASoX0wlUi1Es+yTDhsmiUo2UVukmLs= -github.com/mholt/archives v0.0.0-20241226194006-fc8400ac3529/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I= +github.com/mholt/archives v0.1.0 h1:FacgJyrjiuyomTuNA92X5GyRBRZjE43Y/lrzKIlF35Q= +github.com/mholt/archives v0.1.0/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -170,8 +171,9 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= @@ -193,8 +195,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -245,8 +247,9 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -255,8 +258,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= -golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= @@ -305,8 +308,9 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -346,8 +350,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -372,8 +377,8 @@ golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -402,8 +407,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/option.go b/option.go index 2ae578b..f08527f 100644 --- a/option.go +++ b/option.go @@ -9,6 +9,7 @@ import ( "time" "github.com/gospider007/ja3" + "github.com/gospider007/tools" "github.com/gospider007/websocket" utls "github.com/refraction-networking/utls" ) @@ -44,12 +45,12 @@ type Log struct { // Connection Management Options type ClientOption struct { - RequestOption Logger func(Log) //debuggable H3 bool //开启http3 OrderHeaders []string //order headers - Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create - H2Ja3Spec ja3.H2Ja3Spec //h2 fingerprint + Ja3Spec ja3.Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create + H2Ja3Spec ja3.H2Spec //h2 fingerprint + UJa3Spec ja3.USpec //h3 fingerprint Proxy string //proxy,support https,http,socks5 Proxys []string //proxy list,support https,http,socks5 ForceHttp1 bool //force use http1 send requests @@ -57,7 +58,6 @@ type ClientOption struct { DisCookie bool //disable cookies DisDecode bool //disable auto decode DisUnZip bool //disable auto zip decode - DisAlive bool //disable keepalive Bar bool ////enable bar display OptionCallBack func(ctx context.Context, option *RequestOption) error //option callback,if error is returnd, break request ResultCallBack func(ctx context.Context, option *RequestOption, response *Response) error //result callback,if error is returnd,next errCallback @@ -70,53 +70,17 @@ type ClientOption struct { ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:300 TlsHandshakeTimeout time.Duration //tls timeout,default:15 UserAgent string //headers User-Agent value - //other option - GetProxy func(ctx context.Context, url *url.URL) (string, error) //proxy callback:support https,http,socks5 proxy - GetProxys func(ctx context.Context, url *url.URL) ([]string, error) //proxys callback:support https,http,socks5 proxy - DialOption DialOption - - Jar Jar //custom cookies - TlsConfig *tls.Config - UtlsConfig *utls.Config + GetProxy func(ctx context.Context, url *url.URL) (string, error) //proxy callback:support https,http,socks5 proxy + GetProxys func(ctx context.Context, url *url.URL) ([]string, error) //proxys callback:support https,http,socks5 proxy + DialOption DialOption + Jar Jar //custom cookies + TlsConfig *tls.Config + UtlsConfig *utls.Config } // Options for sending requests type RequestOption struct { - Logger func(Log) //debuggable - H3 bool //开启http3 - OrderHeaders []string //order headers - Ja3Spec ja3.Ja3Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create - H2Ja3Spec ja3.H2Ja3Spec //custom h2 fingerprint - Proxy string //proxy,support http,https,socks5,example:http://127.0.0.1:7005 - Proxys []string //proxy list,support http,https,socks5,example:http://127.0.0.1:7005 - ForceHttp1 bool //force use http1 send requests - Ja3 bool //enable ja3 fingerprint - DisCookie bool //disable cookies,not use cookies - DisDecode bool //disable auto decode - DisUnZip bool //disable auto zip decode - Bar bool //enable bar display - OptionCallBack func(ctx context.Context, option *RequestOption) error //option callback,if error is returnd, break request - ResultCallBack func(ctx context.Context, option *RequestOption, response *Response) error //result callback,if error is returnd,next errCallback - ErrCallBack func(ctx context.Context, option *RequestOption, response *Response, err error) error //error callback,if error is returnd,break request - RequestCallBack func(ctx context.Context, request *http.Request, response *http.Response) error //request and response callback,if error is returnd,reponse is error - - MaxRetries int //try num - MaxRedirect int //redirect num ,<0 no redirect,==0 no limit - Headers any //request headers:json,map,header - Timeout time.Duration //request timeout - ResponseHeaderTimeout time.Duration //ResponseHeaderTimeout ,default:300 - TlsHandshakeTimeout time.Duration - UserAgent string //headers User-Agent value - - GetProxy func(ctx context.Context, url *url.URL) (string, error) //proxy callback:support https,http,socks5 proxy - GetProxys func(ctx context.Context, url *url.URL) ([]string, error) //proxys callback:support https,http,socks5 proxy - DialOption DialOption - //network card ip - - Jar Jar //custom cookies - TlsConfig *tls.Config - UtlsConfig *utls.Config - + ClientOption // other option Method string //method Url *url.URL @@ -251,122 +215,17 @@ func (obj *RequestOption) initParams() (*url.URL, error) { } return baseUrl, nil } -func (obj *Client) newRequestOption(option RequestOption) RequestOption { - // start - if !option.Ja3Spec.IsSet() { - option.Ja3Spec = obj.option.Ja3Spec - } - if !option.H2Ja3Spec.IsSet() { - option.H2Ja3Spec = obj.option.H2Ja3Spec - } - if option.Proxy == "" { - option.Proxy = obj.option.Proxy - } - if len(option.Proxys) == 0 { - option.Proxys = obj.option.Proxys - } - if !option.ForceHttp1 { - option.ForceHttp1 = obj.option.ForceHttp1 - } - if !option.Ja3 { - option.Ja3 = obj.option.Ja3 - } - if !option.DisCookie { - option.DisCookie = obj.option.DisCookie - } - if !option.DisDecode { - option.DisDecode = obj.option.DisDecode - } - if !option.DisUnZip { - option.DisUnZip = obj.option.DisUnZip - } - if !option.Bar { - option.Bar = obj.option.Bar - } - if !option.H3 { - option.H3 = obj.option.H3 - } - if option.Logger == nil { - option.Logger = obj.option.Logger - } - if option.Headers == nil { - option.Headers = obj.option.Headers - } - if option.Timeout == 0 { - option.Timeout = obj.option.Timeout - } - if option.ResponseHeaderTimeout == 0 { - option.ResponseHeaderTimeout = obj.option.ResponseHeaderTimeout - } - if option.TlsHandshakeTimeout == 0 { - option.TlsHandshakeTimeout = obj.option.TlsHandshakeTimeout - } - if option.TlsConfig == nil { - option.TlsConfig = obj.option.TlsConfig - } - if option.UtlsConfig == nil { - option.UtlsConfig = obj.option.UtlsConfig - } - if option.OrderHeaders == nil { - option.OrderHeaders = obj.option.OrderHeaders - } - if option.OptionCallBack == nil { - option.OptionCallBack = obj.option.OptionCallBack - } - if option.ResultCallBack == nil { - option.ResultCallBack = obj.option.ResultCallBack - } - if option.ErrCallBack == nil { - option.ErrCallBack = obj.option.ErrCallBack - } - if option.RequestCallBack == nil { - option.RequestCallBack = obj.option.RequestCallBack - } - if option.MaxRetries == 0 { - option.MaxRetries = obj.option.MaxRetries - } - if option.MaxRedirect == 0 { - option.MaxRedirect = obj.option.MaxRedirect - } - if option.Headers == nil { - option.Headers = obj.option.Headers - } - if option.Timeout == 0 { - option.Timeout = obj.option.Timeout - } - if option.ResponseHeaderTimeout == 0 { - option.ResponseHeaderTimeout = obj.option.ResponseHeaderTimeout - } - if option.TlsHandshakeTimeout == 0 { - option.TlsHandshakeTimeout = obj.option.TlsHandshakeTimeout - } - if option.DialOption.DialTimeout == 0 { - option.DialOption.DialTimeout = obj.option.DialOption.DialTimeout - } - if option.DialOption.KeepAlive == 0 { - option.DialOption.KeepAlive = obj.option.DialOption.KeepAlive - } - if option.DialOption.LocalAddr == nil { - option.DialOption.LocalAddr = obj.option.DialOption.LocalAddr - } - if option.DialOption.AddrType == 0 { - option.DialOption.AddrType = obj.option.DialOption.AddrType - } - if option.DialOption.Dns == nil { - option.DialOption.Dns = obj.option.DialOption.Dns - } - if option.DialOption.GetAddrType == nil { - option.DialOption.GetAddrType = obj.option.DialOption.GetAddrType - } - if option.Jar == nil { - option.Jar = obj.option.Jar - } +func (obj *Client) newRequestOption(option RequestOption) (RequestOption, error) { + err := tools.Merge(&option, obj.option) //end if option.MaxRetries < 0 { option.MaxRetries = 0 } if !option.Ja3Spec.IsSet() && option.Ja3 { - option.Ja3Spec = ja3.DefaultJa3Spec() + option.Ja3Spec = ja3.DefaultSpec() + } + if !option.UJa3Spec.IsSet() && option.Ja3 { + option.UJa3Spec = ja3.DefaultUSpec() } if option.UserAgent == "" { option.UserAgent = obj.option.UserAgent @@ -377,12 +236,148 @@ func (obj *Client) newRequestOption(option RequestOption) RequestOption { if option.DisProxy { option.Proxy = "" } - if option.GetProxy == nil { - option.GetProxy = obj.option.GetProxy - } - if option.GetProxys == nil { - option.GetProxys = obj.option.GetProxys - } - - return option + return option, err } + +// func (obj *Client) newRequestOption(option RequestOption) RequestOption { +// // start +// if !option.Ja3Spec.IsSet() { +// option.Ja3Spec = obj.option.Ja3Spec +// } +// if !option.Ja3 { +// option.Ja3 = obj.option.Ja3 +// } +// if !option.UJa3Spec.IsSet() { +// option.UJa3Spec = obj.option.UJa3Spec +// } + +// if !option.H2Ja3Spec.IsSet() { +// option.H2Ja3Spec = obj.option.H2Ja3Spec +// } +// if option.Proxy == "" { +// option.Proxy = obj.option.Proxy +// } +// if len(option.Proxys) == 0 { +// option.Proxys = obj.option.Proxys +// } +// if !option.ForceHttp1 { +// option.ForceHttp1 = obj.option.ForceHttp1 +// } +// if !option.DisCookie { +// option.DisCookie = obj.option.DisCookie +// } +// if !option.DisDecode { +// option.DisDecode = obj.option.DisDecode +// } +// if !option.DisUnZip { +// option.DisUnZip = obj.option.DisUnZip +// } +// if !option.Bar { +// option.Bar = obj.option.Bar +// } +// if !option.H3 { +// option.H3 = obj.option.H3 +// } +// if option.Logger == nil { +// option.Logger = obj.option.Logger +// } +// if option.Headers == nil { +// option.Headers = obj.option.Headers +// } +// if option.Timeout == 0 { +// option.Timeout = obj.option.Timeout +// } +// if option.ResponseHeaderTimeout == 0 { +// option.ResponseHeaderTimeout = obj.option.ResponseHeaderTimeout +// } +// if option.TlsHandshakeTimeout == 0 { +// option.TlsHandshakeTimeout = obj.option.TlsHandshakeTimeout +// } +// if option.TlsConfig == nil { +// option.TlsConfig = obj.option.TlsConfig +// } +// if option.UtlsConfig == nil { +// option.UtlsConfig = obj.option.UtlsConfig +// } +// if option.OrderHeaders == nil { +// option.OrderHeaders = obj.option.OrderHeaders +// } +// if option.OptionCallBack == nil { +// option.OptionCallBack = obj.option.OptionCallBack +// } +// if option.ResultCallBack == nil { +// option.ResultCallBack = obj.option.ResultCallBack +// } +// if option.ErrCallBack == nil { +// option.ErrCallBack = obj.option.ErrCallBack +// } +// if option.RequestCallBack == nil { +// option.RequestCallBack = obj.option.RequestCallBack +// } +// if option.MaxRetries == 0 { +// option.MaxRetries = obj.option.MaxRetries +// } +// if option.MaxRedirect == 0 { +// option.MaxRedirect = obj.option.MaxRedirect +// } +// if option.Headers == nil { +// option.Headers = obj.option.Headers +// } +// if option.Timeout == 0 { +// option.Timeout = obj.option.Timeout +// } +// if option.ResponseHeaderTimeout == 0 { +// option.ResponseHeaderTimeout = obj.option.ResponseHeaderTimeout +// } +// if option.TlsHandshakeTimeout == 0 { +// option.TlsHandshakeTimeout = obj.option.TlsHandshakeTimeout +// } +// if option.DialOption.DialTimeout == 0 { +// option.DialOption.DialTimeout = obj.option.DialOption.DialTimeout +// } +// if option.DialOption.KeepAlive == 0 { +// option.DialOption.KeepAlive = obj.option.DialOption.KeepAlive +// } +// if option.DialOption.LocalAddr == nil { +// option.DialOption.LocalAddr = obj.option.DialOption.LocalAddr +// } +// if option.DialOption.AddrType == 0 { +// option.DialOption.AddrType = obj.option.DialOption.AddrType +// } +// if option.DialOption.Dns == nil { +// option.DialOption.Dns = obj.option.DialOption.Dns +// } +// if option.DialOption.GetAddrType == nil { +// option.DialOption.GetAddrType = obj.option.DialOption.GetAddrType +// } +// if option.Jar == nil { +// option.Jar = obj.option.Jar +// } +// //end +// if option.MaxRetries < 0 { +// option.MaxRetries = 0 +// } +// if !option.Ja3Spec.IsSet() && option.Ja3 { +// option.Ja3Spec = ja3.DefaultJa3Spec() +// } +// if !option.UJa3Spec.IsSet() && option.Ja3 { +// option.UJa3Spec = ja3.DefaultUJa3Spec() +// } +// if option.UserAgent == "" { +// option.UserAgent = obj.option.UserAgent +// } +// if option.DisCookie { +// option.Jar = nil +// } +// if option.DisProxy { +// option.Proxy = "" +// } +// if option.GetProxy == nil { +// option.GetProxy = obj.option.GetProxy +// } +// if option.GetProxys == nil { +// option.GetProxys = obj.option.GetProxys +// } + +// return option +// } diff --git a/requests.go b/requests.go index 873ea45..e6c19ff 100644 --- a/requests.go +++ b/requests.go @@ -145,7 +145,10 @@ func (obj *Client) Request(ctx context.Context, method string, href string, opti if len(options) > 0 { rawOption = options[0] } - optionBak := obj.newRequestOption(rawOption) + optionBak, err := obj.newRequestOption(rawOption) + if err != nil { + return nil, err + } optionBak.requestId = tools.NaoId() if optionBak.Method == "" { optionBak.Method = method @@ -205,7 +208,7 @@ func (obj *Client) request(ctx context.Context, option *RequestOption) (response //设置 h2 请求头顺序 if option.OrderHeaders != nil { if !option.H2Ja3Spec.IsSet() { - option.H2Ja3Spec = ja3.DefaultH2Ja3Spec() + option.H2Ja3Spec = ja3.DefaultH2Spec() option.H2Ja3Spec.OrderHeaders = option.OrderHeaders } else if option.H2Ja3Spec.OrderHeaders == nil { option.H2Ja3Spec.OrderHeaders = option.OrderHeaders diff --git a/roundTripper.go b/roundTripper.go index fdf08d7..7b4906d 100644 --- a/roundTripper.go +++ b/roundTripper.go @@ -13,6 +13,7 @@ import ( "github.com/gospider007/gtls" "github.com/gospider007/http2" "github.com/gospider007/http3" + "github.com/gospider007/ja3" "github.com/gospider007/tools" "github.com/quic-go/quic-go" uquic "github.com/refraction-networking/uquic" @@ -96,7 +97,6 @@ func (obj *roundTripper) http3Dial(ctx context.Context, option *RequestOption, r err = errors.New("http3 last proxy must socks5 proxy") return } - // udpConn, err = obj.dialer.Socks5UdpProxy(ctx, option, remtoeAddress, proxyAddress...) udpConn, _, err = obj.dialer.DialProxyContext(ctx, option, "tcp", option.TlsConfig.Clone(), append(proxyAddress, remtoeAddress)...) } else { udpConn, err = net.ListenUDP("udp", nil) @@ -126,6 +126,10 @@ func (obj *roundTripper) ghttp3Dial(ctx context.Context, option *RequestOption, } func (obj *roundTripper) uhttp3Dial(ctx context.Context, option *RequestOption, remoteAddress Address, proxyAddress ...Address) (conn *connecotr, err error) { + spec, err := ja3.CreateSpecWithUSpec(option.UJa3Spec) + if err != nil { + return nil, err + } udpConn, err := obj.http3Dial(ctx, option, remoteAddress, proxyAddress...) if err != nil { return nil, err @@ -139,7 +143,12 @@ func (obj *roundTripper) uhttp3Dial(ctx context.Context, option *RequestOption, return nil, err } } - netConn, err := uquic.DialEarly(ctx, udpConn, remoteAddress, tlsConfig, nil) + netConn, err := (&uquic.UTransport{ + Transport: &uquic.Transport{ + Conn: udpConn, + }, + QUICSpec: &spec, + }).DialEarly(ctx, &net.UDPAddr{IP: remoteAddress.IP, Port: remoteAddress.Port}, tlsConfig, nil) conn = obj.newConnecotr() conn.Conn = http3.NewUClient(netConn, func() { conn.forceCnl(errors.New("http3 client close")) @@ -157,7 +166,7 @@ func (obj *roundTripper) dial(option *RequestOption, req *http.Request) (conn *c return nil, err } if option.H3 { - if option.Ja3Spec.IsSet() { + if option.UJa3Spec.IsSet() { return obj.uhttp3Dial(req.Context(), option, remoteAddress, proxys...) } else { return obj.ghttp3Dial(req.Context(), option, remoteAddress, proxys...) @@ -227,13 +236,13 @@ func (obj *roundTripper) dialAddTls(option *RequestOption, req *http.Request, ne ctx, cnl := context.WithTimeout(req.Context(), option.TlsHandshakeTimeout) defer cnl() if option.Ja3Spec.IsSet() { - if tlsConn, err := obj.dialer.addJa3Tls(ctx, netConn, getHost(req), option.ForceHttp1, option.Ja3Spec, option.UtlsConfig.Clone()); err != nil { + if tlsConn, err := obj.dialer.addJa3Tls(ctx, netConn, getHost(req), !option.ForceHttp1, option.Ja3Spec, option.UtlsConfig.Clone()); err != nil { return tlsConn, false, tools.WrapError(err, "add ja3 tls error") } else { return tlsConn, tlsConn.ConnectionState().NegotiatedProtocol == "h2", nil } } else { - if tlsConn, err := obj.dialer.addTls(ctx, netConn, getHost(req), option.ForceHttp1, option.TlsConfig.Clone()); err != nil { + if tlsConn, err := obj.dialer.addTls(ctx, netConn, getHost(req), !option.ForceHttp1, option.TlsConfig.Clone()); err != nil { return tlsConn, false, tools.WrapError(err, "add tls error") } else { return tlsConn, tlsConn.ConnectionState().NegotiatedProtocol == "h2", nil diff --git a/test/cookies/setCookies_test.go b/test/cookies/setCookies_test.go index ba49f60..d1f2a38 100644 --- a/test/cookies/setCookies_test.go +++ b/test/cookies/setCookies_test.go @@ -17,11 +17,14 @@ func TestSetCookies(t *testing.T) { log.Panic(err) } _, err = session.Get(context.TODO(), "https://www.baidu.com", requests.RequestOption{ - RequestCallBack: func(ctx context.Context, request *http.Request, response *http.Response) error { - if request.Cookies() == nil { - log.Panic("cookie is nil") - } - return nil + ClientOption: requests.ClientOption{ + + RequestCallBack: func(ctx context.Context, request *http.Request, response *http.Response) error { + if request.Cookies() == nil { + log.Panic("cookie is nil") + } + return nil + }, }, }) if err != nil { diff --git a/test/dns_test.go b/test/dns_test.go index d6aa9a8..141addd 100644 --- a/test/dns_test.go +++ b/test/dns_test.go @@ -9,10 +9,12 @@ import ( func TestDns(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - DialOption: requests.DialOption{ - Dns: &net.UDPAddr{ //set dns server - IP: net.ParseIP("223.5.5.5"), - Port: 53, + ClientOption: requests.ClientOption{ + DialOption: requests.DialOption{ + Dns: &net.UDPAddr{ //set dns server + IP: net.ParseIP("223.5.5.5"), + Port: 53, + }, }, }, }) diff --git a/test/fingerprint/http2_test.go b/test/fingerprint/http2_test.go index dd1b1f9..1912044 100644 --- a/test/fingerprint/http2_test.go +++ b/test/fingerprint/http2_test.go @@ -17,7 +17,9 @@ func TestH2(t *testing.T) { } // log.Print(h2Spec) resp, err := requests.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{ - H2Ja3Spec: h2Spec, //set h2 spec + ClientOption: requests.ClientOption{ + H2Ja3Spec: h2Spec, //set h2 spec + }, }) // log.Print(resp.Text()) if err != nil { diff --git a/test/fingerprint/ja3_test.go b/test/fingerprint/ja3_test.go index 443b5c5..2c9cde0 100644 --- a/test/fingerprint/ja3_test.go +++ b/test/fingerprint/ja3_test.go @@ -19,7 +19,10 @@ func TestJa3(t *testing.T) { t.Fatal(err) } resp, err := requests.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{ - Ja3Spec: ja3Spec, + ClientOption: requests.ClientOption{ + + Ja3Spec: ja3Spec, + }, }) if err != nil { t.Fatal(err) @@ -48,7 +51,10 @@ func TestJa3Psk(t *testing.T) { session, _ := requests.NewClient(nil) for i := 0; i < 2; i++ { resp, err := session.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{ - Ja3Spec: ja3Spec, //set ja3 spec + ClientOption: requests.ClientOption{ + + Ja3Spec: ja3Spec, //set ja3 spec + }, }) if err != nil { t.Fatal(err) @@ -79,7 +85,10 @@ func TestJa3ClientHello(t *testing.T) { } // log.Print(ja3Spec) resp, err := requests.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{ - Ja3Spec: ja3Spec, + ClientOption: requests.ClientOption{ + + Ja3Spec: ja3Spec, + }, }) if err != nil { t.Fatal(err) diff --git a/test/fingerprint/ja4_test.go b/test/fingerprint/ja4_test.go index 94d8170..1dd6499 100644 --- a/test/fingerprint/ja4_test.go +++ b/test/fingerprint/ja4_test.go @@ -21,7 +21,9 @@ func TestOrderHeaders(t *testing.T) { headers.Set("Sec-Ch-Ua-Mobile", "?0") headers.Set("Sec-Ch-Ua-Platform", `"Windows"`) resp, err := requests.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{ - Headers: headers, + ClientOption: requests.ClientOption{ + Headers: headers, + }, // ForceHttp1: true, }) if err != nil { @@ -72,8 +74,11 @@ func TestOrderHeaders2(t *testing.T) { "Sec-Ch-Ua-Platform", } resp, err := requests.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{ - Headers: headers, - OrderHeaders: orderHeaders, + ClientOption: requests.ClientOption{ + + Headers: headers, + OrderHeaders: orderHeaders, + }, // ForceHttp1: true, }) if err != nil { diff --git a/test/fingerprint/quic_test.go b/test/fingerprint/quic_test.go index 6d13068..6d67fb9 100644 --- a/test/fingerprint/quic_test.go +++ b/test/fingerprint/quic_test.go @@ -5,13 +5,16 @@ import ( "log" "testing" + "github.com/gospider007/ja3" "github.com/gospider007/requests" ) func TestHttp3(t *testing.T) { resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{ - H3: true, - Ja3: true, + ClientOption: requests.ClientOption{ + H3: true, + Ja3: true, + }, }, ) if err != nil { @@ -26,5 +29,22 @@ func TestHttp3(t *testing.T) { } } -// [0 87 164 1 116 253 33 138 106 82] -// [0 87 162 31 139 8 0 0 0 0] +func TestHttp32(t *testing.T) { + resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{ + ClientOption: requests.ClientOption{ + UJa3Spec: ja3.CreateUSpecWithId(ja3.QUICChrome_115), + H3: true, + }, + }, + ) + if err != nil { + t.Error(err) + } + log.Print(resp.Proto()) + if resp.StatusCode() != 200 { + t.Error("resp.StatusCode!= 200") + } + if resp.Proto() != "HTTP/3.0" { + t.Error("resp.Proto!= HTTP/3.0") + } +} diff --git a/test/logger/logger_test.go b/test/logger/logger_test.go index 8e7efcd..d2d92e9 100644 --- a/test/logger/logger_test.go +++ b/test/logger/logger_test.go @@ -10,9 +10,12 @@ import ( func TestLogger(t *testing.T) { for i := 0; i < 2; i++ { response, err := requests.Get(nil, "https://www.httpbin.org", requests.RequestOption{ - Ja3: true, - Logger: func(l requests.Log) { - log.Print(l) + ClientOption: requests.ClientOption{ + + Ja3: true, + Logger: func(l requests.Log) { + log.Print(l) + }, }, }) if err != nil { diff --git a/test/middleware/errCallBack_test.go b/test/middleware/errCallBack_test.go index af10690..154bf09 100644 --- a/test/middleware/errCallBack_test.go +++ b/test/middleware/errCallBack_test.go @@ -11,16 +11,19 @@ import ( func TestErrCallBack(t *testing.T) { n := 0 _, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - MaxRetries: 3, - ResultCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response) error { - return errors.New("try") - }, - ErrCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response, err error) error { - if n == 0 { - n++ - return nil - } - return errors.New("test") + ClientOption: requests.ClientOption{ + + MaxRetries: 3, + ResultCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response) error { + return errors.New("try") + }, + ErrCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response, err error) error { + if n == 0 { + n++ + return nil + } + return errors.New("test") + }, }, }) if err == nil { diff --git a/test/middleware/optionltCallBack_test.go b/test/middleware/optionltCallBack_test.go index c49eac7..a6c2594 100644 --- a/test/middleware/optionltCallBack_test.go +++ b/test/middleware/optionltCallBack_test.go @@ -9,9 +9,12 @@ import ( func TestOptionCallBack(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - OptionCallBack: func(ctx context.Context, option *requests.RequestOption) error { - option.Params = map[string]string{"name": "test"} - return nil + ClientOption: requests.ClientOption{ + + OptionCallBack: func(ctx context.Context, option *requests.RequestOption) error { + option.Params = map[string]string{"name": "test"} + return nil + }, }, }) if err != nil { diff --git a/test/middleware/redirectCallBack_test.go b/test/middleware/redirectCallBack_test.go index 5927e92..9420378 100644 --- a/test/middleware/redirectCallBack_test.go +++ b/test/middleware/redirectCallBack_test.go @@ -10,11 +10,14 @@ import ( func TestRedirectCallBack(t *testing.T) { response, err := requests.Get(context.TODO(), "http://www.baidu.com", requests.RequestOption{ - RequestCallBack: func(ctx context.Context, request *http.Request, response *http.Response) error { - if response != nil { - return requests.ErrUseLastResponse - } - return nil + ClientOption: requests.ClientOption{ + + RequestCallBack: func(ctx context.Context, request *http.Request, response *http.Response) error { + if response != nil { + return requests.ErrUseLastResponse + } + return nil + }, }, }) if err != nil { diff --git a/test/middleware/requestCallback_test.go b/test/middleware/requestCallback_test.go index c109be3..3684e68 100644 --- a/test/middleware/requestCallback_test.go +++ b/test/middleware/requestCallback_test.go @@ -12,13 +12,16 @@ import ( func TestRequestCallBack(t *testing.T) { _, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - RequestCallBack: func(ctx context.Context, request *http.Request, response *http.Response) error { - if response != nil { - if response.ContentLength > 100 { - return errors.New("max length") + ClientOption: requests.ClientOption{ + + RequestCallBack: func(ctx context.Context, request *http.Request, response *http.Response) error { + if response != nil { + if response.ContentLength > 100 { + return errors.New("max length") + } } - } - return nil + return nil + }, }, }) if !strings.Contains(err.Error(), "max length") { diff --git a/test/middleware/resultCallBack_test.go b/test/middleware/resultCallBack_test.go index 014a402..8f6d38f 100644 --- a/test/middleware/resultCallBack_test.go +++ b/test/middleware/resultCallBack_test.go @@ -11,12 +11,15 @@ import ( func TestResultCallBack(t *testing.T) { var code int _, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - ResultCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response) error { - if response.StatusCode() != 200 { - return errors.New("resp.StatusCode!= 200") - } - code = response.StatusCode() - return nil + ClientOption: requests.ClientOption{ + + ResultCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response) error { + if response.StatusCode() != 200 { + return errors.New("resp.StatusCode!= 200") + } + code = response.StatusCode() + return nil + }, }, }) if err != nil { diff --git a/test/middleware/try_test.go b/test/middleware/try_test.go index c9a7f7b..50caeec 100644 --- a/test/middleware/try_test.go +++ b/test/middleware/try_test.go @@ -11,14 +11,17 @@ import ( func TestMaxRetries(t *testing.T) { n := 0 resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - MaxRetries: 3, - ResultCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response) error { + ClientOption: requests.ClientOption{ - if n == 0 { - n++ - return errors.New("try") - } - return nil + MaxRetries: 3, + ResultCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response) error { + + if n == 0 { + n++ + return errors.New("try") + } + return nil + }, }, }) if err != nil { diff --git a/test/protocol/http1_test.go b/test/protocol/http1_test.go index d0c357d..e8a41ab 100644 --- a/test/protocol/http1_test.go +++ b/test/protocol/http1_test.go @@ -10,13 +10,16 @@ import ( func TestHttp1(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - ForceHttp1: true, - Logger: func(l requests.Log) { - log.Print(l) - }, - ErrCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response, err error) error { - log.Print(err) - return nil + ClientOption: requests.ClientOption{ + + ForceHttp1: true, + Logger: func(l requests.Log) { + log.Print(l) + }, + ErrCallBack: func(ctx context.Context, option *requests.RequestOption, response *requests.Response, err error) error { + log.Print(err) + return nil + }, }, }) if err != nil { diff --git a/test/protocol/http3_test.go b/test/protocol/http3_test.go index a211fbd..22c7bbe 100644 --- a/test/protocol/http3_test.go +++ b/test/protocol/http3_test.go @@ -10,7 +10,10 @@ import ( func TestHttp3(t *testing.T) { resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{ - H3: true, + ClientOption: requests.ClientOption{ + + H3: true, + }, }, ) if err != nil { diff --git a/test/proxy/chain_proxy_test.go b/test/proxy/chain_proxy_test.go index c5fc7d7..9cbf69d 100644 --- a/test/proxy/chain_proxy_test.go +++ b/test/proxy/chain_proxy_test.go @@ -33,10 +33,14 @@ func TestProxy2(t *testing.T) { if err != nil { t.Fatal(err) } - resp, err := reqCli.Request(nil, "get", "https://httpbin.org/ip", requests.RequestOption{Proxys: []string{ - proIp, - proIp2, - }}) + resp, err := reqCli.Request(nil, "get", "https://httpbin.org/ip", requests.RequestOption{ + ClientOption: requests.ClientOption{ + + Proxys: []string{ + proIp, + proIp2, + }, + }}) if err != nil { t.Fatal(err) } @@ -45,7 +49,10 @@ func TestProxy2(t *testing.T) { func TestChainProxy(t *testing.T) { resp, err := requests.Get(context.TODO(), "https://httpbin.org/anything", requests.RequestOption{ - Proxys: []string{}, //set proxy,ex:"http://127.0.0.1:8080","https://127.0.0.1:8080","socks5://127.0.0.1:8080" + ClientOption: requests.ClientOption{ + + Proxys: []string{}, //set proxy,ex:"http://127.0.0.1:8080","https://127.0.0.1:8080","socks5://127.0.0.1:8080" + }, }) if err != nil { t.Error(err) diff --git a/test/proxy/disProxy_test.go b/test/proxy/disProxy_test.go index d22d111..79cf061 100644 --- a/test/proxy/disProxy_test.go +++ b/test/proxy/disProxy_test.go @@ -8,7 +8,10 @@ import ( func TestDisProxy(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - Proxy: "http://192.368.7.256:9887", + ClientOption: requests.ClientOption{ + + Proxy: "http://192.368.7.256:9887", + }, DisProxy: true, }) if err != nil { diff --git a/test/proxy/http3_proxy_test.go b/test/proxy/http3_proxy_test.go index 79ba3a0..0491539 100644 --- a/test/proxy/http3_proxy_test.go +++ b/test/proxy/http3_proxy_test.go @@ -25,12 +25,15 @@ var ( func client() { for range 5 { resp, err := requests.Post(nil, "https://"+remoteHost, requests.RequestOption{ - H3: true, - Logger: func(l requests.Log) { - log.Print(l) + ClientOption: requests.ClientOption{ + + H3: true, + Logger: func(l requests.Log) { + log.Print(l) + }, + Proxy: "socks5://" + proxyHost, }, - Proxy: "socks5://" + proxyHost, - Body: []byte("hello, server!"), + Body: []byte("hello, server!"), }) if err != nil { fmt.Println(err) @@ -45,13 +48,16 @@ func client() { func client2() { for range 5 { resp, err := requests.Post(nil, "https://"+remoteHost, requests.RequestOption{ - H3: true, - Logger: func(l requests.Log) { - log.Print(l) - }, - Proxys: []string{ - "http://" + proxyHost, - "socks5://" + proxyHost, + + ClientOption: requests.ClientOption{ + H3: true, + Logger: func(l requests.Log) { + log.Print(l) + }, + Proxys: []string{ + "http://" + proxyHost, + "socks5://" + proxyHost, + }, }, Body: []byte("hello, server!"), }) diff --git a/test/proxy/proxy_test.go b/test/proxy/proxy_test.go index f234e13..5caa389 100644 --- a/test/proxy/proxy_test.go +++ b/test/proxy/proxy_test.go @@ -10,7 +10,7 @@ import ( func TestProxy(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - Proxy: "", //set proxy,ex:"http://127.0.0.1:8080","https://127.0.0.1:8080","socks5://127.0.0.1:8080" + ClientOption: requests.ClientOption{Proxy: ""}, //set proxy,ex:"http://127.0.0.1:8080","https://127.0.0.1:8080","socks5://127.0.0.1:8080" }) if err != nil { t.Error(err) diff --git a/test/response/request/localAddr_test.go b/test/response/request/localAddr_test.go index 5c21047..c9b6143 100644 --- a/test/response/request/localAddr_test.go +++ b/test/response/request/localAddr_test.go @@ -9,9 +9,11 @@ import ( func TestLocalAddr(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ - DialOption: requests.DialOption{ - LocalAddr: &net.TCPAddr{ //set dns server - IP: net.ParseIP("192.168.1.239"), + ClientOption: requests.ClientOption{ + DialOption: requests.DialOption{ + LocalAddr: &net.TCPAddr{ //set dns server + IP: net.ParseIP("192.168.1.239"), + }, }, }, }) diff --git a/test/response/request/stream_test.go b/test/response/request/stream_test.go index 4597173..8ebce67 100644 --- a/test/response/request/stream_test.go +++ b/test/response/request/stream_test.go @@ -11,8 +11,10 @@ import ( func TestStream(t *testing.T) { resp, err := requests.Get(nil, "https://httpbin.org/anything", requests.RequestOption{ Stream: true, - Logger: func(l requests.Log) { - log.Print(l) + ClientOption: requests.ClientOption{ + Logger: func(l requests.Log) { + log.Print(l) + }, }, }) if err != nil { diff --git a/test/session_test.go b/test/session_test.go index 1590e81..305efe0 100644 --- a/test/session_test.go +++ b/test/session_test.go @@ -49,7 +49,7 @@ func TestSession2(t *testing.T) { func TestSession3(t *testing.T) { session, _ := requests.NewClient(nil) for i := 0; i < 2; i++ { - resp, err := session.Get(nil, "https://cloudflare-quic.com/", requests.RequestOption{H3: true}) + resp, err := session.Get(nil, "https://cloudflare-quic.com/", requests.RequestOption{ClientOption: requests.ClientOption{H3: true}}) if err != nil { t.Error(err) }