GithubMetaProvider.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using Microsoft.Extensions.DependencyInjection;
  2. using Microsoft.Extensions.Logging;
  3. using Microsoft.Extensions.Options;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Net.Http;
  8. using System.Net.Http.Json;
  9. using System.Net.Sockets;
  10. using System.Text.Json.Serialization;
  11. using System.Threading.Tasks;
  12. namespace FastGithub.Scanner.DomainAddressProviders
  13. {
  14. /// <summary>
  15. /// Github公开的域名与ip关系提供者
  16. /// </summary>
  17. [Service(ServiceLifetime.Singleton, ServiceType = typeof(IDomainAddressProvider))]
  18. sealed class GithubMetaProvider : IDomainAddressProvider
  19. {
  20. private readonly IOptionsMonitor<GithubOptions> options;
  21. private readonly IHttpClientFactory httpClientFactory;
  22. private readonly ILogger<GithubMetaProvider> logger;
  23. private const string META_URI = "https://api.github.com/meta";
  24. /// <summary>
  25. /// 获取排序
  26. /// </summary>
  27. public int Order => int.MaxValue;
  28. /// <summary>
  29. /// Github公开的域名与ip关系提供者
  30. /// </summary>
  31. /// <param name="options"></param>
  32. /// <param name="logger"></param>
  33. public GithubMetaProvider(
  34. IOptionsMonitor<GithubOptions> options,
  35. IHttpClientFactory httpClientFactory,
  36. ILogger<GithubMetaProvider> logger)
  37. {
  38. this.options = options;
  39. this.httpClientFactory = httpClientFactory;
  40. this.logger = logger;
  41. }
  42. /// <summary>
  43. /// 创建域名与ip的关系
  44. /// </summary>
  45. /// <returns></returns>
  46. public async Task<IEnumerable<DomainAddress>> CreateDomainAddressesAsync()
  47. {
  48. var setting = this.options.CurrentValue.DominAddressProviders.GithubMetaProvider;
  49. if (setting.Enable == false)
  50. {
  51. return Enumerable.Empty<DomainAddress>();
  52. }
  53. try
  54. {
  55. var httpClient = this.httpClientFactory.CreateClient(nameof(FastGithub));
  56. var meta = await this.GetMetaAsync(httpClient, setting.MetaUri);
  57. if (meta != null)
  58. {
  59. return meta.ToDomainAddresses();
  60. }
  61. }
  62. catch (Exception ex)
  63. {
  64. this.logger.LogWarning($"加载远程的ip列表异常:{ex.Message}");
  65. }
  66. return Enumerable.Empty<DomainAddress>();
  67. }
  68. /// <summary>
  69. /// 尝试获取meta
  70. /// </summary>
  71. /// <param name="httpClient"></param>
  72. /// <param name="metaUri"></param>
  73. /// <returns></returns>
  74. private async Task<Meta?> GetMetaAsync(HttpClient httpClient, Uri metaUri)
  75. {
  76. try
  77. {
  78. return await httpClient.GetFromJsonAsync<Meta>(META_URI);
  79. }
  80. catch (Exception)
  81. {
  82. return await httpClient.GetFromJsonAsync<Meta>(metaUri);
  83. }
  84. }
  85. /// <summary>
  86. /// github的meta结构
  87. /// </summary>
  88. private class Meta
  89. {
  90. [JsonPropertyName("web")]
  91. public string[] Web { get; set; } = Array.Empty<string>();
  92. [JsonPropertyName("api")]
  93. public string[] Api { get; set; } = Array.Empty<string>();
  94. /// <summary>
  95. /// 转换为域名与ip关系
  96. /// </summary>
  97. /// <returns></returns>
  98. public IEnumerable<DomainAddress> ToDomainAddresses()
  99. {
  100. foreach (var range in IPAddressRange.From(this.Web).OrderBy(item => item.Size))
  101. {
  102. if (range.AddressFamily == AddressFamily.InterNetwork)
  103. {
  104. foreach (var address in range)
  105. {
  106. yield return new DomainAddress("github.com", address);
  107. }
  108. }
  109. }
  110. foreach (var range in IPAddressRange.From(this.Api).OrderBy(item => item.Size))
  111. {
  112. if (range.AddressFamily == AddressFamily.InterNetwork)
  113. {
  114. foreach (var address in range)
  115. {
  116. yield return new DomainAddress("api.github.com", address);
  117. }
  118. }
  119. }
  120. }
  121. }
  122. }
  123. }