You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

OnlineConfigResolver.cs 2.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Threading.Tasks;
  7. using Newtonsoft.Json.Linq;
  8. using Shadowsocks.Model;
  9. namespace Shadowsocks.Controller.Service
  10. {
  11. public class OnlineConfigResolver
  12. {
  13. public static async Task<List<Server>> GetOnline(string url, IWebProxy proxy = null)
  14. {
  15. var socketsHttpHandler = new SocketsHttpHandler()
  16. {
  17. UseProxy = proxy != null,
  18. Proxy = proxy
  19. };
  20. var httpClient = new HttpClient(socketsHttpHandler)
  21. {
  22. Timeout = TimeSpan.FromSeconds(15)
  23. };
  24. string server_json = await httpClient.GetStringAsync(url);
  25. var servers = server_json.GetServers();
  26. foreach (var server in servers)
  27. {
  28. server.group = url;
  29. }
  30. return servers.ToList();
  31. }
  32. }
  33. internal static class OnlineConfigResolverEx
  34. {
  35. private static readonly string[] BASIC_FORMAT = new[] { "server", "server_port", "password", "method" };
  36. private static readonly IEnumerable<Server> EMPTY_SERVERS = Array.Empty<Server>();
  37. internal static IEnumerable<Server> GetServers(this string json) =>
  38. JToken.Parse(json).SearchJToken().AsEnumerable();
  39. private static IEnumerable<Server> SearchJArray(JArray array) =>
  40. array == null ? EMPTY_SERVERS : array.SelectMany(SearchJToken).ToList();
  41. private static IEnumerable<Server> SearchJObject(JObject obj)
  42. {
  43. if (obj == null)
  44. return EMPTY_SERVERS;
  45. if (BASIC_FORMAT.All(field => obj.ContainsKey(field)))
  46. return new[] { obj.ToObject<Server>() };
  47. var servers = new List<Server>();
  48. foreach (var kv in obj)
  49. {
  50. var token = kv.Value;
  51. servers.AddRange(SearchJToken(token));
  52. }
  53. return servers;
  54. }
  55. private static IEnumerable<Server> SearchJToken(this JToken token)
  56. {
  57. switch (token.Type)
  58. {
  59. default:
  60. return Array.Empty<Server>();
  61. case JTokenType.Object:
  62. return SearchJObject(token as JObject);
  63. case JTokenType.Array:
  64. return SearchJArray(token as JArray);
  65. }
  66. }
  67. }
  68. }