@@ -3,6 +3,7 @@ package splithttp
3
3
import (
4
4
"context"
5
5
gotls "crypto/tls"
6
+ "fmt"
6
7
"io"
7
8
"net/http"
8
9
"net/http/httptrace"
@@ -83,23 +84,32 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
83
84
return res .Resource .(DialerClient ), res
84
85
}
85
86
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
+
86
106
func createHTTPClient (dest net.Destination , streamSettings * internet.MemoryStreamConfig ) DialerClient {
87
107
tlsConfig := tls .ConfigFromStreamSettings (streamSettings )
88
108
realityConfig := reality .ConfigFromStreamSettings (streamSettings )
89
109
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
103
113
}
104
114
105
115
var gotlsConfig * gotls.Config
@@ -138,7 +148,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
138
148
139
149
var transport http.RoundTripper
140
150
141
- if isH3 {
151
+ if httpVersion == "3" {
142
152
if keepAlivePeriod == 0 {
143
153
keepAlivePeriod = quicgoH3KeepAlivePeriod
144
154
}
@@ -194,7 +204,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
194
204
return quic .DialEarly (ctx , udpConn , udpAddr , tlsCfg , cfg )
195
205
},
196
206
}
197
- } else if isH2 {
207
+ } else if httpVersion == "2" {
198
208
if keepAlivePeriod == 0 {
199
209
keepAlivePeriod = chromeH2KeepAlivePeriod
200
210
}
@@ -228,8 +238,7 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
228
238
client : & http.Client {
229
239
Transport : transport ,
230
240
},
231
- isH2 : isH2 ,
232
- isH3 : isH3 ,
241
+ httpVersion : httpVersion ,
233
242
uploadRawPool : & sync.Pool {},
234
243
dialUploadConn : dialContext ,
235
244
}
@@ -242,16 +251,16 @@ func init() {
242
251
}
243
252
244
253
func 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 )
250
254
tlsConfig := tls .ConfigFromStreamSettings (streamSettings )
251
255
realityConfig := reality .ConfigFromStreamSettings (streamSettings )
252
256
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
255
264
256
265
if tlsConfig != nil || realityConfig != nil {
257
266
requestURL .Scheme = "https"
@@ -275,8 +284,21 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
275
284
276
285
httpClient , muxRes := getHTTPClient (ctx , dest , streamSettings )
277
286
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
+
279
300
requestURL2 := requestURL
301
+ httpClient2 := httpClient
280
302
var muxRes2 * muxResource
281
303
if transportConfiguration .DownloadSettings != nil {
282
304
globalDialerAccess .Lock ()
@@ -286,9 +308,12 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
286
308
globalDialerAccess .Unlock ()
287
309
memory2 := streamSettings .DownloadSettings
288
310
dest2 := * memory2 .Destination // just panic
289
- httpClient2 , muxRes2 = getHTTPClient (ctx , dest2 , memory2 )
290
311
tlsConfig2 := tls .ConfigFromStreamSettings (memory2 )
291
312
realityConfig2 := reality .ConfigFromStreamSettings (memory2 )
313
+ httpVersion2 := decideHTTPVersion (tlsConfig2 , realityConfig2 )
314
+ if httpVersion2 == "3" {
315
+ dest2 .Network = net .Network_UDP
316
+ }
292
317
if tlsConfig2 != nil || realityConfig2 != nil {
293
318
requestURL2 .Scheme = "https"
294
319
} else {
@@ -307,20 +332,10 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
307
332
}
308
333
requestURL2 .Path = config2 .GetNormalizedPath () + sessionIdUuid .String ()
309
334
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 ))
310
337
}
311
338
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
-
324
339
var writer io.WriteCloser
325
340
var reader io.ReadCloser
326
341
var remoteAddr , localAddr net.Addr
@@ -373,6 +388,9 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
373
388
return stat .Connection (& conn ), nil
374
389
}
375
390
391
+ scMaxEachPostBytes := transportConfiguration .GetNormalizedScMaxEachPostBytes ()
392
+ scMinPostsIntervalMs := transportConfiguration .GetNormalizedScMinPostsIntervalMs ()
393
+
376
394
maxUploadSize := scMaxEachPostBytes .roll ()
377
395
// WithSizeLimit(0) will still allow single bytes to pass, and a lot of
378
396
// 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
408
426
seq += 1
409
427
410
428
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 ))
415
430
}
416
431
417
432
// by offloading the uploads into a buffered pipe, multiple conn.Write
0 commit comments