| @@ -5,6 +5,7 @@ using System.Text; | |||
| using System.Web; | |||
| using Shadowsocks.Controller; | |||
| using System.Text.RegularExpressions; | |||
| using System.Linq; | |||
| namespace Shadowsocks.Model | |||
| { | |||
| @@ -162,79 +163,81 @@ namespace Shadowsocks.Model | |||
| return server; | |||
| } | |||
| public static List<Server> GetServers(string ssURL) | |||
| public static Server ParseURL(string serverUrl) | |||
| { | |||
| var serverUrls = ssURL.Split('\r', '\n', ' '); | |||
| string _serverUrl = serverUrl.Trim(); | |||
| if (!_serverUrl.BeginWith("ss://", StringComparison.InvariantCultureIgnoreCase)) | |||
| { | |||
| return null; | |||
| } | |||
| List<Server> servers = new List<Server>(); | |||
| foreach (string serverUrl in serverUrls) | |||
| Server legacyServer = ParseLegacyURL(serverUrl); | |||
| if (legacyServer != null) //legacy | |||
| { | |||
| return legacyServer; | |||
| } | |||
| else //SIP002 | |||
| { | |||
| string _serverUrl = serverUrl.Trim(); | |||
| if (!_serverUrl.BeginWith("ss://", StringComparison.InvariantCultureIgnoreCase)) | |||
| Uri parsedUrl; | |||
| try | |||
| { | |||
| continue; | |||
| parsedUrl = new Uri(serverUrl); | |||
| } | |||
| Server legacyServer = ParseLegacyURL(serverUrl); | |||
| if (legacyServer != null) //legacy | |||
| catch (UriFormatException) | |||
| { | |||
| servers.Add(legacyServer); | |||
| return null; | |||
| } | |||
| else //SIP002 | |||
| Server server = new Server | |||
| { | |||
| Uri parsedUrl; | |||
| try | |||
| { | |||
| parsedUrl = new Uri(serverUrl); | |||
| } | |||
| catch (UriFormatException) | |||
| { | |||
| continue; | |||
| } | |||
| Server server = new Server | |||
| { | |||
| remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped), | |||
| server = parsedUrl.IdnHost, | |||
| server_port = parsedUrl.Port, | |||
| }; | |||
| // parse base64 UserInfo | |||
| string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped); | |||
| string base64 = rawUserInfo.Replace('-', '+').Replace('_', '/'); // Web-safe base64 to normal base64 | |||
| string userInfo = ""; | |||
| try | |||
| { | |||
| userInfo = Encoding.UTF8.GetString(Convert.FromBase64String( | |||
| base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))); | |||
| } | |||
| catch (FormatException) | |||
| { | |||
| continue; | |||
| } | |||
| string[] userInfoParts = userInfo.Split(new char[] { ':' }, 2); | |||
| if (userInfoParts.Length != 2) | |||
| { | |||
| continue; | |||
| } | |||
| server.method = userInfoParts[0]; | |||
| server.password = userInfoParts[1]; | |||
| NameValueCollection queryParameters = HttpUtility.ParseQueryString(parsedUrl.Query); | |||
| string[] pluginParts = (queryParameters["plugin"] ?? "").Split(new[] { ';' }, 2); | |||
| if (pluginParts.Length > 0) | |||
| { | |||
| server.plugin = pluginParts[0] ?? ""; | |||
| } | |||
| remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped), | |||
| server = parsedUrl.IdnHost, | |||
| server_port = parsedUrl.Port, | |||
| }; | |||
| // parse base64 UserInfo | |||
| string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped); | |||
| string base64 = rawUserInfo.Replace('-', '+').Replace('_', '/'); // Web-safe base64 to normal base64 | |||
| string userInfo = ""; | |||
| try | |||
| { | |||
| userInfo = Encoding.UTF8.GetString(Convert.FromBase64String( | |||
| base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))); | |||
| } | |||
| catch (FormatException) | |||
| { | |||
| return null; | |||
| } | |||
| string[] userInfoParts = userInfo.Split(new char[] { ':' }, 2); | |||
| if (userInfoParts.Length != 2) | |||
| { | |||
| return null; | |||
| } | |||
| server.method = userInfoParts[0]; | |||
| server.password = userInfoParts[1]; | |||
| if (pluginParts.Length > 1) | |||
| { | |||
| server.plugin_opts = pluginParts[1] ?? ""; | |||
| } | |||
| NameValueCollection queryParameters = HttpUtility.ParseQueryString(parsedUrl.Query); | |||
| string[] pluginParts = (queryParameters["plugin"] ?? "").Split(new[] { ';' }, 2); | |||
| if (pluginParts.Length > 0) | |||
| { | |||
| server.plugin = pluginParts[0] ?? ""; | |||
| } | |||
| servers.Add(server); | |||
| if (pluginParts.Length > 1) | |||
| { | |||
| server.plugin_opts = pluginParts[1] ?? ""; | |||
| } | |||
| return server; | |||
| } | |||
| return servers; | |||
| } | |||
| public static List<Server> GetServers(string ssURL) | |||
| { | |||
| return ssURL | |||
| .Split('\r', '\n', ' ') | |||
| .Select(u => ParseURL(u)) | |||
| .Where(s => s != null) | |||
| .ToList(); | |||
| } | |||
| public string Identifier() | |||