From 70ddf4ecfcf30208952dda885a3f66c36c12dbc3 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 8 Nov 2025 11:14:01 +0800 Subject: [PATCH] Add allowInsecure and insecure to the shared URI https://github.com/2dust/v2rayN/issues/8267 --- v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs | 4 +- v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs | 68 ++++++++++++++++--- v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs | 15 +--- v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs | 4 +- v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs | 13 ++-- v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs | 4 +- v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs | 6 +- v2rayN/ServiceLib/Models/VmessQRCode.cs | 2 + 8 files changed, 77 insertions(+), 39 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs index f175ce82..f098b6a4 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/AnytlsFmt.cs @@ -23,7 +23,7 @@ public class AnytlsFmt : BaseFmt item.Id = rawUserInfo; var query = Utils.ParseQueryString(parsedUrl.Query); - _ = ResolveStdTransport(query, ref item); + ResolveUriQuery(query, ref item); return item; } @@ -41,7 +41,7 @@ public class AnytlsFmt : BaseFmt } var pw = item.Id; var dicQuery = new Dictionary(); - _ = GetStdTransport(item, Global.None, ref dicQuery); + ToUriQuery(item, Global.None, ref dicQuery); return ToUri(EConfigType.Anytls, item.Address, item.Port, pw, dicQuery, remark); } diff --git a/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs index 25435fce..481e183b 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs @@ -4,6 +4,8 @@ namespace ServiceLib.Handler.Fmt; public class BaseFmt { + private static readonly string[] _allowInsecureArray = new[] { "insecure", "allowInsecure", "allow_insecure", "verify" }; + protected static string GetIpv6(string address) { if (Utils.IsIpv6(address)) @@ -17,7 +19,7 @@ public class BaseFmt } } - protected static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary dicQuery) + protected static int ToUriQuery(ProfileItem item, string? securityDef, ref Dictionary dicQuery) { if (item.Flow.IsNotEmpty()) { @@ -37,11 +39,7 @@ public class BaseFmt } if (item.Sni.IsNotEmpty()) { - dicQuery.Add("sni", item.Sni); - } - if (item.Alpn.IsNotEmpty()) - { - dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); + dicQuery.Add("sni", Utils.UrlEncode(item.Sni)); } if (item.Fingerprint.IsNotEmpty()) { @@ -63,9 +61,14 @@ public class BaseFmt { dicQuery.Add("pqv", Utils.UrlEncode(item.Mldsa65Verify)); } - if (item.AllowInsecure.Equals("true")) + + if (item.StreamSecurity.Equals(Global.StreamSecurity)) { - dicQuery.Add("allowInsecure", "1"); + if (item.Alpn.IsNotEmpty()) + { + dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); + } + ToUriQueryAllowInsecure(item, ref dicQuery); } dicQuery.Add("type", item.Network.IsNotEmpty() ? item.Network : nameof(ETransport.tcp)); @@ -153,7 +156,40 @@ public class BaseFmt return 0; } - protected static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item) + protected static int ToUriQueryLite(ProfileItem item, ref Dictionary dicQuery) + { + if (item.Sni.IsNotEmpty()) + { + dicQuery.Add("sni", Utils.UrlEncode(item.Sni)); + } + if (item.Alpn.IsNotEmpty()) + { + dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); + } + + ToUriQueryAllowInsecure(item, ref dicQuery); + + return 0; + } + + private static int ToUriQueryAllowInsecure(ProfileItem item, ref Dictionary dicQuery) + { + if (item.AllowInsecure.Equals(Global.AllowInsecure.First())) + { + // Add two for compatibility + dicQuery.Add("insecure", "1"); + dicQuery.Add("allowInsecure", "1"); + } + else + { + dicQuery.Add("insecure", "0"); + dicQuery.Add("allowInsecure", "0"); + } + + return 0; + } + + protected static int ResolveUriQuery(NameValueCollection query, ref ProfileItem item) { item.Flow = GetQueryValue(query, "flow"); item.StreamSecurity = GetQueryValue(query, "security"); @@ -164,7 +200,19 @@ public class BaseFmt item.ShortId = GetQueryDecoded(query, "sid"); item.SpiderX = GetQueryDecoded(query, "spx"); item.Mldsa65Verify = GetQueryDecoded(query, "pqv"); - item.AllowInsecure = new[] { "allowInsecure", "allow_insecure", "insecure" }.Any(k => (query[k] ?? "") == "1") ? "true" : ""; + + if (_allowInsecureArray.Any(k => GetQueryDecoded(query, k) == "1")) + { + item.AllowInsecure = Global.AllowInsecure.First(); + } + else if (_allowInsecureArray.Any(k => GetQueryDecoded(query, k) == "0")) + { + item.AllowInsecure = Global.AllowInsecure.Skip(1).First(); + } + else + { + item.AllowInsecure = string.Empty; + } item.Network = GetQueryValue(query, "type", nameof(ETransport.tcp)); switch (item.Network) diff --git a/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs b/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs index ae670662..adcd3114 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs @@ -22,10 +22,8 @@ public class Hysteria2Fmt : BaseFmt item.Id = Utils.UrlDecode(url.UserInfo); var query = Utils.ParseQueryString(url.Query); - ResolveStdTransport(query, ref item); + ResolveUriQuery(query, ref item); item.Path = GetQueryDecoded(query, "obfs-password"); - item.AllowInsecure = GetQueryValue(query, "insecure") == "1" ? "true" : "false"; - item.Ports = GetQueryDecoded(query, "mport"); return item; @@ -46,20 +44,13 @@ public class Hysteria2Fmt : BaseFmt remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - if (item.Sni.IsNotEmpty()) - { - dicQuery.Add("sni", item.Sni); - } - if (item.Alpn.IsNotEmpty()) - { - dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); - } + ToUriQueryLite(item, ref dicQuery); + if (item.Path.IsNotEmpty()) { dicQuery.Add("obfs", "salamander"); dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path)); } - dicQuery.Add("insecure", item.AllowInsecure.ToLower() == "true" ? "1" : "0"); if (item.Ports.IsNotEmpty()) { dicQuery.Add("mport", Utils.UrlEncode(item.Ports.Replace(':', '-'))); diff --git a/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs index 3a4ee984..dc4794d8 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs @@ -23,7 +23,7 @@ public class TrojanFmt : BaseFmt item.Id = Utils.UrlDecode(url.UserInfo); var query = Utils.ParseQueryString(url.Query); - _ = ResolveStdTransport(query, ref item); + ResolveUriQuery(query, ref item); return item; } @@ -40,7 +40,7 @@ public class TrojanFmt : BaseFmt remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - _ = GetStdTransport(item, null, ref dicQuery); + ToUriQuery(item, null, ref dicQuery); return ToUri(EConfigType.Trojan, item.Address, item.Port, item.Id, dicQuery, remark); } diff --git a/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs index 5dcc15b1..1c5aded6 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs @@ -29,7 +29,7 @@ public class TuicFmt : BaseFmt } var query = Utils.ParseQueryString(url.Query); - ResolveStdTransport(query, ref item); + ResolveUriQuery(query, ref item); item.HeaderType = GetQueryValue(query, "congestion_control"); return item; @@ -47,15 +47,10 @@ public class TuicFmt : BaseFmt { remark = "#" + Utils.UrlEncode(item.Remarks); } + var dicQuery = new Dictionary(); - if (item.Sni.IsNotEmpty()) - { - dicQuery.Add("sni", item.Sni); - } - if (item.Alpn.IsNotEmpty()) - { - dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); - } + ToUriQueryLite(item, ref dicQuery); + dicQuery.Add("congestion_control", item.HeaderType); return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.Id}:{item.Security}", dicQuery, remark); diff --git a/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs index abf8c55a..3048b51c 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs @@ -26,7 +26,7 @@ public class VLESSFmt : BaseFmt var query = Utils.ParseQueryString(url.Query); item.Security = GetQueryValue(query, "encryption", Global.None); item.StreamSecurity = GetQueryValue(query, "security"); - _ = ResolveStdTransport(query, ref item); + ResolveUriQuery(query, ref item); return item; } @@ -52,7 +52,7 @@ public class VLESSFmt : BaseFmt { dicQuery.Add("encryption", Global.None); } - _ = GetStdTransport(item, Global.None, ref dicQuery); + ToUriQuery(item, Global.None, ref dicQuery); return ToUri(EConfigType.VLESS, item.Address, item.Port, item.Id, dicQuery, remark); } diff --git a/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs index 5892236f..e6535d6e 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs @@ -39,7 +39,8 @@ public class VmessFmt : BaseFmt tls = item.StreamSecurity, sni = item.Sni, alpn = item.Alpn, - fp = item.Fingerprint + fp = item.Fingerprint, + insecure = item.AllowInsecure.Equals(Global.AllowInsecure.First()) ? "1" : "0" }; var url = JsonUtils.Serialize(vmessQRCode); @@ -94,6 +95,7 @@ public class VmessFmt : BaseFmt item.Sni = Utils.ToString(vmessQRCode.sni); item.Alpn = Utils.ToString(vmessQRCode.alpn); item.Fingerprint = Utils.ToString(vmessQRCode.fp); + item.AllowInsecure = vmessQRCode.insecure == "1" ? Global.AllowInsecure.First() : string.Empty; return item; } @@ -118,7 +120,7 @@ public class VmessFmt : BaseFmt item.Id = Utils.UrlDecode(url.UserInfo); var query = Utils.ParseQueryString(url.Query); - ResolveStdTransport(query, ref item); + ResolveUriQuery(query, ref item); return item; } diff --git a/v2rayN/ServiceLib/Models/VmessQRCode.cs b/v2rayN/ServiceLib/Models/VmessQRCode.cs index a555aae0..f182c328 100644 --- a/v2rayN/ServiceLib/Models/VmessQRCode.cs +++ b/v2rayN/ServiceLib/Models/VmessQRCode.cs @@ -38,4 +38,6 @@ public class VmessQRCode public string alpn { get; set; } = string.Empty; public string fp { get; set; } = string.Empty; + + public string insecure { get; set; } = string.Empty; }