using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Json; using System.Net.Sockets; using System.Text.Json.Serialization; using System.Threading.Tasks; namespace FastGithub.Scanner.DomainMiddlewares { [Service(ServiceLifetime.Singleton, ServiceType = typeof(IDomainAddressProvider))] sealed class GithubMetaProvider : IDomainAddressProvider { private readonly IOptionsMonitor options; private readonly ILogger logger; public GithubMetaProvider( IOptionsMonitor options, ILogger logger) { this.options = options; this.logger = logger; } public async Task> CreateDomainAddressesAsync() { var setting = this.options.CurrentValue.DominAddressProviders.GithubMetaProvider; if (setting.Enable == false) { return Enumerable.Empty(); } try { using var httpClient = new HttpClient(); var meta = await httpClient.GetFromJsonAsync(setting.MetaUri); if (meta != null) { return meta.ToDomainAddresses(); } } catch (Exception ex) { this.logger.LogWarning($"加载远程的ip列表异常:{ex.Message}"); } return Enumerable.Empty(); } private class Meta { [JsonPropertyName("web")] public string[] Web { get; set; } = Array.Empty(); public IEnumerable ToDomainAddresses() { foreach (var range in IPAddressRange.From(this.Web).OrderBy(item => item.Size)) { if (range.AddressFamily == AddressFamily.InterNetwork) { foreach (var address in range) { yield return new DomainAddress("github.com", address); } } } } } } }