Skip to content

Commit c7c2a50

Browse files
committed
Fix missing default http2 and socket presets
1 parent 03bc923 commit c7c2a50

File tree

4 files changed

+156
-1
lines changed

4 files changed

+156
-1
lines changed

engine_params_experimental_options.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,18 @@ func (p EngineParams) SetUseDnsHttpsSvcb(enable bool) error {
7474
"enable": enable,
7575
})
7676
}
77+
78+
func (p EngineParams) SetHTTP2Options(sessionMaxReceiveWindowSize, initialWindowSize int) error {
79+
return p.SetExperimentalOption("HTTP2Options", map[string]any{
80+
"session_max_recv_window_size": sessionMaxReceiveWindowSize,
81+
"initial_window_size": initialWindowSize,
82+
})
83+
}
84+
85+
func (p EngineParams) SetSocketPoolOptions(maxPerPool, maxPerProxyChain, maxPerGroup int) error {
86+
return p.SetExperimentalOption("SocketPoolOptions", map[string]any{
87+
"max_sockets_per_pool": maxPerPool,
88+
"max_sockets_per_proxy_chain": maxPerProxyChain,
89+
"max_sockets_per_group": maxPerGroup,
90+
})
91+
}

naive_client.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,18 @@ func (c *NaiveClient) Start() error {
351351
}
352352
}
353353

354+
if !c.quicEnabled {
355+
startError = params.SetHTTP2Options(134217728, 67108864) // 128 MB session, 64 MB stream
356+
if startError != nil {
357+
return startError
358+
}
359+
}
360+
361+
startError = params.SetSocketPoolOptions(2048, 2048, 2040)
362+
if startError != nil {
363+
return startError
364+
}
365+
354366
engine.StartWithParams(params)
355367
params.Destroy()
356368

naiveproxy

test/experimental_options_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package test
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
11+
cronet "github.com/sagernet/cronet-go"
12+
M "github.com/sagernet/sing/common/metadata"
13+
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
func TestHTTP2Options(t *testing.T) {
18+
const (
19+
sessionMaxReceiveWindowSize = 134217728
20+
streamInitialWindowSize = 67108864
21+
defaultHTTP2InitialWindowSize = 65535
22+
)
23+
24+
env := setupTestEnv(t)
25+
client := env.newNaiveClient(t, cronet.NaiveClientOptions{
26+
DNSResolver: localhostDNSResolver(t),
27+
})
28+
29+
startEchoServer(t, 18100)
30+
31+
netLogPath := filepath.Join(t.TempDir(), "http2_options_netlog.json")
32+
require.True(t, client.Engine().StartNetLogToFile(netLogPath, true),
33+
"Failed to start NetLog")
34+
35+
conn, err := client.DialEarly(M.ParseSocksaddrHostPort("127.0.0.1", 18100))
36+
require.NoError(t, err)
37+
38+
testData := []byte("hello")
39+
_, err = conn.Write(testData)
40+
require.NoError(t, err)
41+
42+
buffer := make([]byte, len(testData))
43+
_, err = io.ReadFull(conn, buffer)
44+
require.NoError(t, err)
45+
require.Equal(t, testData, buffer)
46+
47+
conn.Close()
48+
client.Engine().StopNetLog()
49+
50+
logContent, err := os.ReadFile(netLogPath)
51+
require.NoError(t, err)
52+
logString := string(logContent)
53+
54+
var netLog struct {
55+
Constants struct {
56+
LogEventTypes map[string]int `json:"logEventTypes"`
57+
} `json:"constants"`
58+
Events []struct {
59+
Type int `json:"type"`
60+
Params json.RawMessage `json:"params"`
61+
} `json:"events"`
62+
}
63+
err = json.Unmarshal(logContent, &netLog)
64+
require.NoError(t, err)
65+
66+
// HTTP2_SESSION_SEND_SETTINGS should contain SETTINGS_INITIAL_WINDOW_SIZE =
67+
// 67108864 (64 MB, naive default).
68+
sendSettingsType, ok := netLog.Constants.LogEventTypes["HTTP2_SESSION_SEND_SETTINGS"]
69+
require.True(t, ok, "expected HTTP2_SESSION_SEND_SETTINGS in NetLog constants")
70+
sendSettingsFound := false
71+
for _, event := range netLog.Events {
72+
if event.Type == sendSettingsType {
73+
sendSettingsFound = true
74+
break
75+
}
76+
}
77+
require.True(t, sendSettingsFound, "expected HTTP2_SESSION_SEND_SETTINGS event in netlog")
78+
require.Contains(t, logString,
79+
fmt.Sprintf("SETTINGS_INITIAL_WINDOW_SIZE) value:%d]", streamInitialWindowSize),
80+
"expected SETTINGS_INITIAL_WINDOW_SIZE = 64 MB in HTTP/2 SETTINGS")
81+
82+
// HTTP2_SESSION_SEND_WINDOW_UPDATE with stream_id 0 should carry
83+
// delta = session_max_recv_window_size - default_initial_window_size.
84+
sendWindowUpdateType, ok := netLog.Constants.LogEventTypes["HTTP2_SESSION_SEND_WINDOW_UPDATE"]
85+
require.True(t, ok, "expected HTTP2_SESSION_SEND_WINDOW_UPDATE in NetLog constants")
86+
expectedSessionWindowDelta := sessionMaxReceiveWindowSize - defaultHTTP2InitialWindowSize
87+
sessionWindowUpdateFound := false
88+
for _, event := range netLog.Events {
89+
if event.Type != sendWindowUpdateType {
90+
continue
91+
}
92+
93+
var params struct {
94+
StreamID *int `json:"stream_id"`
95+
Delta *int `json:"delta"`
96+
}
97+
err = json.Unmarshal(event.Params, &params)
98+
require.NoError(t, err)
99+
100+
if params.StreamID != nil &&
101+
params.Delta != nil &&
102+
*params.StreamID == 0 &&
103+
*params.Delta == expectedSessionWindowDelta {
104+
sessionWindowUpdateFound = true
105+
break
106+
}
107+
}
108+
require.True(t, sessionWindowUpdateFound,
109+
"expected session WINDOW_UPDATE event with stream_id=0 and delta=%d", expectedSessionWindowDelta)
110+
}
111+
112+
func TestSocketPoolOptions(t *testing.T) {
113+
params := cronet.NewEngineParams()
114+
defer params.Destroy()
115+
116+
err := params.SetSocketPoolOptions(2048, 2048, 2040)
117+
require.NoError(t, err)
118+
119+
options := params.ExperimentalOptions()
120+
require.Contains(t, options, `"SocketPoolOptions"`,
121+
"expected SocketPoolOptions key, got: %s", options)
122+
require.Contains(t, options, `"max_sockets_per_pool":2048`,
123+
"expected max_sockets_per_pool in options, got: %s", options)
124+
require.Contains(t, options, `"max_sockets_per_proxy_chain":2048`,
125+
"expected max_sockets_per_proxy_chain in options, got: %s", options)
126+
require.Contains(t, options, `"max_sockets_per_group":2040`,
127+
"expected max_sockets_per_group in options, got: %s", options)
128+
}

0 commit comments

Comments
 (0)