diff --git a/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs b/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs index 856b4dd..5b73f64 100644 --- a/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs +++ b/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs @@ -19,6 +19,7 @@ namespace FastGithub.Scanner.DomainAddressProviders sealed class GithubMetaProvider : IDomainAddressProvider { private readonly IOptionsMonitor options; + private readonly HttpClientFactory httpClientFactory; private readonly ILogger logger; private const string META_URI = "https://api.github.com/meta"; @@ -29,9 +30,11 @@ namespace FastGithub.Scanner.DomainAddressProviders /// public GithubMetaProvider( IOptionsMonitor options, + HttpClientFactory httpClientFactory, ILogger logger) { this.options = options; + this.httpClientFactory = httpClientFactory; this.logger = logger; } @@ -49,7 +52,7 @@ namespace FastGithub.Scanner.DomainAddressProviders try { - using var httpClient = new HttpClient(); + using var httpClient = this.httpClientFactory.Create(); var meta = await this.GetMetaAsync(httpClient, setting.MetaUri); if (meta != null) { @@ -91,6 +94,9 @@ namespace FastGithub.Scanner.DomainAddressProviders [JsonPropertyName("web")] public string[] Web { get; set; } = Array.Empty(); + [JsonPropertyName("api")] + public string[] Api { get; set; } = Array.Empty(); + /// /// 转换为域名与ip关系 /// @@ -107,6 +113,17 @@ namespace FastGithub.Scanner.DomainAddressProviders } } } + + foreach (var range in IPAddressRange.From(this.Api).OrderBy(item => item.Size)) + { + if (range.AddressFamily == AddressFamily.InterNetwork) + { + foreach (var address in range) + { + yield return new DomainAddress("api.github.com", address); + } + } + } } } } diff --git a/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs b/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs index 827fff1..e6bfc0e 100644 --- a/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs +++ b/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs @@ -18,6 +18,7 @@ namespace FastGithub.Scanner.DomainAddressProviders sealed class IPAddressComProvider : IDomainAddressProvider { private readonly IOptionsMonitor options; + private readonly HttpClientFactory httpClientFactory; private readonly ILogger logger; private readonly Uri lookupUri = new("https://www.ipaddress.com/ip-lookup"); @@ -28,9 +29,11 @@ namespace FastGithub.Scanner.DomainAddressProviders /// public IPAddressComProvider( IOptionsMonitor options, + HttpClientFactory httpClientFactory, ILogger logger) { this.options = options; + this.httpClientFactory = httpClientFactory; this.logger = logger; } @@ -46,7 +49,7 @@ namespace FastGithub.Scanner.DomainAddressProviders return Enumerable.Empty(); } - using var httpClient = new HttpClient(); + using var httpClient = this.httpClientFactory.Create(); var result = new HashSet(); foreach (var domain in setting.Domains) { diff --git a/FastGithub.Scanner/HttpClientFactory.cs b/FastGithub.Scanner/HttpClientFactory.cs new file mode 100644 index 0000000..de7db0e --- /dev/null +++ b/FastGithub.Scanner/HttpClientFactory.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.DependencyInjection; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Reflection; + +namespace FastGithub.Scanner +{ + /// + /// HttpClient工厂 + /// + [Service(ServiceLifetime.Singleton)] + sealed class HttpClientFactory + { + /// + /// 程序集版本信息 + /// + private static readonly AssemblyName assemblyName = typeof(HttpClientFactory).Assembly.GetName(); + + /// + /// 请求头的默认UserAgent + /// + private readonly static ProductInfoHeaderValue defaultUserAgent = new(assemblyName.Name ?? "FastGithub", assemblyName.Version?.ToString()); + + /// + /// 创建httpClient + /// + /// + public HttpClient Create(bool allowAutoRedirect = true) + { + var httpClient = new HttpClient(new HttpClientHandler + { + Proxy = null, + UseProxy = false, + AllowAutoRedirect = allowAutoRedirect + }); + httpClient.DefaultRequestHeaders.Accept.TryParseAdd("*/*"); + httpClient.DefaultRequestHeaders.UserAgent.Add(defaultUserAgent); + return httpClient; + } + } +} diff --git a/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs b/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs index f98d5dc..f026da0 100644 --- a/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs +++ b/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs @@ -18,6 +18,7 @@ namespace FastGithub.Scanner.ScanMiddlewares sealed class HttpsScanMiddleware : IMiddleware { private readonly IOptionsMonitor options; + private readonly HttpClientFactory httpClientFactory; private readonly ILogger logger; /// @@ -27,9 +28,11 @@ namespace FastGithub.Scanner.ScanMiddlewares /// public HttpsScanMiddleware( IOptionsMonitor options, + HttpClientFactory httpClientFactory, ILogger logger) { this.options = options; + this.httpClientFactory = httpClientFactory; this.logger = logger; } @@ -52,18 +55,12 @@ namespace FastGithub.Scanner.ScanMiddlewares }; request.Headers.Host = context.Domain; request.Headers.ConnectionClose = true; - request.Headers.Accept.TryParseAdd("*/*"); - - using var httpClient = new HttpMessageInvoker(new SocketsHttpHandler - { - Proxy = null, - UseProxy = false, - AllowAutoRedirect = false, - }); var timeout = this.options.CurrentValue.Scan.HttpsScanTimeout; using var cancellationTokenSource = new CancellationTokenSource(timeout); - using var response = await httpClient.SendAsync(request, cancellationTokenSource.Token); + using var httpClient = this.httpClientFactory.Create(allowAutoRedirect: false); + using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token); + this.VerifyHttpsResponse(context.Domain, response); context.Available = true;