This commit is contained in:
gospider
2025-08-21 16:54:11 +08:00
parent d2dbece5db
commit 863dc9330c
11 changed files with 119 additions and 201 deletions

93
conn.go
View File

@@ -2,7 +2,6 @@ package requests
import (
"context"
"errors"
"net"
"net/http"
"time"
@@ -11,61 +10,24 @@ import (
"github.com/gospider007/tools"
)
func taskMain(conn http1.Conn, task *reqTask) (err error) {
defer func() {
if err != nil && task.reqCtx.option.ErrCallBack != nil {
task.reqCtx.err = err
if err2 := task.reqCtx.option.ErrCallBack(task.reqCtx); err2 != nil {
task.disRetry = true
err = err2
}
}
if err != nil {
task.cnl(err)
} else {
task.cnl(tools.ErrNoErr)
if task.reqCtx.response != nil && task.reqCtx.response.Body != nil {
if bodyContext := task.reqCtx.response.Body.(*http1.Body).Context(); bodyContext != nil {
select {
case <-task.reqCtx.Context().Done():
if context.Cause(task.reqCtx.Context()) != tools.ErrNoErr {
err = context.Cause(task.reqCtx.Context())
}
case <-bodyContext.Done():
if context.Cause(bodyContext) != tools.ErrNoErr {
err = context.Cause(bodyContext)
}
}
}
}
}
if err != nil {
conn.CloseWithError(tools.WrapError(err, "taskMain close with error"))
}
}()
select {
case <-conn.Context().Done(): //force conn close
err = context.Cause(conn.Context())
return
default:
}
func (obj *Response) doRequest(conn http1.Conn) (err error) {
var response *http.Response
if task.reqCtx.option.ResponseHeaderTimeout > 0 {
ctx, cnl := context.WithTimeout(task.reqCtx.Context(), task.reqCtx.option.ResponseHeaderTimeout)
response, err = conn.DoRequest(ctx, task.reqCtx.request, &http1.Option{OrderHeaders: task.reqCtx.option.orderHeaders.Data()})
if obj.option.ResponseHeaderTimeout > 0 {
ctx, cnl := context.WithTimeout(obj.Context(), obj.option.ResponseHeaderTimeout)
response, err = conn.DoRequest(ctx, obj.request, &http1.Option{OrderHeaders: obj.option.orderHeaders.Data()})
cnl()
} else {
response, err = conn.DoRequest(task.reqCtx.Context(), task.reqCtx.request, &http1.Option{OrderHeaders: task.reqCtx.option.orderHeaders.Data()})
response, err = conn.DoRequest(obj.Context(), obj.request, &http1.Option{OrderHeaders: obj.option.orderHeaders.Data()})
}
if err != nil {
err = tools.WrapError(err, "roundTrip error")
} else {
task.reqCtx.response = response
task.reqCtx.response.Request = task.reqCtx.request
obj.response = response
obj.response.Request = obj.request
}
if task.reqCtx.option.Logger != nil {
task.reqCtx.option.Logger(Log{
Id: task.reqCtx.requestId,
if obj.option.Logger != nil {
obj.option.Logger(Log{
Id: obj.requestId,
Time: time.Now(),
Type: LogType_ResponseHeader,
Msg: "response header",
@@ -74,41 +36,6 @@ func taskMain(conn http1.Conn, task *reqTask) (err error) {
return
}
func taskM(conn http1.Conn, task *reqTask) error {
err := taskMain(conn, task)
if err != nil {
return err
}
if task.reqCtx.response != nil && task.reqCtx.response.Close {
return tools.ErrNoErr
}
return err
}
func rwMain(conn http1.Conn, task *reqTask, tasks chan *reqTask) (err error) {
defer func() {
if err != nil && err != tools.ErrNoErr {
conn.CloseWithError(tools.WrapError(err, "rwMain close with error"))
}
}()
if err = taskM(conn, task); err != nil {
return
}
for {
select {
case <-conn.Context().Done(): //force close conn
return errors.New("connecotr force close")
case task := <-tasks: //recv task
if task == nil {
return errors.New("task is nil")
}
err = taskM(conn, task)
if err != nil {
return
}
}
}
}
func newSSHConn(sshCon net.Conn, rawCon net.Conn) *sshConn {
return &sshConn{sshCon: sshCon, rawCon: rawCon}
}

14
go.mod
View File

@@ -8,12 +8,12 @@ require (
github.com/gospider007/bs4 v0.0.0-20250815030800-a352d3ad57ee
github.com/gospider007/gson v0.0.0-20250819094627-31f516e714bd
github.com/gospider007/gtls v0.0.0-20250818100212-f466fa4cc860
github.com/gospider007/http1 v0.0.0-20250820001757-7e2103027e4b
github.com/gospider007/http2 v0.0.0-20250820001924-b6e8432bd4b1
github.com/gospider007/http3 v0.0.0-20250819094613-7dfd55495d56
github.com/gospider007/ja3 v0.0.0-20250815031055-0948dc3bbe0b
github.com/gospider007/http1 v0.0.0-20250820083711-1ab54092bd54
github.com/gospider007/http2 v0.0.0-20250820090250-584a27dfb0dc
github.com/gospider007/http3 v0.0.0-20250820090306-a29c4f3f6000
github.com/gospider007/ja3 v0.0.0-20250820090351-07b1daefd162
github.com/gospider007/re v0.0.0-20250815031101-a57caeff73bf
github.com/gospider007/tools v0.0.0-20250819094836-a81233312764
github.com/gospider007/tools v0.0.0-20250820090327-734cf60271ec
github.com/gospider007/websocket v0.0.0-20250819094917-c00c0a99815f
github.com/quic-go/quic-go v0.54.0
github.com/refraction-networking/uquic v0.0.6
@@ -44,7 +44,7 @@ require (
github.com/gobwas/ws v1.4.0 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 // indirect
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect
github.com/gospider007/blog v0.0.0-20250815030743-f2af6b9013ab // indirect
github.com/gospider007/kinds v0.0.0-20250815031133-b2282666f69c // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
@@ -62,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.24.0 // indirect
github.com/onsi/ginkgo/v2 v2.25.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

28
go.sum
View File

@@ -99,8 +99,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY=
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
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=
@@ -116,20 +116,20 @@ github.com/gospider007/gson v0.0.0-20250819094627-31f516e714bd h1:glQmHO1YxJ+dPC
github.com/gospider007/gson v0.0.0-20250819094627-31f516e714bd/go.mod h1:WAsyRFl9Ehb1Pl2Tg7bqvbE+qAjuRdljGfzxvGnBWlY=
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-20250820001757-7e2103027e4b h1:uuPDoNcnWUAlKSEjQ9d8tiQwVXnQ56ahJEbaaVZeibc=
github.com/gospider007/http1 v0.0.0-20250820001757-7e2103027e4b/go.mod h1:SX5Ely+axEItPLrKM6IMeZd5/md9IdJJXoqMdjlkpnA=
github.com/gospider007/http2 v0.0.0-20250820001924-b6e8432bd4b1 h1:Z/XBKm9wLp4NvtjskzvhFyewPPT0EVcqgjR48l9fhFw=
github.com/gospider007/http2 v0.0.0-20250820001924-b6e8432bd4b1/go.mod h1:0XYLpyiEfL9X5gsgjDX8ygftOkCL1ZvzbUkV6wGmlkc=
github.com/gospider007/http3 v0.0.0-20250819094613-7dfd55495d56 h1:/0LlX2DHVVqPQvAXDtpPaaK52wdTt8EWCuT2y/e1wOg=
github.com/gospider007/http3 v0.0.0-20250819094613-7dfd55495d56/go.mod h1:YvnqTQahyjng+BqchoNzYz8Uc/m01jLj+W5gveeBNp8=
github.com/gospider007/ja3 v0.0.0-20250815031055-0948dc3bbe0b h1:5KIC/KDX6/gqOLpFD/ZaHGjqEh5UcBWhqmS9EQVUmX8=
github.com/gospider007/ja3 v0.0.0-20250815031055-0948dc3bbe0b/go.mod h1:RL5TNXk0uuyzZhcAa33WLAIsTSc1Lo0JRsR+aarH4A0=
github.com/gospider007/http1 v0.0.0-20250820083711-1ab54092bd54 h1:W26pE++3LFAa8Pr0f0enIf0XJ9EFY/7acIa3GsOPL2Q=
github.com/gospider007/http1 v0.0.0-20250820083711-1ab54092bd54/go.mod h1:sdLxNFcD9e40HUxjhCFukalB5FDb0PBa+WKDKIYZVY8=
github.com/gospider007/http2 v0.0.0-20250820090250-584a27dfb0dc h1:q8Pwu2jd8hMvm3cYwUGfnDQiuk+qFFE1R8/5OvZT5SA=
github.com/gospider007/http2 v0.0.0-20250820090250-584a27dfb0dc/go.mod h1:nbCbZGJejScuY/tM4LHDZjwRLekCLhHvF95tezBm8YQ=
github.com/gospider007/http3 v0.0.0-20250820090306-a29c4f3f6000 h1:fsbGySDvrrIcmlScCScohyQ/78S3Yefu0V+xThPcHm4=
github.com/gospider007/http3 v0.0.0-20250820090306-a29c4f3f6000/go.mod h1:ulhfixr7vgsJqqaYUYlexbhBqLeXvdbZ6V82Enos5Mk=
github.com/gospider007/ja3 v0.0.0-20250820090351-07b1daefd162 h1:2W2Ekh4W7yX+iIN2j041xiHkhAgx47bgYkG+NSruv2Y=
github.com/gospider007/ja3 v0.0.0-20250820090351-07b1daefd162/go.mod h1:4SQvbDPFIqWokdYZ2UXLRbUZc7RCB8yX/mvbQo7PhjM=
github.com/gospider007/kinds v0.0.0-20250815031133-b2282666f69c h1:WnFZf0v+Du5nH/R3pq5QwkTcfVxLqVMRp2dPaI6w6YY=
github.com/gospider007/kinds v0.0.0-20250815031133-b2282666f69c/go.mod h1:8eAmhxyW7p81nsYlD5Wj8I0HuZpVGci+Q9wr6vfY8pg=
github.com/gospider007/re v0.0.0-20250815031101-a57caeff73bf h1:+3g9qmg+XLbYcY4vvbsDM7xHkXF+5U8V/haAYDImGTA=
github.com/gospider007/re v0.0.0-20250815031101-a57caeff73bf/go.mod h1:5fVj9OYkqlOgBdz+kH4jgdiSZ6jdfbmexLIFqtMa9v8=
github.com/gospider007/tools v0.0.0-20250819094836-a81233312764 h1:NYVqv0I6pE7yV5Enee9VOWmqjgJFZqQT66p+yZ1CwO4=
github.com/gospider007/tools v0.0.0-20250819094836-a81233312764/go.mod h1:Imryilbsdhsx+zIE+s6mIB+DNrAIig0ixupk45exsts=
github.com/gospider007/tools v0.0.0-20250820090327-734cf60271ec h1:mAZOEIJ9X9LQmH1GNhkVHEVHSZysnR0wHHpnJ9JGTiM=
github.com/gospider007/tools v0.0.0-20250820090327-734cf60271ec/go.mod h1:oDjcjXaKqctjovjRI8G7uRbU4Eve/4sj/7YxiXuM7Qo=
github.com/gospider007/websocket v0.0.0-20250819094917-c00c0a99815f h1:nyklmiKQ1vLOmC2DCPL8/RZHN22or/CFRi0xCGTiZiU=
github.com/gospider007/websocket v0.0.0-20250819094917-c00c0a99815f/go.mod h1:olruUjPKXJ74OlFipbKedfK0LMuDu/UarSWIVhEtOX4=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -177,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.24.0 h1:obZz8LAnHicNdbBqvG3ytAFx8fgza+i1IDpBVcHT2YE=
github.com/onsi/ginkgo/v2 v2.24.0/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
github.com/onsi/ginkgo/v2 v2.25.0 h1:LJu94oDZUdgnw+GD0Sk/iwG9c5Fnr1vLgMb4FUUwWxE=
github.com/onsi/ginkgo/v2 v2.25.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=

View File

@@ -73,8 +73,11 @@ type Response struct {
content []byte
proxys []*url.URL
readBodyLock sync.Mutex
connLock sync.Mutex
isNewConn bool
bodyErr error
connKey string
putOk bool
}
type SSE struct {
reader *bufio.Reader
@@ -330,28 +333,47 @@ func (obj *Response) CloseConn() {
func (obj *Response) CloseBody(err error) {
obj.closeBody(true, err)
}
func (obj *Response) closeBody(i bool, err error) {
if obj.bodyErr != io.EOF {
func (obj *Response) closeBody(i bool, err error) { // 如果关闭body这一步几乎是必须的body 所有情况都要考虑调用这个函数
if obj.bodyErr != io.EOF { //body 读取有错误
obj.CloseConn()
return
} else if i { //用户主动调用
if obj.StatusCode() == 101 && obj.webSocket == nil {
obj.CloseConn()
return
} else { //没有错误
if obj.StatusCode() == 101 { //如果为websocket
if i && obj.webSocket == nil { //用户没有启用websocket则关闭连接
obj.CloseConn()
return
}
} else {
if obj.response.Close {
obj.CloseConn()
return
}
}
}
if err == nil {
err = tools.ErrNoErr
}
if err == tools.ErrNoErr {
if err == tools.ErrNoErr { //没有错误
obj.rawBody.CloseWithError(err)
} else {
if obj.StatusCode() != 101 {
obj.PutConn()
}
} else { //有错误
obj.CloseConn()
}
obj.cnl()
}
// read body
func (obj *Response) PutConn() {
obj.connLock.Lock()
defer obj.connLock.Unlock()
if obj.putOk {
return
}
obj.putOk = true
obj.client.transport.putConnPool(obj.connKey, obj.rawBody.Conn())
}
func (obj *Response) ReadBody() (err error) {
obj.readBodyLock.Lock()
defer obj.readBodyLock.Unlock()
@@ -432,9 +454,6 @@ func (obj *body) closeWithError(i bool, err error) error {
obj.err = err
}
obj.ctx.closeBody(i, err)
if err != nil {
obj.ctx.CloseConn()
}
return obj.err
}

View File

@@ -21,21 +21,13 @@ import (
uquic "github.com/refraction-networking/uquic"
)
type reqTask struct {
ctx context.Context
cnl context.CancelCauseFunc
reqCtx *Response
disRetry bool
key string
}
func (obj *reqTask) suppertRetry() bool {
if obj.disRetry {
func (obj *Response) suppertRetry() bool {
if obj.isNewConn {
return false
}
if obj.reqCtx.request.Body == nil {
if obj.request.Body == nil {
return true
} else if body, ok := obj.reqCtx.request.Body.(io.Seeker); ok {
} else if body, ok := obj.request.Body.(io.Seeker); ok {
if i, err := body.Seek(0, io.SeekStart); i == 0 && err == nil {
return true
}
@@ -61,7 +53,7 @@ func getKey(ctx *Response) (string, error) {
type roundTripper struct {
ctx context.Context
connPools sync.Map
connPools map[string]chan http1.Conn
dialer *Dialer
lock sync.Mutex
}
@@ -73,21 +65,33 @@ func newRoundTripper(preCtx context.Context) *roundTripper {
preCtx = context.TODO()
}
return &roundTripper{
ctx: preCtx,
dialer: new(Dialer),
ctx: preCtx,
connPools: make(map[string]chan http1.Conn),
dialer: new(Dialer),
}
}
func (obj *roundTripper) getConnPool(task *reqTask) chan *reqTask {
func (obj *roundTripper) getConnPool(key string) chan http1.Conn {
obj.lock.Lock()
defer obj.lock.Unlock()
val, ok := obj.connPools.Load(task.key)
val, ok := obj.connPools[key]
if ok {
return val.(chan *reqTask)
return val
}
tasks := make(chan *reqTask)
obj.connPools.Store(task.key, tasks)
return tasks
val = make(chan http1.Conn)
obj.connPools[key] = val
return val
}
func runConn(ctx context.Context, pool chan http1.Conn, conn http1.Conn) {
select {
case pool <- conn:
case <-conn.Context().Done():
case <-ctx.Done():
conn.CloseWithError(context.Cause(ctx))
}
}
func (obj *roundTripper) putConnPool(key string, con http1.Conn) {
go runConn(obj.ctx, obj.getConnPool(key), con)
}
func (obj *roundTripper) http3Dial(ctx *Response, remtoeAddress Address, proxyAddress ...Address) (udpConn net.PacketConn, err error) {
@@ -176,7 +180,12 @@ func (obj *roundTripper) uhttp3Dial(ctx *Response, remoteAddress Address, proxyA
return
}
func (obj *roundTripper) dial(ctx *Response) (conn http1.Conn, err error) {
func (obj *roundTripper) newConn(ctx *Response) (conn http1.Conn, err error) {
defer func() {
if err != nil && conn != nil {
conn.CloseWithError(err)
}
}()
proxys, err := obj.initProxys(ctx)
if err != nil {
return nil, err
@@ -301,49 +310,6 @@ func (obj *roundTripper) initProxys(ctx *Response) ([]Address, error) {
return proxys, nil
}
func (obj *roundTripper) waitTask(task *reqTask) error {
<-task.ctx.Done()
err := context.Cause(task.ctx)
if errors.Is(err, tools.ErrNoErr) {
err = nil
}
return err
}
func (obj *roundTripper) newRoundTrip(task *reqTask) error {
task.reqCtx.isNewConn = true
conn, err := obj.dial(task.reqCtx)
if err != nil {
if conn != nil {
conn.CloseWithError(err)
}
err = tools.WrapError(err, "newRoudTrip dial error")
if task.reqCtx.option.ErrCallBack != nil {
task.reqCtx.err = err
if err2 := task.reqCtx.option.ErrCallBack(task.reqCtx); err2 != nil {
err = err2
}
}
}
if err == nil {
go rwMain(conn, task, obj.getConnPool(task))
return obj.waitTask(task)
}
return err
}
func (obj *roundTripper) newReqTask(ctx *Response) (*reqTask, error) {
task := new(reqTask)
task.reqCtx = ctx
task.reqCtx.response = nil
key, err := getKey(ctx)
if err != nil {
return nil, err
}
task.key = key
return task, nil
}
func (obj *roundTripper) RoundTrip(ctx *Response) (err error) {
if ctx.option.RequestCallBack != nil {
if err = ctx.option.RequestCallBack(ctx); err != nil {
@@ -357,30 +323,32 @@ func (obj *roundTripper) RoundTrip(ctx *Response) (err error) {
return err
}
}
var task *reqTask
ctx.connKey, err = getKey(ctx)
if err != nil {
return err
}
var conn http1.Conn
for send := true; send; {
select {
case <-ctx.Context().Done():
return context.Cause(ctx.Context())
default:
}
task, err = obj.newReqTask(ctx)
if err != nil {
return err
}
task.ctx, task.cnl = context.WithCancelCause(task.reqCtx.Context())
ctx.response = nil
select {
case obj.getConnPool(task) <- task:
err = obj.waitTask(task)
case conn = <-obj.getConnPool(ctx.connKey):
ctx.isNewConn = false
default:
err = obj.newRoundTrip(task)
task.disRetry = true
ctx.isNewConn = true
conn, err = obj.newConn(ctx)
}
task.cnl(err)
if err == nil {
break
err = ctx.doRequest(conn)
if err == nil {
break
}
}
send = task.suppertRetry()
send = ctx.suppertRetry()
}
if err == nil && ctx.option.RequestCallBack != nil {
if err2 := ctx.option.RequestCallBack(ctx); err2 != nil {

View File

@@ -9,7 +9,7 @@ import (
)
func TestHttp3(t *testing.T) {
resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{
resp, err := requests.Get(context.TODO(), "https://quic.nginx.org/", requests.RequestOption{
ForceHttp3: true,
Spec: "16030106f2010006ee03039a2b98d81139db0e128ea09eff6874549c219b543fb6dbaa7e4dbfe9e31602c620ce04c4026f019442affade7fed8ba66e022e186f77f1c670fd992f33c0143f120020aaaa130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035010006851a1a00000010000e000c02683208687474702f312e31002b000706dada03040303002d00020101000d0012001004030804040105030805050108060601001b0003020002ff0100010000230000000a000c000afafa11ec001d001700180000000e000c0000096c6f63616c686f7374003304ef04edfafa00010011ec04c06903195f3660633741f9f5ae64d05a316ac8e717582adb9e58c5c242ba306c99ca8f68c15f261245f9141812383c9265f7d0b5c44a5e0d7633f4f40ab8e820ec01bb6cc74e6ab3168e66b40cc4cd37e96e286b4080552b8b0217f786b7c1a0088fb613cc84471b17a33fbcc68db151df387907a1cf3fb14a0f45c6b84608db5b103131b537255c09559cf1940c3980a7f37959a7f95d32c49923600c76c616af238c579361e1c6a20c251d3d42a50e182ad54b1e5d54a57fe6986e64142815b9478cca8066c9bdcc0eb9022ebe05b0ebd53e7d146761d81aee41cd377611699c536a444d300c152994bfeef3cfb4736cb3d57d683269c1e3c001fba2ac220b2c993cec410f6fa5104d1bcde21c46a9b0be8ab7b51aba15f1745ebbd0a0d3a5224170b3bce456c157937e43390b733375bb96601667f5b36888f9520931bead48bae4723d9ed40af2680746e27eee4328503a280ee8846b37803d6206e0f5248bea4ca4a53ca4e1afdd2b84bce0c83260333bc9b38b86486fb48e18d1ce9187b1b6332b2f4145eca38122ac363210137f52140a57b7976b609d739844fa61f21c1e3c300f3434bc3f8b6856994847e2c9b0f20a24b976f9d552b153246db69f30d4a95301b933b0ba9d48402ddb7863cb4f1923a2c33021fd68634a387bf0f76d87f01b35b6182dd10fe9c14b8e548d7988388308b08ff1585ba18a7615737857a7c23c24ee9b3a2ab1915be18b233acd354c7c6513b8ea617a5cf299f34139756cc1df524292c43ee3364990961b2490ae204634a4461b53c95a11d214503985f27ab85bc7c179ab1ba37a828312cabea8cfc5088616386a83e566279a0a5517b60aca4ec6c30a32191dca3cbb7d33ae5087bbdbab5c42e6293b63ad8e35311d459e1ce57037e65e96283e449c3e012051d247653197834c42613ac377a950607c98cbd5a79fef948d18e99758e12d31d13231e638cfb183623346b231a443f56533d444c7204a63479e4efb34ef97597d858915a8a10a32aa78824c9d2993741176da643be1c6c4d91b6511055b098477e7a3c5b5c312cf7bb4ef5905fd741375e62c8ce942a2117bbe707fcc9871e59c0687507862f3634c871885949fce97612793a30a155e84ac503dc519816a13772c50e1167a7031cb2c8187913108f9a26e55958fd19a6e1ef18ed53a70f1c13d01d71d3b40a22413852c9982daac4ae8071966016c38a60bd5c0258c32b882740c6ed5252093c91e51c50cf037d4f5cb6ca610672710f7ca77b0a76039a9968e368a6b243ee4ca7632855cb568c73f01764c4944fc5879d2c52d7992840863c057db2efec658eeb2a73e02bd62617438d9192911bac1f6b0e55cb38255417af20000d69378c857bb278156f16a684200125906b6c22f3d505bc9e76d75fac3a009332ff98fe6baabe3941cab5271c6d2c0ebc993b944c49bd437353019d1b24d10390e45fa87ad77b329a9025933a11af2af0da44d3ed761722c94d8053242f537624113d7bc0155600573301bd2217c6c481ce63b0944b052c97bcb9d3349258257ff33cccf963a6945119ecab21c25051ce02548f642e0ec1ffd392d60facfdf76bfb7274363b62979231f4996362c85d5ba19d2cab7019750b3443565436867a53b71d875eba3282e6d0ee22076d6b97b7c6c556ae216e8bc1bc9f202ce94c763bfe9afc105fca9372dec2e286a001d00200ee8ac33f1ea3153f6b4a06ab71d21b7ce7955ce64ccfc66b7ec8077d02ffd18fe0d00fa00000100018b00206cada2aa48ee4478c40adad21f147d6bc90d13f6889a9b8a58a02536585a261f00d09306c85aab2a6e424b658f3cd9d1c46f35020839287259d3be605ff97faea0d87b9f7f96529661f08cf3f3899db8e805ee7405e2f9b6abd99bc4f6fa5f99b1ed442ebe53c5b10451c93d1221f662783efc3cc8fcf135ed935bcf02ec32251dd09705f191bd7959afbab5619d8e63cb634a259dd63d1b0e42225ae8c08b5b1620cd59d914857e9f1e8a3b7b892863bdaa05429922d75583059641468d8fc51c01e977a69d3a51d714cd5cceea9a5f404ce4a285fd6647931ed8b1c12db027328f214afdbe2c8102b46fe041b553f8670b00050005010000000044cd0005000302683200170000000b0002010000120000caca000100@@505249202a20485454502f322e300d0a0d0a534d0d0a0d0a00001804000000000000010001000000020000000000040060000000060004000000000408000000000000ef00010001d401250000000180000000ff82418aa0e41d139d09b8f3efbf87845887a47e561cc5801f40874148b1275ad1ffb9fe749d3fd4372ed83aa4fe7efbc1fcbefff3f4a7f388e79a82a97a7b0f497f9fbef07f21659fe7e94fe6f4f61e935b4ff3f7de0fe42cb3fcff408b4148b1275ad1ad49e33505023f30408d4148b1275ad1ad5d034ca7b29f07226d61634f53224092b6b9ac1c8558d520a4b6c2ad617b5a54251f01317ad9d07f66a281b0dae053fad0321aa49d13fda992a49685340c8a6adca7e28104416e277fb521aeba0bc8b1e632586d975765c53facd8f7e8cff4a506ea5531149d4ffda97a7b0f49580b2cae05c0b814dc394761986d975765cf53e5497ca589d34d1f43aeba0c41a4c7a98f33a69a3fdf9a68fa1d75d0620d263d4c79a68fbed00177fe8d48e62b03ee697e8d48e62b1e0b1d7f46a4731581d754df5f2c7cfdf6800bbdf43aeba0c41a4c7a9841a6a8b22c5f249c754c5fbef046cfdf6800bbbf408a4148b4a549275906497f83a8f517408a4148b4a549275a93c85f86a87dcd30d25f408a4148b4a549275ad416cf023f31408a4148b4a549275a42a13f8690e4b692d49f50929bd9abfa5242cb40d25fa523b3e94f684c9f518cf73ad7b4fd7b9fefb4005dff4086aec31ec327d785b6007d286f",
},
@@ -27,7 +27,7 @@ func TestHttp3(t *testing.T) {
}
func TestHttp32(t *testing.T) {
resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{
resp, err := requests.Get(context.TODO(), "https://quic.nginx.org/", requests.RequestOption{
ForceHttp3: true,
},
)

View File

@@ -12,7 +12,7 @@ import (
)
func TestHttp3(t *testing.T) {
resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{
resp, err := requests.Get(context.TODO(), "https://quic.nginx.org/", requests.RequestOption{
ForceHttp3: true,
},
)
@@ -38,7 +38,7 @@ func TestHttp3Proxy(t *testing.T) {
time.Sleep(time.Second)
// href := "https://google.com"
href := "https://cloudflare-quic.com/"
href := "https://quic.nginx.org/"
resp, err := requests.Get(context.Background(), href,
requests.RequestOption{

View File

@@ -115,8 +115,7 @@ func TestHttp3Proxy(t *testing.T) {
func TestHttp3Proxy2(t *testing.T) {
go proxyServer(proxyHost)
for range 5 {
resp, err := requests.Get(context.TODO(), "https://cloudflare-quic.com/", requests.RequestOption{
resp, err := requests.Get(context.TODO(), "https://quic.nginx.org/", requests.RequestOption{
USpec: true,
ForceHttp3: true,
// Logger: func(l requests.Log) {

View File

@@ -117,6 +117,10 @@ func TestSendJsonWithOrder(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if resp.StatusCode() != 200 {
log.Print("状态吗为:", resp.StatusCode())
t.Fatal("status code error")
}
jsonData, err := resp.Json()
if err != nil {
t.Fatal(err)

View File

@@ -86,6 +86,7 @@ func TestStreamWithConn3(t *testing.T) {
t.Fatal(err)
}
if resp.StatusCode() != 200 {
log.Print("状态吗为:",resp.StatusCode())
t.Fatal("resp.StatusCode()!= 200")
}
// body := resp.Body()

View File

@@ -50,9 +50,9 @@ 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{ForceHttp3: true})
resp, err := session.Get(nil, "https://quic.nginx.org/", requests.RequestOption{ForceHttp3: true})
if err != nil {
t.Error(err)
log.Panic(err)
}
log.Print(resp.Proto(), resp.IsNewConn())
if i == 0 {