diff --git a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs index eacd170e..ee48fdf5 100644 --- a/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs +++ b/shadowsocks-csharp/Controller/Service/OnlineConfigResolver.cs @@ -3,83 +3,78 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; -using System.Text; using System.Threading.Tasks; -using NLog; -using Shadowsocks.Model; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Shadowsocks.Model; namespace Shadowsocks.Controller.Service { public class OnlineConfigResolver { - private static Logger logger = LogManager.GetCurrentClassLogger(); - public static async Task> GetOnline(string url, IWebProxy proxy = null) { - var httpClientHandler = new HttpClientHandler(); - var httpClient = new HttpClient(httpClientHandler); - httpClient.Timeout = TimeSpan.FromSeconds(15); - - if (proxy != null) + var httpClientHandler = new HttpClientHandler() { - httpClientHandler.Proxy = proxy; - } + Proxy = proxy + }; + var httpClient = new HttpClient(httpClientHandler) + { + Timeout = TimeSpan.FromSeconds(15) + }; + + string server_json = await httpClient.GetStringAsync(url); - string str = await httpClient.GetStringAsync(url); + var servers = server_json.GetServers(); - var ret = Get(str); - foreach (var item in ret) + foreach (var server in servers) { - item.group = url; + server.group = url; } - return ret; - } - public static List Get(string json) - { - var t = JToken.Parse(json); - return SearchJToken(t).ToList(); + return servers.ToList(); } + } - private static IEnumerable SearchJArray(JArray a) - { - if (a == null) return Array.Empty(); - return a.SelectMany(SearchJToken).ToList(); - } + internal static class OnlineConfigResolverEx + { + private static readonly string[] BASIC_FORMAT = new[] { "server", "server_port", "password", "method" }; + + private static readonly IEnumerable EMPTY_SERVERS = Array.Empty(); + + internal static IEnumerable GetServers(this string json) => + JToken.Parse(json).SearchJToken().AsEnumerable(); - private static IEnumerable SearchJObject(JObject o) + private static IEnumerable SearchJArray(JArray array) => + array == null ? EMPTY_SERVERS : array.SelectMany(SearchJToken).ToList(); + + private static IEnumerable SearchJObject(JObject obj) { - var l = new List(); - if (o == null) return l; - if (IsServerObject(o)) - return new List { o.ToObject() }; + if (obj == null) + return EMPTY_SERVERS; + + if (BASIC_FORMAT.All(field => obj.ContainsKey(field))) + return new[] { obj.ToObject() }; - foreach (var kv in o) + var servers = new List(); + foreach (var kv in obj) { - JToken v = kv.Value; - l.AddRange(SearchJToken(v)); + var token = kv.Value; + servers.AddRange(SearchJToken(token)); } - return l; + return servers; } - private static IEnumerable SearchJToken(JToken t) + private static IEnumerable SearchJToken(this JToken token) { - switch (t.Type) + switch (token.Type) { default: return Array.Empty(); case JTokenType.Object: - return SearchJObject(t as JObject); + return SearchJObject(token as JObject); case JTokenType.Array: - return SearchJArray(t as JArray); + return SearchJArray(token as JArray); } } - - private static bool IsServerObject(JObject o) - { - return new[] { "server", "server_port", "password", "method" }.All(i => o.ContainsKey(i)); - } } }