mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-08 13:35:01 +03:00
fix(singbox): keep the ws path query when removing ed (#10548)
Removing "?ed=2048" from a WebSocket path also removed the '?', so "/ws?ed=2048&key=value" was sent to sing-box as "/ws&key=value". Match "ed" without the separator in front of it and trim the leftover '&' or '?' instead.
This commit is contained in:
@@ -817,4 +817,29 @@ public class CoreConfigSingboxServiceTests
|
||||
await proxyOutbound.method.Should().BeEqualTo("aes-128-gcm");
|
||||
await proxyOutbound.password.Should().BeEqualTo("custom_password");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Arguments("/ws?ed=2048", "/ws")]
|
||||
[Arguments("/ws?ed=2048&key=value", "/ws?key=value")]
|
||||
[Arguments("/ws?key=value&ed=2048", "/ws?key=value")]
|
||||
[Arguments("/ws?a=1&ed=2048&b=2", "/ws?a=1&b=2")]
|
||||
public async Task GenerateClientConfigContent_WsEarlyDataInPath_ShouldKeepRemainingQuery(string path, string expectedPath)
|
||||
{
|
||||
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
|
||||
CoreConfigTestFactory.BindAppManagerConfig(config);
|
||||
var node = CoreConfigTestFactory.CreateVmessNode(ECoreType.sing_box);
|
||||
node.Network = nameof(ETransport.ws);
|
||||
node.SetTransportExtra(node.GetTransportExtra() with { Path = path });
|
||||
var context = CoreConfigTestFactory.CreateContext(config, node, ECoreType.sing_box);
|
||||
|
||||
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
|
||||
|
||||
await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
|
||||
var cfg = JsonUtils.Deserialize<SingboxConfig>(result.Data!.ToString())!;
|
||||
var transport = cfg.outbounds.First(o => o.tag == Global.ProxyTag).transport;
|
||||
await transport.Should().NotBeNull();
|
||||
await transport!.max_early_data.Should().BeEqualTo(2048);
|
||||
await transport.early_data_header_name.Should().BeEqualTo("Sec-WebSocket-Protocol");
|
||||
await transport.path.Should().BeEqualTo(expectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +542,9 @@ public partial class CoreConfigSingboxService
|
||||
// Parse eh and ed parameters from path using regex
|
||||
if (!wsPath.IsNullOrEmpty())
|
||||
{
|
||||
var edRegex = new Regex(@"[?&]ed=(\d+)");
|
||||
// Keep the '?' or '&' in front of "ed" out of the match, so removing it
|
||||
// leaves "/ws?ed=2048&key=value" as "/ws?key=value", not "/ws&key=value".
|
||||
var edRegex = new Regex(@"(?<=[?&])ed=(\d+)&?");
|
||||
var edMatch = edRegex.Match(wsPath);
|
||||
if (edMatch.Success && int.TryParse(edMatch.Groups[1].Value, out var edValue))
|
||||
{
|
||||
@@ -550,11 +552,7 @@ public partial class CoreConfigSingboxService
|
||||
transport.early_data_header_name = "Sec-WebSocket-Protocol";
|
||||
|
||||
wsPath = edRegex.Replace(wsPath, "");
|
||||
wsPath = wsPath.Replace("?&", "?");
|
||||
if (wsPath.EndsWith('?'))
|
||||
{
|
||||
wsPath = wsPath.TrimEnd('?');
|
||||
}
|
||||
wsPath = wsPath.TrimEnd('&').TrimEnd('?');
|
||||
}
|
||||
|
||||
var ehRegex = new Regex(@"[?&]eh=([^&]+)");
|
||||
|
||||
Reference in New Issue
Block a user