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.DomainAddressProviders
{
///
/// Github公开的域名与ip关系提供者
///
[Service(ServiceLifetime.Singleton, ServiceType = typeof(IDomainAddressProvider))]
sealed class GithubMetaProvider : IDomainAddressProvider
{
private readonly IOptionsMonitor options;
private readonly ILogger logger;
///
/// Github公开的域名与ip关系提供者
///
///
///
public GithubMetaProvider(
IOptionsMonitor options,
ILogger logger)
{
this.options = options;
this.logger = logger;
}
///
/// 创建域名与ip的关系
///
///
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();
}
///
/// github的meta结构
///
private class Meta
{
[JsonPropertyName("web")]
public string[] Web { get; set; } = Array.Empty();
///
/// 转换为域名与ip关系
///
///
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);
}
}
}
}
}
}
}