@@ -10,6 +10,8 @@ import (
10
10
"sync"
11
11
"time"
12
12
13
+ "github.com/quic-go/quic-go"
14
+ "github.com/quic-go/quic-go/http3"
13
15
"github.com/xtls/xray-core/common"
14
16
"github.com/xtls/xray-core/common/buf"
15
17
"github.com/xtls/xray-core/common/errors"
@@ -50,12 +52,9 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
50
52
return client
51
53
}
52
54
53
- if browser_dialer .HasBrowserDialer () {
54
- return & BrowserDialerClient {}
55
- }
56
-
57
55
tlsConfig := tls .ConfigFromStreamSettings (streamSettings )
58
56
isH2 := tlsConfig != nil && ! (len (tlsConfig .NextProtocol ) == 1 && tlsConfig .NextProtocol [0 ] == "http/1.1" )
57
+ isH3 := tlsConfig != nil && (len (tlsConfig .NextProtocol ) == 1 && tlsConfig .NextProtocol [0 ] == "h3" )
59
58
60
59
var gotlsConfig * gotls.Config
61
60
@@ -83,10 +82,35 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
83
82
return conn , nil
84
83
}
85
84
86
- var uploadTransport http.RoundTripper
87
85
var downloadTransport http.RoundTripper
86
+ var uploadTransport http.RoundTripper
88
87
89
- if isH2 {
88
+ if isH3 {
89
+ dest .Network = net .Network_UDP
90
+ quicConfig := & quic.Config {
91
+ HandshakeIdleTimeout : 10 * time .Second ,
92
+ MaxIdleTimeout : 90 * time .Second ,
93
+ KeepAlivePeriod : 3 * time .Second ,
94
+ Allow0RTT : true ,
95
+ }
96
+ roundTripper := & http3.RoundTripper {
97
+ TLSClientConfig : gotlsConfig ,
98
+ QUICConfig : quicConfig ,
99
+ Dial : func (ctx context.Context , addr string , tlsCfg * gotls.Config , cfg * quic.Config ) (quic.EarlyConnection , error ) {
100
+ conn , err := internet .DialSystem (ctx , dest , streamSettings .SocketSettings )
101
+ if err != nil {
102
+ return nil , err
103
+ }
104
+ udpAddr , err := net .ResolveUDPAddr ("udp" , conn .RemoteAddr ().String ())
105
+ if err != nil {
106
+ return nil , err
107
+ }
108
+ return quic .DialEarly (ctx , conn .(* internet.PacketConnWrapper ).Conn .(* net.UDPConn ), udpAddr , tlsCfg , cfg )
109
+ },
110
+ }
111
+ downloadTransport = roundTripper
112
+ uploadTransport = roundTripper
113
+ } else if isH2 {
90
114
downloadTransport = & http2.Transport {
91
115
DialTLSContext : func (ctxInner context.Context , network string , addr string , cfg * gotls.Config ) (net.Conn , error ) {
92
116
return dialContext (ctxInner )
@@ -107,7 +131,6 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
107
131
// http.Client and our custom dial context.
108
132
DisableKeepAlives : true ,
109
133
}
110
-
111
134
// we use uploadRawPool for that
112
135
uploadTransport = nil
113
136
}
@@ -121,6 +144,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
121
144
Transport : uploadTransport ,
122
145
},
123
146
isH2 : isH2 ,
147
+ isH3 : isH3 ,
124
148
uploadRawPool : & sync.Pool {},
125
149
dialUploadConn : dialContext ,
126
150
}
0 commit comments