@@ -3,6 +3,7 @@ package splithttp
33import (
44 "context"
55 gotls "crypto/tls"
6+ "fmt"
67 "io"
78 "net/http"
89 "net/http/httptrace"
@@ -83,23 +84,32 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
8384 return res .Resource .(DialerClient ), res
8485}
8586
87+ func decideHTTPVersion (tlsConfig * tls.Config , realityConfig * reality.Config ) string {
88+ if realityConfig != nil {
89+ return "2"
90+ }
91+ if tlsConfig == nil {
92+ return "1.1"
93+ }
94+ if len (tlsConfig .NextProtocol ) != 1 {
95+ return "2"
96+ }
97+ if tlsConfig .NextProtocol [0 ] == "http/1.1" {
98+ return "1.1"
99+ }
100+ if tlsConfig .NextProtocol [0 ] == "h3" {
101+ return "3"
102+ }
103+ return "2"
104+ }
105+
86106func createHTTPClient (dest net.Destination , streamSettings * internet.MemoryStreamConfig ) DialerClient {
87107 tlsConfig := tls .ConfigFromStreamSettings (streamSettings )
88108 realityConfig := reality .ConfigFromStreamSettings (streamSettings )
89109
90- isH2 := false
91- isH3 := false
92-
93- if tlsConfig != nil {
94- isH2 = ! (len (tlsConfig .NextProtocol ) == 1 && tlsConfig .NextProtocol [0 ] == "http/1.1" )
95- isH3 = len (tlsConfig .NextProtocol ) == 1 && tlsConfig .NextProtocol [0 ] == "h3"
96- } else if realityConfig != nil {
97- isH2 = true
98- isH3 = false
99- }
100-
101- if isH3 {
102- dest .Network = net .Network_UDP
110+ httpVersion := decideHTTPVersion (tlsConfig , realityConfig )
111+ if httpVersion == "3" {
112+ dest .Network = net .Network_UDP // better to keep this line
103113 }
104114
105115 var gotlsConfig * gotls.Config
@@ -138,7 +148,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
138148
139149 var transport http.RoundTripper
140150
141- if isH3 {
151+ if httpVersion == "3" {
142152 if keepAlivePeriod == 0 {
143153 keepAlivePeriod = quicgoH3KeepAlivePeriod
144154 }
@@ -194,7 +204,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
194204 return quic .DialEarly (ctx , udpConn , udpAddr , tlsCfg , cfg )
195205 },
196206 }
197- } else if isH2 {
207+ } else if httpVersion == "2" {
198208 if keepAlivePeriod == 0 {
199209 keepAlivePeriod = chromeH2KeepAlivePeriod
200210 }
@@ -228,8 +238,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
228238 client : & http.Client {
229239 Transport : transport ,
230240 },
231- isH2 : isH2 ,
232- isH3 : isH3 ,
241+ httpVersion : httpVersion ,
233242 uploadRawPool : & sync.Pool {},
234243 dialUploadConn : dialContext ,
235244 }
@@ -242,16 +251,16 @@ func init() {
242251}
243252
244253func Dial (ctx context.Context , dest net.Destination , streamSettings * internet.MemoryStreamConfig ) (stat.Connection , error ) {
245- errors .LogInfo (ctx , "dialing splithttp to " , dest )
246-
247- var requestURL url.URL
248-
249- transportConfiguration := streamSettings .ProtocolSettings .(* Config )
250254 tlsConfig := tls .ConfigFromStreamSettings (streamSettings )
251255 realityConfig := reality .ConfigFromStreamSettings (streamSettings )
252256
253- scMaxEachPostBytes := transportConfiguration .GetNormalizedScMaxEachPostBytes ()
254- scMinPostsIntervalMs := transportConfiguration .GetNormalizedScMinPostsIntervalMs ()
257+ httpVersion := decideHTTPVersion (tlsConfig , realityConfig )
258+ if httpVersion == "3" {
259+ dest .Network = net .Network_UDP
260+ }
261+
262+ transportConfiguration := streamSettings .ProtocolSettings .(* Config )
263+ var requestURL url.URL
255264
256265 if tlsConfig != nil || realityConfig != nil {
257266 requestURL .Scheme = "https"
@@ -275,8 +284,21 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
275284
276285 httpClient , muxRes := getHTTPClient (ctx , dest , streamSettings )
277286
278- httpClient2 := httpClient
287+ mode := transportConfiguration .Mode
288+ if mode == "" || mode == "auto" {
289+ mode = "packet-up"
290+ if httpVersion == "2" {
291+ mode = "stream-up"
292+ }
293+ if realityConfig != nil && transportConfiguration .DownloadSettings == nil {
294+ mode = "stream-one"
295+ }
296+ }
297+
298+ errors .LogInfo (ctx , fmt .Sprintf ("XHTTP is dialing to %s, mode %s, HTTP version %s, host %s" , dest , mode , httpVersion , requestURL .Host ))
299+
279300 requestURL2 := requestURL
301+ httpClient2 := httpClient
280302 var muxRes2 * muxResource
281303 if transportConfiguration .DownloadSettings != nil {
282304 globalDialerAccess .Lock ()
@@ -286,9 +308,12 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
286308 globalDialerAccess .Unlock ()
287309 memory2 := streamSettings .DownloadSettings
288310 dest2 := * memory2 .Destination // just panic
289- httpClient2 , muxRes2 = getHTTPClient (ctx , dest2 , memory2 )
290311 tlsConfig2 := tls .ConfigFromStreamSettings (memory2 )
291312 realityConfig2 := reality .ConfigFromStreamSettings (memory2 )
313+ httpVersion2 := decideHTTPVersion (tlsConfig2 , realityConfig2 )
314+ if httpVersion2 == "3" {
315+ dest2 .Network = net .Network_UDP
316+ }
292317 if tlsConfig2 != nil || realityConfig2 != nil {
293318 requestURL2 .Scheme = "https"
294319 } else {
@@ -307,20 +332,10 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
307332 }
308333 requestURL2 .Path = config2 .GetNormalizedPath () + sessionIdUuid .String ()
309334 requestURL2 .RawQuery = config2 .GetNormalizedQuery ()
335+ httpClient2 , muxRes2 = getHTTPClient (ctx , dest2 , memory2 )
336+ errors .LogInfo (ctx , fmt .Sprintf ("XHTTP is downloading from %s, mode %s, HTTP version %s, host %s" , dest2 , "stream-down" , httpVersion2 , requestURL2 .Host ))
310337 }
311338
312- mode := transportConfiguration .Mode
313- if mode == "" || mode == "auto" {
314- mode = "packet-up"
315- if (tlsConfig != nil && (len (tlsConfig .NextProtocol ) != 1 || tlsConfig .NextProtocol [0 ] == "h2" )) || realityConfig != nil {
316- mode = "stream-up"
317- }
318- if realityConfig != nil && transportConfiguration .DownloadSettings == nil {
319- mode = "stream-one"
320- }
321- }
322- errors .LogInfo (ctx , "XHTTP is using mode: " + mode )
323-
324339 var writer io.WriteCloser
325340 var reader io.ReadCloser
326341 var remoteAddr , localAddr net.Addr
@@ -373,6 +388,9 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
373388 return stat .Connection (& conn ), nil
374389 }
375390
391+ scMaxEachPostBytes := transportConfiguration .GetNormalizedScMaxEachPostBytes ()
392+ scMinPostsIntervalMs := transportConfiguration .GetNormalizedScMinPostsIntervalMs ()
393+
376394 maxUploadSize := scMaxEachPostBytes .roll ()
377395 // WithSizeLimit(0) will still allow single bytes to pass, and a lot of
378396 // code relies on this behavior. Subtract 1 so that together with
@@ -408,10 +426,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
408426 seq += 1
409427
410428 if scMinPostsIntervalMs .From > 0 {
411- sleep := time .Duration (scMinPostsIntervalMs .roll ())* time .Millisecond - time .Since (lastWrite )
412- if sleep > 0 {
413- time .Sleep (sleep )
414- }
429+ time .Sleep (time .Duration (scMinPostsIntervalMs .roll ())* time .Millisecond - time .Since (lastWrite ))
415430 }
416431
417432 // by offloading the uploads into a buffered pipe, multiple conn.Write
0 commit comments