using System.Collections.Specialized; namespace ServiceLib.Handler.Fmt { public class BaseFmt { protected static string GetIpv6(string address) { if (Utils.IsIpv6(address)) { // 检查地址是否已经被方括号包围,如果没有,则添加方括号 return address.StartsWith('[') && address.EndsWith(']') ? address : $"[{address}]"; } return address; // 如果不是IPv6地址,直接返回原地址 } protected static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary dicQuery) { if (Utils.IsNotEmpty(item.Flow)) { dicQuery.Add("flow", item.Flow); } if (Utils.IsNotEmpty(item.StreamSecurity)) { dicQuery.Add("security", item.StreamSecurity); } else { if (securityDef != null) { dicQuery.Add("security", securityDef); } } if (Utils.IsNotEmpty(item.Sni)) { dicQuery.Add("sni", item.Sni); } if (Utils.IsNotEmpty(item.Alpn)) { dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); } if (Utils.IsNotEmpty(item.Fingerprint)) { dicQuery.Add("fp", Utils.UrlEncode(item.Fingerprint)); } if (Utils.IsNotEmpty(item.PublicKey)) { dicQuery.Add("pbk", Utils.UrlEncode(item.PublicKey)); } if (Utils.IsNotEmpty(item.ShortId)) { dicQuery.Add("sid", Utils.UrlEncode(item.ShortId)); } if (Utils.IsNotEmpty(item.SpiderX)) { dicQuery.Add("spx", Utils.UrlEncode(item.SpiderX)); } if (item.AllowInsecure.Equals("true")) { dicQuery.Add("allowInsecure", "1"); } dicQuery.Add("type", Utils.IsNotEmpty(item.Network) ? item.Network : nameof(ETransport.tcp)); switch (item.Network) { case nameof(ETransport.tcp): dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None); if (Utils.IsNotEmpty(item.RequestHost)) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } break; case nameof(ETransport.kcp): dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None); if (Utils.IsNotEmpty(item.Path)) { dicQuery.Add("seed", Utils.UrlEncode(item.Path)); } break; case nameof(ETransport.ws): case nameof(ETransport.httpupgrade): if (Utils.IsNotEmpty(item.RequestHost)) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } if (Utils.IsNotEmpty(item.Path)) { dicQuery.Add("path", Utils.UrlEncode(item.Path)); } break; case nameof(ETransport.xhttp): if (Utils.IsNotEmpty(item.RequestHost)) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } if (Utils.IsNotEmpty(item.Path)) { dicQuery.Add("path", Utils.UrlEncode(item.Path)); } if (Utils.IsNotEmpty(item.HeaderType) && Global.XhttpMode.Contains(item.HeaderType)) { dicQuery.Add("mode", Utils.UrlEncode(item.HeaderType)); } if (Utils.IsNotEmpty(item.Extra)) { dicQuery.Add("extra", Utils.UrlEncode(item.Extra)); } break; case nameof(ETransport.http): case nameof(ETransport.h2): dicQuery["type"] = nameof(ETransport.http); if (Utils.IsNotEmpty(item.RequestHost)) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } if (Utils.IsNotEmpty(item.Path)) { dicQuery.Add("path", Utils.UrlEncode(item.Path)); } break; case nameof(ETransport.quic): dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None); dicQuery.Add("quicSecurity", Utils.UrlEncode(item.RequestHost)); dicQuery.Add("key", Utils.UrlEncode(item.Path)); break; case nameof(ETransport.grpc): if (Utils.IsNotEmpty(item.Path)) { dicQuery.Add("authority", Utils.UrlEncode(item.RequestHost)); dicQuery.Add("serviceName", Utils.UrlEncode(item.Path)); if (item.HeaderType is Global.GrpcGunMode or Global.GrpcMultiMode) { dicQuery.Add("mode", Utils.UrlEncode(item.HeaderType)); } } break; } return 0; } protected static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item) { item.Flow = query["flow"] ?? ""; item.StreamSecurity = query["security"] ?? ""; item.Sni = query["sni"] ?? ""; item.Alpn = Utils.UrlDecode(query["alpn"] ?? ""); item.Fingerprint = Utils.UrlDecode(query["fp"] ?? ""); item.PublicKey = Utils.UrlDecode(query["pbk"] ?? ""); item.ShortId = Utils.UrlDecode(query["sid"] ?? ""); item.SpiderX = Utils.UrlDecode(query["spx"] ?? ""); item.AllowInsecure = (query["allowInsecure"] ?? "") == "1" ? "true" : ""; item.Network = query["type"] ?? nameof(ETransport.tcp); switch (item.Network) { case nameof(ETransport.tcp): item.HeaderType = query["headerType"] ?? Global.None; item.RequestHost = Utils.UrlDecode(query["host"] ?? ""); break; case nameof(ETransport.kcp): item.HeaderType = query["headerType"] ?? Global.None; item.Path = Utils.UrlDecode(query["seed"] ?? ""); break; case nameof(ETransport.ws): case nameof(ETransport.httpupgrade): item.RequestHost = Utils.UrlDecode(query["host"] ?? ""); item.Path = Utils.UrlDecode(query["path"] ?? "/"); break; case nameof(ETransport.xhttp): item.RequestHost = Utils.UrlDecode(query["host"] ?? ""); item.Path = Utils.UrlDecode(query["path"] ?? "/"); item.HeaderType = Utils.UrlDecode(query["mode"] ?? ""); item.Extra = Utils.UrlDecode(query["extra"] ?? ""); break; case nameof(ETransport.http): case nameof(ETransport.h2): item.Network = nameof(ETransport.h2); item.RequestHost = Utils.UrlDecode(query["host"] ?? ""); item.Path = Utils.UrlDecode(query["path"] ?? "/"); break; case nameof(ETransport.quic): item.HeaderType = query["headerType"] ?? Global.None; item.RequestHost = query["quicSecurity"] ?? Global.None; item.Path = Utils.UrlDecode(query["key"] ?? ""); break; case nameof(ETransport.grpc): item.RequestHost = Utils.UrlDecode(query["authority"] ?? ""); item.Path = Utils.UrlDecode(query["serviceName"] ?? ""); item.HeaderType = Utils.UrlDecode(query["mode"] ?? Global.GrpcGunMode); break; default: break; } return 0; } protected static bool Contains(string str, params string[] s) { foreach (var item in s) { if (str.Contains(item, StringComparison.OrdinalIgnoreCase)) return true; } return false; } protected static string WriteAllText(string strData, string ext = "json") { var fileName = Utils.GetTempPath($"{Utils.GetGuid(false)}.{ext}"); File.WriteAllText(fileName, strData); return fileName; } protected static string ToUri(EConfigType eConfigType, string address, object port, string userInfo, Dictionary? dicQuery, string? remark) { var query = dicQuery != null ? ("?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray())) : string.Empty; var url = $"{Utils.UrlEncode(userInfo)}@{GetIpv6(address)}:{port}"; return $"{Global.ProtocolShares[eConfigType]}{url}{query}{remark}"; } } }