This commit is contained in:
gospider
2025-02-28 09:10:07 +08:00
parent 068b80538f
commit 877d36c992
11 changed files with 154 additions and 42 deletions

View File

@@ -13,6 +13,7 @@ import (
"time"
"github.com/gospider007/gtls"
"github.com/gospider007/ja3"
"github.com/gospider007/tools"
utls "github.com/refraction-networking/utls"
)
@@ -398,7 +399,7 @@ func (obj *Dialer) addTls(ctx context.Context, conn net.Conn, host string, tlsCo
tlsConn = tls.Client(conn, tlsConfig)
return tlsConn, tlsConn.HandshakeContext(ctx)
}
func (obj *Dialer) addJa3Tls(ctx context.Context, conn net.Conn, host string, spec utls.ClientHelloSpec, tlsConfig *utls.Config, forceHttp1 bool) (*utls.UConn, error) {
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) {

2
go.mod
View File

@@ -48,6 +48,7 @@ require (
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/libdns/libdns v0.2.3 // indirect
github.com/mholt/acmez/v3 v3.0.1 // indirect
github.com/mholt/archives v0.1.0 // indirect
@@ -58,6 +59,7 @@ require (
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/sorairolake/lzip-go v0.3.5 // indirect
github.com/therootcompany/xz v1.0.1 // indirect
github.com/tidwall/gjson v1.18.0 // indirect

17
go.sum
View File

@@ -59,7 +59,6 @@ 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=
@@ -107,12 +106,8 @@ github.com/gospider007/gson v0.0.0-20250221154009-98d1695297de h1:QMZz0bl8YGWLjq
github.com/gospider007/gson v0.0.0-20250221154009-98d1695297de/go.mod h1:lS6dHguAqv+QgM12UwMKO58Eeph79DvDm+uTJfzQJkE=
github.com/gospider007/gtls v0.0.0-20250217075148-cad34209c0ae h1:w0FETfH2q/N1B8llpFC0+XZkxjNc99LoDSy1XW5NfT8=
github.com/gospider007/gtls v0.0.0-20250217075148-cad34209c0ae/go.mod h1:VoExB3KZrF8CwtvNfLWtLG5OcDWElgQ3dsjs/C+6f04=
github.com/gospider007/http2 v0.0.0-20250221154021-1366bc240764 h1:MYeVyTA++3l5YeXjEFHfYU3II7ufZSplHIlE6pW31Gc=
github.com/gospider007/http2 v0.0.0-20250221154021-1366bc240764/go.mod h1:2+tAfJBMjihghMV0c09jA6kScoRn3hBQxgVM1ntMLqQ=
github.com/gospider007/http2 v0.0.0-20250226135657-bd12c18bfa85 h1:8HbRWRJacp7fkL1svCYru3UX7wnyrEw5UkDIoLlhFKQ=
github.com/gospider007/http2 v0.0.0-20250226135657-bd12c18bfa85/go.mod h1:2+tAfJBMjihghMV0c09jA6kScoRn3hBQxgVM1ntMLqQ=
github.com/gospider007/http3 v0.0.0-20250221154026-be54f80e5184 h1:eoreZ2QcnMOqFoswlNJeJWzfberRLngXn0z+TArhUow=
github.com/gospider007/http3 v0.0.0-20250221154026-be54f80e5184/go.mod h1:qxy521ewxMMvL7Vr4e45mSqSZuWzO978WqYGEIrTa5I=
github.com/gospider007/http3 v0.0.0-20250226135718-f7f291b88480 h1:nBiIJNsMXonhivkXKU29WBo9hJctR1lcMPLThuwDMcI=
github.com/gospider007/http3 v0.0.0-20250226135718-f7f291b88480/go.mod h1:qxy521ewxMMvL7Vr4e45mSqSZuWzO978WqYGEIrTa5I=
github.com/gospider007/ja3 v0.0.0-20250221154036-c583ec1f60a4 h1:965mrrn3KPilX8wjNqnFS/6WybVbK9JVoDbeOy7EMVo=
@@ -125,8 +120,6 @@ github.com/gospider007/proxy v0.0.0-20250221154359-9d745b93f9f6 h1:SneVkgpr6mv+f
github.com/gospider007/proxy v0.0.0-20250221154359-9d745b93f9f6/go.mod h1:DIR1eozSgpyH59MwaIw1ryW97zwruM90EuFEM6ZrXhg=
github.com/gospider007/re v0.0.0-20250217075352-bcb79f285d6c h1:8/Cf+c2680tkWJ+ueZ9RLLK5R5R8nhE8pNBUPHjkvkM=
github.com/gospider007/re v0.0.0-20250217075352-bcb79f285d6c/go.mod h1:dd8aDIUG1vDPP5r+vHBtiUK0Zn6uk3SsWt1ZvmCCHLs=
github.com/gospider007/tools v0.0.0-20250221154605-e0d63fd3e79b h1:4Vamrbjg14m49Edhw8etVrowBilbDqv/S0pKnMXOVls=
github.com/gospider007/tools v0.0.0-20250221154605-e0d63fd3e79b/go.mod h1:7D9VPN+5ZUvoX0EnI5ksmaOrXfZpF+n2bKR9DlInBAU=
github.com/gospider007/tools v0.0.0-20250226135821-5d2fbfa9054d h1:Kbzt9ceuK1OhqFwTehmjrwG38weQ9DRtJQoWsUeL8sQ=
github.com/gospider007/tools v0.0.0-20250226135821-5d2fbfa9054d/go.mod h1:7D9VPN+5ZUvoX0EnI5ksmaOrXfZpF+n2bKR9DlInBAU=
github.com/gospider007/websocket v0.0.0-20250221154625-dbca4eba1fab h1:Cqxnb3BZwwQUnx5RX4NKZGpmNjdVSWdzfVMt24GhRsc=
@@ -150,21 +143,18 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/libdns/libdns v0.2.3 h1:ba30K4ObwMGB/QTmqUxf3H4/GmUrCAIkMWejeGl12v8=
github.com/libdns/libdns v0.2.3/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=
@@ -197,6 +187,7 @@ github.com/refraction-networking/uquic v0.0.6/go.mod h1:TFgTmV/yqVCMEXVwP7z7PMAh
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
github.com/sorairolake/lzip-go v0.3.5 h1:ms5Xri9o1JBIWvOFAorYtUNik6HI3HgBTkISiqu0Cwg=
github.com/sorairolake/lzip-go v0.3.5/go.mod h1:N0KYq5iWrMXI0ZEXKXaS9hCyOjZUQdBDEIbXfoUwbdk=
@@ -234,8 +225,6 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM=
go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ=
go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -263,8 +252,6 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
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/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=

View File

@@ -12,7 +12,6 @@ import (
"strings"
"time"
"github.com/gospider007/ja3"
"github.com/gospider007/tools"
"github.com/gospider007/websocket"
"github.com/quic-go/quic-go"
@@ -43,7 +42,7 @@ type Log struct {
// Connection Management Options
type ClientOption struct {
Spec any //support []bytes,hex string,bool
Spec string
DialOption DialOption
Headers any //default headers
Jar Jar //custom cookies
@@ -62,7 +61,6 @@ type ClientOption struct {
Proxy string //proxy,support https,http,socks5
UserAgent string //headers User-Agent value
Proxys []string //proxy list,support https,http,socks5
HSpec ja3.HSpec //h2 fingerprint
MaxRetries int //try num
MaxRedirect int //redirect num ,<0 no redirect,==0 no limit
Timeout time.Duration //request timeout
@@ -96,6 +94,7 @@ type RequestOption struct {
DisProxy bool //force disable proxy
once bool
orderHeaders *OrderData //order headers
gospiderSpec *GospiderSpec
}
// Upload files with form-data,

View File

@@ -284,7 +284,12 @@ func (obj *Client) request(ctx *Response) (err error) {
if cookies != nil {
addCookie(reqs, cookies)
}
if err = ctx.option.initSpec(); err != nil {
return err
}
ctx.request = reqs
//init spec
//send req
err = obj.do(ctx)
if err != nil && err != ErrUseLastResponse {

View File

@@ -261,7 +261,7 @@ func (obj *roundTripper) dial(ctx *Response) (conn *connecotr, err error) {
}
func (obj *roundTripper) dialConnecotr(ctx *Response, conne *connecotr, h2 bool) (err error) {
if h2 {
if conne.Conn, err = http2.NewClientConn(ctx.Context(), conne.c, ctx.option.HSpec, func(err error) {
if conne.Conn, err = http2.NewClientConn(ctx.Context(), conne.c, ctx.option.gospiderSpec.H2Spec, func(err error) {
conne.forceCnl(tools.WrapError(err, "http2 client close"))
}); err != nil {
return err
@@ -276,17 +276,11 @@ func (obj *roundTripper) dialConnecotr(ctx *Response, conne *connecotr, h2 bool)
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.Spec != nil {
spec, err := ja3.CreateSpec(option.Spec)
if err != nil {
return nil, false, err
}
if len(spec.Extensions) > 0 {
if tlsConn, err := obj.dialer.addJa3Tls(ctx, netConn, getHost(req), spec, option.UtlsConfig.Clone(), option.ForceHttp1); err != nil {
return tlsConn, false, tools.WrapError(err, "add ja3 tls error")
} else {
return tlsConn, tlsConn.ConnectionState().NegotiatedProtocol == "h2", nil
}
if option.gospiderSpec.TLSSpec != nil {
if tlsConn, err := obj.dialer.addJa3Tls(ctx, netConn, getHost(req), option.gospiderSpec.TLSSpec, option.UtlsConfig.Clone(), option.ForceHttp1); err != nil {
return tlsConn, false, tools.WrapError(err, "add ja3 tls error")
} else {
return tlsConn, tlsConn.ConnectionState().NegotiatedProtocol == "h2", nil
}
}
if tlsConn, err := obj.dialer.addTls(ctx, netConn, getHost(req), option.TlsConfig.Clone(), option.ForceHttp1); err != nil {

131
sepc.go Normal file
View File

@@ -0,0 +1,131 @@
package requests
import (
"bytes"
"encoding/hex"
"errors"
"log"
"strings"
"github.com/gospider007/http2"
"github.com/gospider007/ja3"
"github.com/gospider007/tools"
)
func (obj *Spec) Map() map[string]any {
results := map[string]any{
"orderHeaders": obj.OrderHeaders,
"raw": obj.String(),
}
return results
}
func (obj *Spec) Hex() string {
return tools.Hex(obj.raw)
}
func (obj *Spec) Bytes() []byte {
return obj.raw
}
func (obj *Spec) String() string {
return tools.BytesToString(obj.raw)
}
type Spec struct {
OrderHeaders []string
raw []byte
}
func ParseSpec(raw []byte) (*Spec, error) {
i := bytes.Index(raw, []byte("\r\n\r\n"))
if i == -1 {
return nil, errors.New("not found \\r\\n")
}
rawContent := raw[:i]
orderHeaders := []string{}
for i, line := range bytes.Split(rawContent, []byte("\r\n")) {
if i == 0 {
continue
}
ols := bytes.Split(line, []byte(": "))
if len(ols) < 2 {
return nil, errors.New("not found header")
}
orderHeaders = append(orderHeaders, string(ols[0]))
}
return &Spec{
raw: raw,
OrderHeaders: orderHeaders,
}, nil
}
type GospiderSpec struct {
TLSSpec *ja3.Spec
H1Spec *Spec
H2Spec *http2.Spec
}
func ParseGospiderSpec(value string) (*GospiderSpec, error) {
specs := strings.Split(value, "@")
spec := new(GospiderSpec)
if len(specs) != 3 {
return nil, errors.New("spec format error")
}
if specs[0] != "" {
b, err := hex.DecodeString(specs[0])
if err != nil {
return nil, err
}
if spec.TLSSpec, err = ja3.ParseSpec(b); err != nil {
return nil, err
}
log.Print("发送请求:", spec.TLSSpec.CipherSuites)
}
if specs[1] != "" {
b, err := hex.DecodeString(specs[1])
if err != nil {
return nil, err
}
if spec.H1Spec, err = ParseSpec(b); err != nil {
return nil, err
}
}
if specs[2] != "" {
b, err := hex.DecodeString(specs[2])
if err != nil {
return nil, err
}
if spec.H2Spec, err = http2.ParseSpec(b); err != nil {
return nil, err
}
}
return spec, nil
}
func (obj *RequestOption) initSpec() error {
if obj.Spec == "" {
return nil
}
gospiderSpec, err := ParseGospiderSpec(obj.Spec)
if err != nil {
return err
}
obj.gospiderSpec = gospiderSpec
if gospiderSpec.H1Spec != nil {
if obj.orderHeaders == nil {
orderData := NewOrderData()
for _, key := range gospiderSpec.H1Spec.OrderHeaders {
orderData.Add(key, nil)
}
obj.orderHeaders = orderData
}
}
if gospiderSpec.H2Spec != nil {
if obj.orderHeaders == nil {
orderData := NewOrderData()
for _, key := range gospiderSpec.H2Spec.OrderHeaders {
orderData.Add(key, nil)
}
obj.orderHeaders = orderData
}
}
return nil
}

View File

@@ -4,21 +4,17 @@ import (
"log"
"testing"
"github.com/gospider007/ja3"
"github.com/gospider007/requests"
)
func TestH2(t *testing.T) {
j := "1:65536,2:0,4:6291456,6:262144|15663105|0|m,a,s,p"
j2 := "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p"
h2Spec, err := ja3.CreateHSpec(j) //create h2 spec with string
if err != nil {
t.Fatal(err)
}
// log.Print(h2Spec)
resp, err := requests.Get(nil, "https://tools.scrapfly.io/api/fp/anything", requests.RequestOption{
ClientOption: requests.ClientOption{
HSpec: h2Spec, //set h2 spec
Spec: "1603010700010006fc0303c4d7be11dc91da4dced4e4189f5ccfce7c4d05bfa760ffc50067426b7cf6d13c2045995420c14ef81f09398076f0cfc4c54fbd4cf39003a4c1d5eaf44b11e9107300207a7a130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035010006934a4a000000170000000a000c000afafa11ec001d0017001844cd00050003026832002d000201010010000e000c02683208687474702f312e31002b0007068a8a03040303001b000302000200230000000500050100000000000d0012001004030804040105030805050108060601000b00020100ff0100010000120000fe0d011a0000010001460020fc9d027aaffdd58b1dc3cca68dd6779d31e2a8c0e84e5e56199cf7a33b805e0200f05c0b63fe280a4c3f941669f883c5caeff4cbf9cf772a70355698f884f4aa40827a00862abd92dff29c79d6fd74dbf9af4eff641a61039b298ecaf1aebd5383972aa221593ea6c05627552e2302a95e8a4dc689bc6a63defcc76e864962cb287475884bfcdbb3dde4d991b6ae9d2be6e6b74d9a35c6d6bc716fd93844f7a440150a475d970b1a193d9b85a0d7e4e36094128607fb68e5a1c7f295896befe995b3874112ee0d83c75f50450e566f1429ece1df4ef5e738457bb78dcbac1a1f952e8a98c752bcd995d7d499818a499e2d2a71756f2ec07d117391aa7f42dffd890954ff370118ce29af1d81eaf815bd7d99003304ef04edfafa00010011ec04c05a9a1970304d50e28e6ac53ab7d63b0d998d5c0076c7e5210c376ca3ca481b08123eb25541aa45354105da14c6a8d6bde7bb175f9a33297919a8487ecc1563c7d10cb5f857eaf075c7a2b67a065b3d935b2a9b10f79ca7a596c3e145ae2415230055b874b730e6103ddb3cad9a6081421388ef34a8d5b8014bdbbcefd75128172878c375365a0f29071d1898072f2387eaf5bb363c1723e562943214ebb52fe21923a4221bc4fa7b1ff612007398664c520c843dc8f74e3db266858502cfcca0c1bc270f0c965058c3a6b5cefda31c615a18dee529dce593c90179538a0156481d7f5b136aa16e84a423303297badb647729195faa94c1f772aa74a4f5a62a1d9a4100f774c1f8a415d6c55c059a76416b95402de31954df3a3522812975004f74b63d113ba889563b1d31197a89c8520c0507f001c6f2b12c586cc5127406879a13084621317d027a2ccc47ca73e436580847ec04b3dd325623b00681270db6e061abfb72e2e421a0705480e35b4b99a2014ab74f270d4dd09618617cfc901f6a2742aa883b864046c9069a3ca4cfb6552e7f094d5187428a9983deb77bf79719b03a378d086e20b72644b5898af123db605f3096a62f07647d00452b416d74837064d467c9f65c1a0302c1550d710c0e34eba53b80cb34524f8f868a298724122baf64352abc530a0a145000b78b11068f27a34a0ab00ad40b0c20b0c60a257bc58c1ff0a0c919b80b1f02cbb0e563ad178d54ca3ed69547fef51e418c0b3c8027fe80c9887c518eb704a60450ab480fbea44aec8908ede9717039a33b279443f9428c2034960c92b9f94935b655292c450210cd7ee4bba25c990d2aab8da209a376826ab8b2499315f143aec0e5bf866123596ace47473dfc185f2f122744c80ddf0c8ba91bc2d5d916e12a40ee2206f1c2b3efc781aa619888c0a97ee102c0c374914663e4b9050740cc0dc839a619c23ea2208c57536b38690069cd2c52a285f127521680b0276f3c81b94b19868e8b590dac446bd352ee9abf1dca49da1250a7c234eea29fa95b06b7a55bdb6685196115d83581ec3bcb38c65a4eda21b66329366cc13d0881739195ff981df57b01ad326857cc7fa4c813151c518c32a49078c996d431887995f7f802d05a8fb5749d4ecc172e30acc040276896404bb67c5d5b95825c3c4dc6b004b784699805e67886da95ad7311c4860278e2f893aeb53b834b8f8b6bb89055367c885d62fc14d11b39070b06461a7c34b86f88b3595d25c198c9b62b3951bdc01100356233b9532c0707d5484c4ac2baf412310b99360a2a76b1d74363a7af103c058cf56b85166be9b5bca99788dd316c8e4b163277b1ca3b3807b820b0ec1b1e6080515a68780cc3ef9902acf7cd56c59d7bbaafbc5357edfc34b9281f41553cdce864fac7b44f91a9fb9c57a7b7444e6c02b96326c41c72ea18305bcb44edba64d5009d43a27ded903dd614763c86297c1cc71ab4ab3aa772c27bc0bd7a19f3c6a32b579f60b14240a760205767a6b720ef68c7ef77878070040d30907cdb98498837ac5b6ff7e931d7741e914cc83d922125b36ac028c05e7368ec9c8510e682d08322520a1cd7c33f79cc8b7703cf3302246d9d2488be79969ddc34be4020b0461b505278bf4d35023ff85c84d815d041abaa5c2e89820fba36bce5be0b06e5fd128a41e86d7041b7964d968cc347fb9c1c001d00209b0d1f6cc21ce5b6ae1ebd680b4249e7dd04037fd84ab05a3e5c4a6b8530062dfafa000100@@505249202a20485454502f322e300d0a0d0a534d0d0a0d0a00001804000000000000010001000000020000000000040060000000060004000000000408000000000000ef00010001d401250000000180000000ff82418a089d5c0b8170dc79f7df87845887a47e561cc5801f40874148b1275ad1ffb9fe749d3fd4372ed83aa4fe7efbc1fcbefff3f4a7f388e79a82a97a7b0f497f9fbef07f21659fe7e94fe6f4f61e935b4ff3f7de0fe42cb3fcff408b4148b1275ad1ad49e33505023f30408d4148b1275ad1ad5d034ca7b29f07226d61634f53224092b6b9ac1c8558d520a4b6c2ad617b5a54251f01317ad9d07f66a281b0dae053fad0321aa49d13fda992a49685340c8a6adca7e28104416e277fb521aeba0bc8b1e632586d975765c53facd8f7e8cff4a506ea5531149d4ffda97a7b0f49580b2cae05c0b814dc394761986d975765cf53e5497ca589d34d1f43aeba0c41a4c7a98f33a69a3fdf9a68fa1d75d0620d263d4c79a68fbed00177fe8d48e62b03ee697e8d48e62b1e0b1d7f46a4731581d754df5f2c7cfdf6800bbdf43aeba0c41a4c7a9841a6a8b22c5f249c754c5fbef046cfdf6800bbbf408a4148b4a549275906497f83a8f517408a4148b4a549275a93c85f86a87dcd30d25f408a4148b4a549275ad416cf023f31408a4148b4a549275a42a13f8690e4b692d49f50929bd9abfa5242cb40d25fa523b3e94f684c9f518cf73ad7b4fd7b9fefb4005dff4086aec31ec327d785b6007d286f",
},
})
// log.Print(resp.Text())

File diff suppressed because one or more lines are too long

View File

@@ -12,7 +12,7 @@ func TestHttp3(t *testing.T) {
resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{
ClientOption: requests.ClientOption{
ForceHttp3: true,
Spec: true,
Spec: "1603010700010006fc0303c4d7be11dc91da4dced4e4189f5ccfce7c4d05bfa760ffc50067426b7cf6d13c2045995420c14ef81f09398076f0cfc4c54fbd4cf39003a4c1d5eaf44b11e9107300207a7a130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035010006934a4a000000170000000a000c000afafa11ec001d0017001844cd00050003026832002d000201010010000e000c02683208687474702f312e31002b0007068a8a03040303001b000302000200230000000500050100000000000d0012001004030804040105030805050108060601000b00020100ff0100010000120000fe0d011a0000010001460020fc9d027aaffdd58b1dc3cca68dd6779d31e2a8c0e84e5e56199cf7a33b805e0200f05c0b63fe280a4c3f941669f883c5caeff4cbf9cf772a70355698f884f4aa40827a00862abd92dff29c79d6fd74dbf9af4eff641a61039b298ecaf1aebd5383972aa221593ea6c05627552e2302a95e8a4dc689bc6a63defcc76e864962cb287475884bfcdbb3dde4d991b6ae9d2be6e6b74d9a35c6d6bc716fd93844f7a440150a475d970b1a193d9b85a0d7e4e36094128607fb68e5a1c7f295896befe995b3874112ee0d83c75f50450e566f1429ece1df4ef5e738457bb78dcbac1a1f952e8a98c752bcd995d7d499818a499e2d2a71756f2ec07d117391aa7f42dffd890954ff370118ce29af1d81eaf815bd7d99003304ef04edfafa00010011ec04c05a9a1970304d50e28e6ac53ab7d63b0d998d5c0076c7e5210c376ca3ca481b08123eb25541aa45354105da14c6a8d6bde7bb175f9a33297919a8487ecc1563c7d10cb5f857eaf075c7a2b67a065b3d935b2a9b10f79ca7a596c3e145ae2415230055b874b730e6103ddb3cad9a6081421388ef34a8d5b8014bdbbcefd75128172878c375365a0f29071d1898072f2387eaf5bb363c1723e562943214ebb52fe21923a4221bc4fa7b1ff612007398664c520c843dc8f74e3db266858502cfcca0c1bc270f0c965058c3a6b5cefda31c615a18dee529dce593c90179538a0156481d7f5b136aa16e84a423303297badb647729195faa94c1f772aa74a4f5a62a1d9a4100f774c1f8a415d6c55c059a76416b95402de31954df3a3522812975004f74b63d113ba889563b1d31197a89c8520c0507f001c6f2b12c586cc5127406879a13084621317d027a2ccc47ca73e436580847ec04b3dd325623b00681270db6e061abfb72e2e421a0705480e35b4b99a2014ab74f270d4dd09618617cfc901f6a2742aa883b864046c9069a3ca4cfb6552e7f094d5187428a9983deb77bf79719b03a378d086e20b72644b5898af123db605f3096a62f07647d00452b416d74837064d467c9f65c1a0302c1550d710c0e34eba53b80cb34524f8f868a298724122baf64352abc530a0a145000b78b11068f27a34a0ab00ad40b0c20b0c60a257bc58c1ff0a0c919b80b1f02cbb0e563ad178d54ca3ed69547fef51e418c0b3c8027fe80c9887c518eb704a60450ab480fbea44aec8908ede9717039a33b279443f9428c2034960c92b9f94935b655292c450210cd7ee4bba25c990d2aab8da209a376826ab8b2499315f143aec0e5bf866123596ace47473dfc185f2f122744c80ddf0c8ba91bc2d5d916e12a40ee2206f1c2b3efc781aa619888c0a97ee102c0c374914663e4b9050740cc0dc839a619c23ea2208c57536b38690069cd2c52a285f127521680b0276f3c81b94b19868e8b590dac446bd352ee9abf1dca49da1250a7c234eea29fa95b06b7a55bdb6685196115d83581ec3bcb38c65a4eda21b66329366cc13d0881739195ff981df57b01ad326857cc7fa4c813151c518c32a49078c996d431887995f7f802d05a8fb5749d4ecc172e30acc040276896404bb67c5d5b95825c3c4dc6b004b784699805e67886da95ad7311c4860278e2f893aeb53b834b8f8b6bb89055367c885d62fc14d11b39070b06461a7c34b86f88b3595d25c198c9b62b3951bdc01100356233b9532c0707d5484c4ac2baf412310b99360a2a76b1d74363a7af103c058cf56b85166be9b5bca99788dd316c8e4b163277b1ca3b3807b820b0ec1b1e6080515a68780cc3ef9902acf7cd56c59d7bbaafbc5357edfc34b9281f41553cdce864fac7b44f91a9fb9c57a7b7444e6c02b96326c41c72ea18305bcb44edba64d5009d43a27ded903dd614763c86297c1cc71ab4ab3aa772c27bc0bd7a19f3c6a32b579f60b14240a760205767a6b720ef68c7ef77878070040d30907cdb98498837ac5b6ff7e931d7741e914cc83d922125b36ac028c05e7368ec9c8510e682d08322520a1cd7c33f79cc8b7703cf3302246d9d2488be79969ddc34be4020b0461b505278bf4d35023ff85c84d815d041abaa5c2e89820fba36bce5be0b06e5fd128a41e86d7041b7964d968cc347fb9c1c001d00209b0d1f6cc21ce5b6ae1ebd680b4249e7dd04037fd84ab05a3e5c4a6b8530062dfafa000100@@505249202a20485454502f322e300d0a0d0a534d0d0a0d0a00001804000000000000010001000000020000000000040060000000060004000000000408000000000000ef00010001d401250000000180000000ff82418a089d5c0b8170dc79f7df87845887a47e561cc5801f40874148b1275ad1ffb9fe749d3fd4372ed83aa4fe7efbc1fcbefff3f4a7f388e79a82a97a7b0f497f9fbef07f21659fe7e94fe6f4f61e935b4ff3f7de0fe42cb3fcff408b4148b1275ad1ad49e33505023f30408d4148b1275ad1ad5d034ca7b29f07226d61634f53224092b6b9ac1c8558d520a4b6c2ad617b5a54251f01317ad9d07f66a281b0dae053fad0321aa49d13fda992a49685340c8a6adca7e28104416e277fb521aeba0bc8b1e632586d975765c53facd8f7e8cff4a506ea5531149d4ffda97a7b0f49580b2cae05c0b814dc394761986d975765cf53e5497ca589d34d1f43aeba0c41a4c7a98f33a69a3fdf9a68fa1d75d0620d263d4c79a68fbed00177fe8d48e62b03ee697e8d48e62b1e0b1d7f46a4731581d754df5f2c7cfdf6800bbdf43aeba0c41a4c7a9841a6a8b22c5f249c754c5fbef046cfdf6800bbbf408a4148b4a549275906497f83a8f517408a4148b4a549275a93c85f86a87dcd30d25f408a4148b4a549275ad416cf023f31408a4148b4a549275a42a13f8690e4b692d49f50929bd9abfa5242cb40d25fa523b3e94f684c9f518cf73ad7b4fd7b9fefb4005dff4086aec31ec327d785b6007d286f",
},
},
)

View File

@@ -11,7 +11,6 @@ func TestLogger(t *testing.T) {
for i := 0; i < 2; i++ {
response, err := requests.Get(nil, "https://www.httpbin.org", requests.RequestOption{
ClientOption: requests.ClientOption{
Spec: true,
Logger: func(l requests.Log) {
log.Print(l)
},