Skip to content

Commit 998d7c8

Browse files
committed
Ignore placeholder VLESS flow values
1 parent 5a37b14 commit 998d7c8

2 files changed

Lines changed: 64 additions & 2 deletions

File tree

internal/subscription/parser.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,7 @@ func convertClashProxyToNode(proxy map[string]any) (ParsedNode, bool) {
12371237
"server_port": port,
12381238
"uuid": uuid,
12391239
}
1240-
if flow := strings.TrimSpace(getString(proxy, "flow")); flow != "" {
1240+
if flow := normalizeVLESSFlow(getString(proxy, "flow")); flow != "" {
12411241
outbound["flow"] = flow
12421242
}
12431243
setTLSFromClash(outbound, proxy, "tls")
@@ -1771,6 +1771,18 @@ func normalizeHysteriaRate(raw string) string {
17711771
return value
17721772
}
17731773

1774+
func normalizeVLESSFlow(raw string) string {
1775+
flow := strings.TrimSpace(raw)
1776+
switch strings.ToLower(flow) {
1777+
case "", "none", "null":
1778+
return ""
1779+
case "xtls-rprx-vision":
1780+
return "xtls-rprx-vision"
1781+
default:
1782+
return ""
1783+
}
1784+
}
1785+
17741786
func normalizeShadowsocksMethod(raw string) string {
17751787
method := strings.TrimSpace(raw)
17761788
if method == "" {
@@ -3112,7 +3124,7 @@ func parseVlessURI(uri string) (ParsedNode, bool) {
31123124
"server_port": port,
31133125
"uuid": uuid,
31143126
}
3115-
if flow := strings.TrimSpace(query.Get("flow")); flow != "" {
3127+
if flow := normalizeVLESSFlow(query.Get("flow")); flow != "" {
31163128
outbound["flow"] = flow
31173129
}
31183130

internal/subscription/parser_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,37 @@ func TestParseGeneralSubscription_ClashJSON_VLESSRealityOpts(t *testing.T) {
900900
}
901901
}
902902

903+
func TestParseGeneralSubscription_ClashJSON_VLESSFlowNoneIgnored(t *testing.T) {
904+
data := []byte(`{
905+
"proxies": [
906+
{
907+
"name": "vless-none-flow",
908+
"type": "vless",
909+
"server": "203.0.113.20",
910+
"port": 443,
911+
"uuid": "11111111-2222-3333-4444-555555555556",
912+
"tls": true,
913+
"flow": "None",
914+
"network": "tcp",
915+
"servername": "example.com"
916+
}
917+
]
918+
}`)
919+
920+
nodes, err := ParseGeneralSubscription(data)
921+
if err != nil {
922+
t.Fatal(err)
923+
}
924+
if len(nodes) != 1 {
925+
t.Fatalf("expected 1 parsed node, got %d", len(nodes))
926+
}
927+
928+
obj := parseNodeRaw(t, nodes[0].RawOptions)
929+
if _, exists := obj["flow"]; exists {
930+
t.Fatalf("flow should be omitted for placeholder value, got %v", obj["flow"])
931+
}
932+
}
933+
903934
func TestParseGeneralSubscription_ClashJSON_VLESSWSDropsALPN(t *testing.T) {
904935
data := []byte(`{
905936
"proxies": [
@@ -1073,6 +1104,25 @@ vless://26a1d547-b031-4139-9fc5-6671e1d0408a@example.com:443?type=tcp&security=t
10731104
}
10741105
}
10751106

1107+
func TestParseGeneralSubscription_VLESSURIFlowNoneIgnored(t *testing.T) {
1108+
data := []byte(
1109+
"vless://11111111-2222-3333-4444-555555555557@example.com:443?type=tcp&security=tls&sni=example.com&flow=None",
1110+
)
1111+
1112+
nodes, err := ParseGeneralSubscription(data)
1113+
if err != nil {
1114+
t.Fatal(err)
1115+
}
1116+
if len(nodes) != 1 {
1117+
t.Fatalf("expected 1 parsed node, got %d", len(nodes))
1118+
}
1119+
1120+
obj := parseNodeRaw(t, nodes[0].RawOptions)
1121+
if _, exists := obj["flow"]; exists {
1122+
t.Fatalf("flow should be omitted for placeholder value, got %v", obj["flow"])
1123+
}
1124+
}
1125+
10761126
func TestParseGeneralSubscription_VMess1URILine(t *testing.T) {
10771127
data := []byte(
10781128
"vmess1://11111111-2222-3333-4444-555555555555@example.com:443?network=ws&tls=true&ws.host=ws.example.com&path=%2Fws#VMESS1%20Node",

0 commit comments

Comments
 (0)