Skip to content

Commit 7463561

Browse files
authored
XHTTP client: Add decideHTTPVersion() and more logs
#4150 (comment)
1 parent 743435d commit 7463561

File tree

4 files changed

+69
-55
lines changed

4 files changed

+69
-55
lines changed

transport/internet/splithttp/client.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ type DialerClient interface {
3939
type DefaultDialerClient struct {
4040
transportConfig *Config
4141
client *http.Client
42-
isH2 bool
43-
isH3 bool
42+
httpVersion string
4443
// pool of net.Conn, created using dialUploadConn
4544
uploadRawPool *sync.Pool
4645
dialUploadConn func(ctxInner context.Context) (net.Conn, error)
@@ -172,7 +171,7 @@ func (c *DefaultDialerClient) SendUploadRequest(ctx context.Context, url string,
172171
req.ContentLength = contentLength
173172
req.Header = c.transportConfig.GetRequestHeader()
174173

175-
if c.isH2 || c.isH3 {
174+
if c.httpVersion != "1.1" {
176175
resp, err := c.client.Do(req)
177176
if err != nil {
178177
return err

transport/internet/splithttp/dialer.go

+57-42
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package splithttp
33
import (
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+
86106
func 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

244253
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)
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

transport/internet/splithttp/hub.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -333,30 +333,30 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
333333
Net: "unix",
334334
}, streamSettings.SocketSettings)
335335
if err != nil {
336-
return nil, errors.New("failed to listen unix domain socket(for SH) on ", address).Base(err)
336+
return nil, errors.New("failed to listen UNIX domain socket for XHTTP on ", address).Base(err)
337337
}
338-
errors.LogInfo(ctx, "listening unix domain socket(for SH) on ", address)
338+
errors.LogInfo(ctx, "listening UNIX domain socket for XHTTP on ", address)
339339
} else if l.isH3 { // quic
340340
Conn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{
341341
IP: address.IP(),
342342
Port: int(port),
343343
}, streamSettings.SocketSettings)
344344
if err != nil {
345-
return nil, errors.New("failed to listen UDP(for SH3) on ", address, ":", port).Base(err)
345+
return nil, errors.New("failed to listen UDP for XHTTP/3 on ", address, ":", port).Base(err)
346346
}
347347
h3listener, err := quic.ListenEarly(Conn, tlsConfig, nil)
348348
if err != nil {
349-
return nil, errors.New("failed to listen QUIC(for SH3) on ", address, ":", port).Base(err)
349+
return nil, errors.New("failed to listen QUIC for XHTTP/3 on ", address, ":", port).Base(err)
350350
}
351351
l.h3listener = h3listener
352-
errors.LogInfo(ctx, "listening QUIC(for SH3) on ", address, ":", port)
352+
errors.LogInfo(ctx, "listening QUIC for XHTTP/3 on ", address, ":", port)
353353

354354
l.h3server = &http3.Server{
355355
Handler: handler,
356356
}
357357
go func() {
358358
if err := l.h3server.ServeListener(l.h3listener); err != nil {
359-
errors.LogWarningInner(ctx, err, "failed to serve http3 for splithttp")
359+
errors.LogWarningInner(ctx, err, "failed to serve HTTP/3 for XHTTP/3")
360360
}
361361
}()
362362
} else { // tcp
@@ -369,9 +369,9 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
369369
Port: int(port),
370370
}, streamSettings.SocketSettings)
371371
if err != nil {
372-
return nil, errors.New("failed to listen TCP(for SH) on ", address, ":", port).Base(err)
372+
return nil, errors.New("failed to listen TCP for XHTTP on ", address, ":", port).Base(err)
373373
}
374-
errors.LogInfo(ctx, "listening TCP(for SH) on ", address, ":", port)
374+
errors.LogInfo(ctx, "listening TCP for XHTTP on ", address, ":", port)
375375
}
376376

377377
// tcp/unix (h1/h2)
@@ -397,7 +397,7 @@ func ListenSH(ctx context.Context, address net.Address, port net.Port, streamSet
397397

398398
go func() {
399399
if err := l.server.Serve(l.listener); err != nil {
400-
errors.LogWarningInner(ctx, err, "failed to serve http for splithttp")
400+
errors.LogWarningInner(ctx, err, "failed to serve HTTP for XHTTP")
401401
}
402402
}()
403403
}

transport/internet/splithttp/upload_queue.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (h *uploadQueue) Push(p Packet) error {
5252
if p.Reader != nil {
5353
p.Reader.Close()
5454
}
55-
return errors.New("splithttp packet queue closed")
55+
return errors.New("packet queue closed")
5656
}
5757

5858
h.pushedPackets <- p

0 commit comments

Comments
 (0)