Fix h1 and h2

This commit is contained in:
Fangliding
2026-06-24 16:16:52 +08:00
parent 518a7efac2
commit e0efc13c6e
+62 -36
View File
@@ -2,6 +2,7 @@ package geodata
import ( import (
"context" "context"
"crypto/tls"
go_errors "errors" go_errors "errors"
"io" "io"
"net/http" "net/http"
@@ -17,6 +18,7 @@ import (
"github.com/xtls/xray-core/common/utils" "github.com/xtls/xray-core/common/utils"
"github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/transport/internet/tagged" "github.com/xtls/xray-core/transport/internet/tagged"
"golang.org/x/net/http2"
) )
const idleTimeout = 30 * time.Second const idleTimeout = 30 * time.Second
@@ -27,8 +29,9 @@ type stage struct {
} }
type downloader struct { type downloader struct {
ctx context.Context ctx context.Context
client *http.Client httpClient *http.Client
httpsClient *http.Client
} }
type idleConn struct { type idleConn struct {
@@ -54,12 +57,13 @@ func (c *idleConn) Write(b []byte) (int, error) {
func newDownloader(ctx context.Context, dispatcher routing.Dispatcher, outbound string) *downloader { func newDownloader(ctx context.Context, dispatcher routing.Dispatcher, outbound string) *downloader {
return &downloader{ return &downloader{
ctx: ctx, ctx: ctx,
client: newClient(ctx, dispatcher, outbound), httpClient: newClient(ctx, dispatcher, outbound, false),
httpsClient: newClient(ctx, dispatcher, outbound, true),
} }
} }
func newClient(baseCtx context.Context, dispatcher routing.Dispatcher, outbound string) *http.Client { func newClient(baseCtx context.Context, dispatcher routing.Dispatcher, outbound string, isHTTPS bool) *http.Client {
dial := func(ctx context.Context, network, address string) (net.Conn, error) { dial := func(ctx context.Context, network, address string) (net.Conn, error) {
var conn net.Conn var conn net.Conn
err := task.Run(ctx, func() error { err := task.Run(ctx, func() error {
@@ -84,37 +88,53 @@ func newClient(baseCtx context.Context, dispatcher routing.Dispatcher, outbound
Conn: conn, Conn: conn,
}, nil }, nil
} }
return &http.Client{ if isHTTPS {
Transport: &http.Transport{ return &http.Client{
Proxy: nil, Transport: &http2.Transport{
DisableKeepAlives: true, DialTLSContext: func(ctx context.Context, network string, address string, cfg *tls.Config) (net.Conn, error) {
DialContext: dial, conn, err := dial(ctx, network, address)
DialTLSContext: func(ctx context.Context, network, address string) (net.Conn, error) { if err != nil {
conn, err := dial(ctx, network, address) return nil, err
if err != nil { }
return nil, err host, _, _ := net.SplitHostPort(address)
} tlsConn := utls.UClient(conn, &utls.Config{ServerName: host}, utls.HelloChrome_Auto)
host, _, _ := net.SplitHostPort(address) handshakeCtx, cancel := context.WithTimeout(ctx, idleTimeout)
tlsConn := utls.UClient(conn, &utls.Config{ServerName: host}, utls.HelloChrome_Auto) defer cancel()
handshakeCtx, cancel := context.WithTimeout(ctx, idleTimeout) if err := tlsConn.HandshakeContext(handshakeCtx); err != nil {
defer cancel() conn.Close()
if err := tlsConn.HandshakeContext(handshakeCtx); err != nil { return nil, err
conn.Close() }
return nil, err return tlsConn, nil
} },
return tlsConn, nil
}, },
ResponseHeaderTimeout: idleTimeout, CheckRedirect: func(req *http.Request, via []*http.Request) error {
}, if req.URL.Scheme != "https" {
CheckRedirect: func(req *http.Request, via []*http.Request) error { return errors.New("redirected to non-https URL: ", req.URL.String())
if req.URL.Scheme != "https" { }
return errors.New("redirected to non-https URL: ", req.URL.String()) if len(via) >= 10 {
} return errors.New("stopped after 10 redirects")
if len(via) >= 10 { }
return errors.New("stopped after 10 redirects") return nil
} },
return nil }
}, } else {
return &http.Client{
Transport: &http.Transport{
Proxy: nil,
DisableKeepAlives: true,
DialContext: dial,
ResponseHeaderTimeout: idleTimeout,
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if req.URL.Scheme != "https" {
return errors.New("redirected to non-https URL: ", req.URL.String())
}
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
return nil
},
}
} }
} }
@@ -176,7 +196,13 @@ func (d *downloader) fetch(rawURL string, writer io.Writer) error {
} }
utils.TryDefaultHeadersWith(req.Header, "nav") utils.TryDefaultHeadersWith(req.Header, "nav")
resp, err := d.client.Do(req) var client *http.Client
if req.URL.Scheme == "https" {
client = d.httpsClient
} else {
client = d.httpClient
}
resp, err := client.Do(req)
if err != nil { if err != nil {
return err return err
} }