mirror of
https://github.com/gospider007/requests.git
synced 2025-12-24 13:57:52 +08:00
sync
This commit is contained in:
@@ -4,10 +4,11 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/gospider007/gtls"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gospider007/gtls"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
)
|
||||
|
||||
// Connection Management
|
||||
|
||||
17
dial.go
17
dial.go
@@ -5,16 +5,17 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"github.com/gospider007/gtls"
|
||||
"github.com/gospider007/ja3"
|
||||
"github.com/gospider007/tools"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gospider007/gtls"
|
||||
"github.com/gospider007/ja3"
|
||||
"github.com/gospider007/tools"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
)
|
||||
|
||||
type msgClient struct {
|
||||
@@ -36,7 +37,8 @@ type dialer interface {
|
||||
|
||||
// 自定义dialer
|
||||
type Dialer struct {
|
||||
dnsIpData sync.Map
|
||||
dnsIpData sync.Map
|
||||
specClient *ja3.Client
|
||||
// dialer dialer
|
||||
}
|
||||
type myDialer struct {
|
||||
@@ -390,14 +392,13 @@ func (obj *Dialer) addTls(ctx context.Context, conn net.Conn, host string, h2 bo
|
||||
tlsConn = tls.Client(conn, tlsConfig)
|
||||
return tlsConn, tlsConn.HandshakeContext(ctx)
|
||||
}
|
||||
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)
|
||||
func (obj *Dialer) addJa3Tls(ctx context.Context, conn net.Conn, host string, h2 bool, spec utls.ClientHelloSpec, tlsConfig *utls.Config) (*utls.UConn, error) {
|
||||
if h2 {
|
||||
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
|
||||
} else {
|
||||
tlsConfig.NextProtos = []string{"http/1.1"}
|
||||
}
|
||||
return ja3.NewClient(ctx, conn, spec, h2, tlsConfig)
|
||||
return obj.specClient.Client(ctx, conn, spec, h2, tlsConfig, gtls.GetServerName(host))
|
||||
}
|
||||
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 {
|
||||
|
||||
4
go.mod
4
go.mod
@@ -7,8 +7,8 @@ require (
|
||||
github.com/gospider007/bs4 v0.0.0-20250110063952-3322ee09a952
|
||||
github.com/gospider007/gson v0.0.0-20250110063619-6fd4001287da
|
||||
github.com/gospider007/gtls v0.0.0-20250107100054-2a14fa6fc9c5
|
||||
github.com/gospider007/http2 v0.0.0-20250207072457-e5aee546e6ef
|
||||
github.com/gospider007/http3 v0.0.0-20250207072522-fbe0ea54a292
|
||||
github.com/gospider007/http2 v0.0.0-20250211075152-9b93ea5934a7
|
||||
github.com/gospider007/http3 v0.0.0-20250211075910-8bad8da7d8cc
|
||||
github.com/gospider007/ja3 v0.0.0-20250210150438-a0b8d7729724
|
||||
github.com/gospider007/proxy v0.0.0-20250114011401-cd5ee0138e0e
|
||||
github.com/gospider007/re v0.0.0-20241216142712-efbef8d55ea2
|
||||
|
||||
6
go.sum
6
go.sum
@@ -59,6 +59,7 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -108,8 +109,12 @@ github.com/gospider007/gtls v0.0.0-20250107100054-2a14fa6fc9c5 h1:c0payCC+agt1c+
|
||||
github.com/gospider007/gtls v0.0.0-20250107100054-2a14fa6fc9c5/go.mod h1:qIlB6X0WLv9QVqo/LLqkml0JDKSjeL3x4tI1QCINU94=
|
||||
github.com/gospider007/http2 v0.0.0-20250207072457-e5aee546e6ef h1:uit8QvhFLCA26ZQHV8akzHu4BHOZ7nSuph097sQHB/8=
|
||||
github.com/gospider007/http2 v0.0.0-20250207072457-e5aee546e6ef/go.mod h1:3uzGktvy4KnYZm+DwWNui4RsvPUQSSphJ1VTtfO1tE0=
|
||||
github.com/gospider007/http2 v0.0.0-20250211075152-9b93ea5934a7 h1:eEqGJ+D+WhsQyD0i1NOapkpSxhb2CS+S2JRnJGm9kn0=
|
||||
github.com/gospider007/http2 v0.0.0-20250211075152-9b93ea5934a7/go.mod h1:tyoQk56/HeqWXUL5dXpmCWoH+jVIaxo3//HAYeMPWkM=
|
||||
github.com/gospider007/http3 v0.0.0-20250207072522-fbe0ea54a292 h1:CpWOjsI8+sFP2uDHXCyN+pcifwLQ3vz9SlRuJFcb0mk=
|
||||
github.com/gospider007/http3 v0.0.0-20250207072522-fbe0ea54a292/go.mod h1:CCgRzDZa7vZZEx+RJK/tGOFAF0L1MX7wKKw+h5ntIA8=
|
||||
github.com/gospider007/http3 v0.0.0-20250211075910-8bad8da7d8cc h1:vZDb6z5iPkAnCkfS77cIiR8gbcWbL9yRD5HAiYovXFA=
|
||||
github.com/gospider007/http3 v0.0.0-20250211075910-8bad8da7d8cc/go.mod h1:B/9ytNa5gyQwktT9klskrWVZliYgNXRpXQtZCu7XGVU=
|
||||
github.com/gospider007/ja3 v0.0.0-20250210150438-a0b8d7729724 h1:RH16GaKyQftA5SFdGCZ7qH0V17T4T9MGcqF4AMXE2UY=
|
||||
github.com/gospider007/ja3 v0.0.0-20250210150438-a0b8d7729724/go.mod h1:LyhufzO6wrBlxeilbUJElfEdDNdD+1v9fB5p30pDAjE=
|
||||
github.com/gospider007/kinds v0.0.0-20240929092451-8f867acde255 h1:X+AM/mgmh/EfyQUjKZp1VFc9TSlrhkwS0eSYeo5fMs4=
|
||||
@@ -152,6 +157,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
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 v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
||||
github.com/mholt/acmez/v3 v3.0.1 h1:4PcjKjaySlgXK857aTfDuRbmnM5gb3Ruz3tvoSJAUp8=
|
||||
github.com/mholt/acmez/v3 v3.0.1/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
|
||||
github.com/mholt/archives v0.1.0 h1:FacgJyrjiuyomTuNA92X5GyRBRZjE43Y/lrzKIlF35Q=
|
||||
|
||||
24
option.go
24
option.go
@@ -3,15 +3,16 @@ package requests
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/gospider007/ja3"
|
||||
"github.com/gospider007/tools"
|
||||
"github.com/gospider007/websocket"
|
||||
"github.com/quic-go/quic-go"
|
||||
uquic "github.com/refraction-networking/uquic"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LogType string
|
||||
@@ -37,7 +38,7 @@ type Log struct {
|
||||
|
||||
// Connection Management Options
|
||||
type ClientOption struct {
|
||||
Ja3Spec ja3.Spec //custom ja3Spec,use ja3.CreateSpecWithStr or ja3.CreateSpecWithId create
|
||||
Ja3Spec any //support utls.ClientHelloID, clienthello with hex string, clienthello with byte array
|
||||
DialOption DialOption
|
||||
Headers any //default headers
|
||||
Jar Jar //custom cookies
|
||||
@@ -52,7 +53,7 @@ type ClientOption struct {
|
||||
UtlsConfig *utls.Config
|
||||
QuicConfig *quic.Config
|
||||
UquicConfig *uquic.Config
|
||||
UJa3Spec ja3.USpec //h3 fingerprint
|
||||
UJa3Spec uquic.QUICID
|
||||
Proxy string //proxy,support https,http,socks5
|
||||
UserAgent string //headers User-Agent value
|
||||
OrderHeaders []string //order headers
|
||||
@@ -66,9 +67,10 @@ type ClientOption struct {
|
||||
H3 bool //开启http3
|
||||
ForceHttp1 bool //force use http1 send requests
|
||||
Ja3 bool //enable ja3 fingerprint
|
||||
DisCookie bool //disable cookies
|
||||
DisDecode bool //disable auto decode
|
||||
Bar bool ////enable bar display
|
||||
UJa3 bool
|
||||
DisCookie bool //disable cookies
|
||||
DisDecode bool //disable auto decode
|
||||
Bar bool ////enable bar display
|
||||
}
|
||||
|
||||
// Options for sending requests
|
||||
@@ -202,12 +204,6 @@ func (obj *Client) newRequestOption(option RequestOption) (RequestOption, error)
|
||||
if option.MaxRetries < 0 {
|
||||
option.MaxRetries = 0
|
||||
}
|
||||
if !option.Ja3Spec.IsSet() && option.Ja3 {
|
||||
option.Ja3Spec = ja3.DefaultSpec()
|
||||
}
|
||||
if !option.UJa3Spec.IsSet() && option.Ja3 {
|
||||
option.UJa3Spec = ja3.DefaultUSpec()
|
||||
}
|
||||
if option.UserAgent == "" {
|
||||
option.UserAgent = obj.ClientOption.UserAgent
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ 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"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
)
|
||||
|
||||
type reqTask struct {
|
||||
@@ -60,9 +62,11 @@ func newRoundTripper(preCtx context.Context) *roundTripper {
|
||||
}
|
||||
ctx, cnl := context.WithCancel(preCtx)
|
||||
return &roundTripper{
|
||||
ctx: ctx,
|
||||
cnl: cnl,
|
||||
dialer: &Dialer{},
|
||||
ctx: ctx,
|
||||
cnl: cnl,
|
||||
dialer: &Dialer{
|
||||
specClient: ja3.NewClient(),
|
||||
},
|
||||
connPools: newConnPools(),
|
||||
}
|
||||
}
|
||||
@@ -134,7 +138,6 @@ func (obj *roundTripper) ghttp3Dial(ctx *Response, remoteAddress Address, proxyA
|
||||
}
|
||||
|
||||
func (obj *roundTripper) uhttp3Dial(ctx *Response, remoteAddress Address, proxyAddress ...Address) (conn *connecotr, err error) {
|
||||
|
||||
udpConn, err := obj.http3Dial(ctx, remoteAddress, proxyAddress...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -152,7 +155,14 @@ func (obj *roundTripper) uhttp3Dial(ctx *Response, remoteAddress Address, proxyA
|
||||
if ctx.option.UquicConfig != nil {
|
||||
quicConfig = ctx.option.UquicConfig.Clone()
|
||||
}
|
||||
spec := uquic.QUICSpec(ctx.option.UJa3Spec)
|
||||
var spec uquic.QUICSpec
|
||||
if ctx.option.UJa3Spec.Client != "" {
|
||||
if spec, err = uquic.QUICID2Spec(ctx.option.UJa3Spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
spec = ja3.DefaultUSpec()
|
||||
}
|
||||
netConn, err := (&uquic.UTransport{
|
||||
Transport: &uquic.Transport{
|
||||
Conn: udpConn,
|
||||
@@ -176,7 +186,7 @@ func (obj *roundTripper) dial(ctx *Response) (conn *connecotr, err error) {
|
||||
return nil, err
|
||||
}
|
||||
if ctx.option.H3 {
|
||||
if ctx.option.UJa3Spec.IsSet() {
|
||||
if ctx.option.UJa3Spec.Client != "" || ctx.option.UJa3 {
|
||||
return obj.uhttp3Dial(ctx, remoteAddress, proxys...)
|
||||
} else {
|
||||
return obj.ghttp3Dial(ctx, remoteAddress, proxys...)
|
||||
@@ -246,8 +256,17 @@ func (obj *roundTripper) dialConnecotr(option *RequestOption, req *http.Request,
|
||||
func (obj *roundTripper) dialAddTls(option *RequestOption, req *http.Request, netConn net.Conn) (net.Conn, bool, error) {
|
||||
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 option.Ja3Spec != nil || option.Ja3 {
|
||||
var spec utls.ClientHelloSpec
|
||||
var err error
|
||||
if option.Ja3Spec != nil {
|
||||
if spec, err = ja3.CreateSpecWithClientHello(option.Ja3Spec); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
} else {
|
||||
spec = ja3.DefaultSpec()
|
||||
}
|
||||
if tlsConn, err := obj.dialer.addJa3Tls(ctx, netConn, getHost(req), !option.ForceHttp1, spec, option.UtlsConfig.Clone()); err != nil {
|
||||
return tlsConn, false, tools.WrapError(err, "add ja3 tls error")
|
||||
} else {
|
||||
return tlsConn, tlsConn.ConnectionState().NegotiatedProtocol == "h2", nil
|
||||
|
||||
@@ -5,9 +5,7 @@ import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/gospider007/ja3"
|
||||
"github.com/gospider007/requests"
|
||||
uquic "github.com/refraction-networking/uquic"
|
||||
)
|
||||
|
||||
func TestHttp3(t *testing.T) {
|
||||
@@ -33,8 +31,8 @@ func TestHttp3(t *testing.T) {
|
||||
func TestHttp32(t *testing.T) {
|
||||
resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{
|
||||
ClientOption: requests.ClientOption{
|
||||
UJa3Spec: ja3.CreateUSpecWithId(uquic.QUICChrome_115),
|
||||
H3: true,
|
||||
UJa3: true,
|
||||
H3: true,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user