From 4b79799175788b451eb9dbf8d27fe3c5d2fd067e Mon Sep 17 00:00:00 2001 From: DHR60 Date: Sat, 22 Nov 2025 15:29:43 +0800 Subject: [PATCH] Fix sing-box ws --- v2rayN/ServiceLib/Models/SingboxConfig.cs | 2 ++ .../Singbox/SingboxOutboundService.cs | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/v2rayN/ServiceLib/Models/SingboxConfig.cs b/v2rayN/ServiceLib/Models/SingboxConfig.cs index 6dde5e7c..cbf674fa 100644 --- a/v2rayN/ServiceLib/Models/SingboxConfig.cs +++ b/v2rayN/ServiceLib/Models/SingboxConfig.cs @@ -216,6 +216,8 @@ public class Transport4Sbox public string? idle_timeout { get; set; } public string? ping_timeout { get; set; } public bool? permit_without_stream { get; set; } + public int? max_early_data { get; set; } + public string? early_data_header_name { get; set; } } public class Headers4Sbox diff --git a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index 5188d177..04bdca48 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -364,7 +364,30 @@ public partial class CoreConfigSingboxService case nameof(ETransport.ws): transport.type = nameof(ETransport.ws); - transport.path = node.Path.IsNullOrEmpty() ? null : node.Path; + var wsPath = node.Path; + + // Parse ed parameter from path using regex + if (!wsPath.IsNullOrEmpty()) + { + var regex = new Regex(@"[?&]ed=(\d+)"); + var match = regex.Match(wsPath); + if (match.Success && int.TryParse(match.Groups[1].Value, out var edValue)) + { + transport.max_early_data = edValue; + transport.early_data_header_name = "Sec-WebSocket-Protocol"; + // Remove ed parameter from path + wsPath = regex.Replace(wsPath, ""); + // Clean up any leftover & at the beginning of query string + wsPath = wsPath.Replace("?&", "?"); + // Remove trailing ? if no parameters left + if (wsPath.EndsWith("?")) + { + wsPath = wsPath.TrimEnd('?'); + } + } + } + + transport.path = wsPath.IsNullOrEmpty() ? null : wsPath; if (node.RequestHost.IsNotEmpty()) { transport.headers = new()