123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace FastGithub.Scanner.DomainAddressProviders
- {
- /// <summary>
- /// ipaddress.com的域名与ip关系提供者
- /// </summary>
- [Service(ServiceLifetime.Singleton, ServiceType = typeof(IDomainAddressProvider))]
- sealed class IPAddressComProvider : IDomainAddressProvider
- {
- private readonly IOptionsMonitor<GithubOptions> options;
- private readonly IHttpClientFactory httpClientFactory;
- private readonly ILogger<IPAddressComProvider> logger;
- private readonly Uri lookupUri = new("https://www.ipaddress.com/ip-lookup");
- /// <summary>
- /// 获取排序
- /// </summary>
- public int Order => default;
- /// <summary>
- /// ipaddress.com的域名与ip关系提供者
- /// </summary>
- /// <param name="options"></param>
- /// <param name="logger"></param>
- public IPAddressComProvider(
- IOptionsMonitor<GithubOptions> options,
- IHttpClientFactory httpClientFactory,
- ILogger<IPAddressComProvider> logger)
- {
- this.options = options;
- this.httpClientFactory = httpClientFactory;
- this.logger = logger;
- }
- /// <summary>
- /// 创建域名与ip的关系
- /// </summary>
- /// <returns></returns>
- public async Task<IEnumerable<DomainAddress>> CreateDomainAddressesAsync()
- {
- var setting = this.options.CurrentValue.DominAddressProviders.IPAddressComProvider;
- if (setting.Enable == false)
- {
- return Enumerable.Empty<DomainAddress>();
- }
- var httpClient = this.httpClientFactory.CreateClient(nameof(FastGithub));
- var result = new HashSet<DomainAddress>();
- foreach (var domain in setting.Domains)
- {
- try
- {
- var addresses = await this.LookupAsync(httpClient, domain);
- foreach (var address in addresses)
- {
- result.Add(new DomainAddress(domain, address));
- }
- }
- catch (Exception)
- {
- this.logger.LogWarning($"ipaddress.com无法解析{domain}");
- }
- }
- return result;
- }
- /// <summary>
- /// 反查ip
- /// </summary>
- /// <param name="httpClient"></param>
- /// <param name="domain"></param>
- /// <returns></returns>
- private async Task<List<IPAddress>> LookupAsync(HttpClient httpClient, string domain)
- {
- var keyValue = new KeyValuePair<string?, string?>("host", domain);
- var content = new FormUrlEncodedContent(Enumerable.Repeat(keyValue, 1));
- using var request = new HttpRequestMessage
- {
- Method = HttpMethod.Post,
- RequestUri = lookupUri,
- Content = content
- };
- using var response = await httpClient.SendAsync(request);
- var html = await response.Content.ReadAsStringAsync();
- var match = Regex.Match(html, @"(?<=<h1>IP Lookup : )\d+\.\d+\.\d+\.\d+", RegexOptions.IgnoreCase);
- if (match.Success && IPAddress.TryParse(match.Value, out var address))
- {
- return new List<IPAddress> { address };
- }
- var prefix = Regex.Escape("type=\"radio\" value=\"");
- var matches = Regex.Matches(html, @$"(?<={prefix})\d+\.\d+\.\d+\.\d+", RegexOptions.IgnoreCase);
- var addressList = new List<IPAddress>();
- foreach (Match item in matches)
- {
- if (IPAddress.TryParse(item.Value, out address))
- {
- addressList.Add(address);
- }
- }
- return addressList;
- }
- }
- }
|