From 9882e7367812a3b3b796a719f2423d0d7a520229 Mon Sep 17 00:00:00 2001 From: xljiulang <366193849@qq.com> Date: Fri, 18 Jun 2021 22:37:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=94=E7=94=A8CancellationToken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.Core/PipelineBuilder.cs | 2 +- FastGithub.Scanner/DomainAddressFacotry.cs | 5 +++-- .../GithubMetaProvider.cs | 13 ++++++++----- .../IPAddressComProvider.cs | 12 +++++++----- .../PublicDnsProvider.cs | 10 ++++++---- FastGithub.Scanner/GithubContext.cs | 18 ++++++++++++++++++ .../GithubFullScanHostedService.cs | 2 +- .../GithubResultScanHostedService.cs | 2 +- FastGithub.Scanner/GithubScanService.cs | 7 ++++--- FastGithub.Scanner/IDomainAddressProvider.cs | 3 ++- FastGithub.Scanner/IPAddressRange.cs | 2 +- .../ScanMiddlewares/ConcurrentMiddleware.cs | 2 +- .../ScanMiddlewares/HttpsScanMiddleware.cs | 16 +++++++--------- .../ScanMiddlewares/StatisticsMiddleware.cs | 11 +++++++---- .../ScanMiddlewares/TcpScanMiddleware.cs | 9 ++++++--- FastGithub/HostBuilderExtensions.cs | 2 +- 16 files changed, 74 insertions(+), 42 deletions(-) diff --git a/FastGithub.Core/PipelineBuilder.cs b/FastGithub.Core/PipelineBuilder.cs index ae5cf02..8e0f017 100644 --- a/FastGithub.Core/PipelineBuilder.cs +++ b/FastGithub.Core/PipelineBuilder.cs @@ -11,7 +11,7 @@ namespace FastGithub public class PipelineBuilder : IPipelineBuilder { private readonly InvokeDelegate completedHandler; - private readonly List, InvokeDelegate>> middlewares = new List, InvokeDelegate>>(); + private readonly List, InvokeDelegate>> middlewares = new(); /// /// 获取服务提供者 diff --git a/FastGithub.Scanner/DomainAddressFacotry.cs b/FastGithub.Scanner/DomainAddressFacotry.cs index cc16cc9..3aef79a 100644 --- a/FastGithub.Scanner/DomainAddressFacotry.cs +++ b/FastGithub.Scanner/DomainAddressFacotry.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner @@ -26,12 +27,12 @@ namespace FastGithub.Scanner /// 创建域名与ip的关系 /// /// - public async Task> CreateDomainAddressesAsync() + public async Task> CreateDomainAddressesAsync(CancellationToken cancellationToken) { var hashSet = new HashSet(); foreach (var provider in this.providers) { - var domainAddresses = await provider.CreateDomainAddressesAsync(); + var domainAddresses = await provider.CreateDomainAddressesAsync(cancellationToken); foreach (var item in domainAddresses) { hashSet.Add(item); diff --git a/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs b/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs index 8ad9bd1..2604437 100644 --- a/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs +++ b/FastGithub.Scanner/DomainAddressProviders/GithubMetaProvider.cs @@ -8,6 +8,7 @@ using System.Net.Http; using System.Net.Http.Json; using System.Net.Sockets; using System.Text.Json.Serialization; +using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner.DomainAddressProviders @@ -47,7 +48,7 @@ namespace FastGithub.Scanner.DomainAddressProviders /// 创建域名与ip的关系 /// /// - public async Task> CreateDomainAddressesAsync() + public async Task> CreateDomainAddressesAsync(CancellationToken cancellationToken) { var setting = this.options.CurrentValue.DominAddressProviders.GithubMetaProvider; if (setting.Enable == false) @@ -58,7 +59,7 @@ namespace FastGithub.Scanner.DomainAddressProviders try { var httpClient = this.httpClientFactory.CreateClient(nameof(FastGithub)); - var meta = await this.GetMetaAsync(httpClient, setting.MetaUri); + var meta = await GetMetaAsync(httpClient, setting.MetaUri, cancellationToken); if (meta != null) { return meta.ToDomainAddresses(); @@ -66,6 +67,7 @@ namespace FastGithub.Scanner.DomainAddressProviders } catch (Exception ex) { + cancellationToken.ThrowIfCancellationRequested(); this.logger.LogWarning($"加载远程的ip列表异常:{ex.Message}"); } @@ -79,15 +81,16 @@ namespace FastGithub.Scanner.DomainAddressProviders /// /// /// - private async Task GetMetaAsync(HttpClient httpClient, Uri metaUri) + private static async Task GetMetaAsync(HttpClient httpClient, Uri metaUri, CancellationToken cancellationToken) { try { - return await httpClient.GetFromJsonAsync(META_URI); + return await httpClient.GetFromJsonAsync(META_URI, cancellationToken); } catch (Exception) { - return await httpClient.GetFromJsonAsync(metaUri); + cancellationToken.ThrowIfCancellationRequested(); + return await httpClient.GetFromJsonAsync(metaUri, cancellationToken); } } diff --git a/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs b/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs index 3e4ae26..f07d9c6 100644 --- a/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs +++ b/FastGithub.Scanner/DomainAddressProviders/IPAddressComProvider.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner.DomainAddressProviders @@ -46,7 +47,7 @@ namespace FastGithub.Scanner.DomainAddressProviders /// 创建域名与ip的关系 /// /// - public async Task> CreateDomainAddressesAsync() + public async Task> CreateDomainAddressesAsync(CancellationToken cancellationToken) { var setting = this.options.CurrentValue.DominAddressProviders.IPAddressComProvider; if (setting.Enable == false) @@ -60,7 +61,7 @@ namespace FastGithub.Scanner.DomainAddressProviders { try { - var addresses = await this.LookupAsync(httpClient, domain); + var addresses = await this.LookupAsync(httpClient, domain, cancellationToken); foreach (var address in addresses) { result.Add(new DomainAddress(domain, address)); @@ -68,6 +69,7 @@ namespace FastGithub.Scanner.DomainAddressProviders } catch (Exception) { + cancellationToken.ThrowIfCancellationRequested(); this.logger.LogWarning($"ipaddress.com无法解析{domain}"); } } @@ -80,7 +82,7 @@ namespace FastGithub.Scanner.DomainAddressProviders /// /// /// - private async Task> LookupAsync(HttpClient httpClient, string domain) + private async Task> LookupAsync(HttpClient httpClient, string domain, CancellationToken cancellationToken) { var keyValue = new KeyValuePair("host", domain); var content = new FormUrlEncodedContent(Enumerable.Repeat(keyValue, 1)); @@ -91,8 +93,8 @@ namespace FastGithub.Scanner.DomainAddressProviders Content = content }; - using var response = await httpClient.SendAsync(request); - var html = await response.Content.ReadAsStringAsync(); + using var response = await httpClient.SendAsync(request, cancellationToken); + var html = await response.Content.ReadAsStringAsync(cancellationToken); var match = Regex.Match(html, @"(?<=

IP Lookup : )\d+\.\d+\.\d+\.\d+", RegexOptions.IgnoreCase); if (match.Success && IPAddress.TryParse(match.Value, out var address)) diff --git a/FastGithub.Scanner/DomainAddressProviders/PublicDnsProvider.cs b/FastGithub.Scanner/DomainAddressProviders/PublicDnsProvider.cs index b2ea8c6..1c26b27 100644 --- a/FastGithub.Scanner/DomainAddressProviders/PublicDnsProvider.cs +++ b/FastGithub.Scanner/DomainAddressProviders/PublicDnsProvider.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner.DomainAddressProviders @@ -41,7 +42,7 @@ namespace FastGithub.Scanner.DomainAddressProviders /// 创建域名与ip的关系 /// /// - public async Task> CreateDomainAddressesAsync() + public async Task> CreateDomainAddressesAsync(CancellationToken cancellationToken) { var setting = this.options.CurrentValue.DominAddressProviders.PublicDnsProvider; if (setting.Enable == false) @@ -52,7 +53,7 @@ namespace FastGithub.Scanner.DomainAddressProviders var result = new HashSet(); foreach (var dns in setting.Dnss) { - var domainAddresses = await this.LookupAsync(dns, setting.Domains); + var domainAddresses = await this.LookupAsync(dns, setting.Domains, cancellationToken); foreach (var item in domainAddresses) { result.Add(item); @@ -68,7 +69,7 @@ namespace FastGithub.Scanner.DomainAddressProviders /// dns服务器 /// 域名 /// - private async Task> LookupAsync(string dns, IEnumerable domains) + private async Task> LookupAsync(string dns, IEnumerable domains, CancellationToken cancellationToken) { var client = new DnsClient(dns); var result = new List(); @@ -77,7 +78,7 @@ namespace FastGithub.Scanner.DomainAddressProviders { try { - var addresses = await client.Lookup(domain); + var addresses = await client.Lookup(domain, cancellationToken: cancellationToken); foreach (var address in addresses) { if (address.AddressFamily == AddressFamily.InterNetwork) @@ -88,6 +89,7 @@ namespace FastGithub.Scanner.DomainAddressProviders } catch (Exception) { + cancellationToken.ThrowIfCancellationRequested(); this.logger.LogWarning($"dns({dns})无法解析{domain}"); } } diff --git a/FastGithub.Scanner/GithubContext.cs b/FastGithub.Scanner/GithubContext.cs index 07e5227..5bfc998 100644 --- a/FastGithub.Scanner/GithubContext.cs +++ b/FastGithub.Scanner/GithubContext.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Threading; namespace FastGithub.Scanner { @@ -13,6 +14,11 @@ namespace FastGithub.Scanner /// public bool Available { get; set; } + /// + /// 设置取消令牌 + /// + public CancellationToken CancellationToken { get; } + /// /// 获取扫描历史信息 /// @@ -25,8 +31,20 @@ namespace FastGithub.Scanner /// /// public GithubContext(string domain, IPAddress address) + : this(domain, address, CancellationToken.None) + { + } + + /// + /// Github扫描上下文 + /// + /// + /// + /// + public GithubContext(string domain, IPAddress address, CancellationToken cancellationToken) : base(domain, address) { + this.CancellationToken = cancellationToken; } public bool Equals(GithubContext? other) diff --git a/FastGithub.Scanner/GithubFullScanHostedService.cs b/FastGithub.Scanner/GithubFullScanHostedService.cs index d745b69..93d112c 100644 --- a/FastGithub.Scanner/GithubFullScanHostedService.cs +++ b/FastGithub.Scanner/GithubFullScanHostedService.cs @@ -36,7 +36,7 @@ namespace FastGithub { while (stoppingToken.IsCancellationRequested == false) { - await githubScanService.ScanAllAsync(); + await githubScanService.ScanAllAsync(stoppingToken); await Task.Delay(this.options.CurrentValue.Scan.FullScanInterval, stoppingToken); } } diff --git a/FastGithub.Scanner/GithubResultScanHostedService.cs b/FastGithub.Scanner/GithubResultScanHostedService.cs index 510efc9..d4c9409 100644 --- a/FastGithub.Scanner/GithubResultScanHostedService.cs +++ b/FastGithub.Scanner/GithubResultScanHostedService.cs @@ -39,6 +39,6 @@ namespace FastGithub await Task.Delay(this.options.CurrentValue.Scan.ResultScanInterval, stoppingToken); await githubScanService.ScanResultAsync(); } - } + } } } diff --git a/FastGithub.Scanner/GithubScanService.cs b/FastGithub.Scanner/GithubScanService.cs index c63684a..7397d7b 100644 --- a/FastGithub.Scanner/GithubScanService.cs +++ b/FastGithub.Scanner/GithubScanService.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner @@ -54,13 +55,13 @@ namespace FastGithub.Scanner /// 扫描所有的ip /// /// - public async Task ScanAllAsync() + public async Task ScanAllAsync(CancellationToken cancellationToken) { this.logger.LogInformation("完整扫描开始.."); - var domainAddresses = await this.domainAddressFactory.CreateDomainAddressesAsync(); + var domainAddresses = await this.domainAddressFactory.CreateDomainAddressesAsync(cancellationToken); var scanTasks = domainAddresses - .Select(item => new GithubContext(item.Domain, item.Address)) + .Select(item => new GithubContext(item.Domain, item.Address, cancellationToken)) .Select(ctx => ScanAsync(ctx)); var results = await Task.WhenAll(scanTasks); diff --git a/FastGithub.Scanner/IDomainAddressProvider.cs b/FastGithub.Scanner/IDomainAddressProvider.cs index f08f707..8ec4a16 100644 --- a/FastGithub.Scanner/IDomainAddressProvider.cs +++ b/FastGithub.Scanner/IDomainAddressProvider.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner @@ -17,6 +18,6 @@ namespace FastGithub.Scanner /// 创建域名与ip的关系 /// /// - Task> CreateDomainAddressesAsync(); + Task> CreateDomainAddressesAsync(CancellationToken cancellationToken); } } diff --git a/FastGithub.Scanner/IPAddressRange.cs b/FastGithub.Scanner/IPAddressRange.cs index 16ec763..de77f36 100644 --- a/FastGithub.Scanner/IPAddressRange.cs +++ b/FastGithub.Scanner/IPAddressRange.cs @@ -73,7 +73,7 @@ namespace FastGithub.Scanner if (index >= 0) { var start = range.Slice(0, index); - var end = range.Slice(index + 1); + var end = range[(index + 1)..]; if (IPAddress.TryParse(start, out var startIp) && IPAddress.TryParse(end, out var endIp) && diff --git a/FastGithub.Scanner/ScanMiddlewares/ConcurrentMiddleware.cs b/FastGithub.Scanner/ScanMiddlewares/ConcurrentMiddleware.cs index 6b97dde..8ab0fae 100644 --- a/FastGithub.Scanner/ScanMiddlewares/ConcurrentMiddleware.cs +++ b/FastGithub.Scanner/ScanMiddlewares/ConcurrentMiddleware.cs @@ -32,7 +32,7 @@ namespace FastGithub.Scanner.ScanMiddlewares { try { - await this.semaphoreSlim.WaitAsync(); + await this.semaphoreSlim.WaitAsync(context.CancellationToken); await next(); } finally diff --git a/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs b/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs index b5358a1..e5911f3 100644 --- a/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs +++ b/FastGithub.Scanner/ScanMiddlewares/HttpsScanMiddleware.cs @@ -53,26 +53,24 @@ namespace FastGithub.Scanner.ScanMiddlewares Method = HttpMethod.Head, RequestUri = new Uri($"https://{context.Address}"), }; - request.Headers.Host = context.Domain; + request.Headers.Host = context.Domain; var timeout = this.options.CurrentValue.Scan.HttpsScanTimeout; - using var cancellationTokenSource = new CancellationTokenSource(timeout); + using var timeoutTokenSource = new CancellationTokenSource(timeout); + using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, context.CancellationToken); + var httpClient = this.httpClientFactory.CreateClient(nameof(FastGithub)); - using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token); + using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, linkedTokenSource.Token); VerifyHttpsResponse(context.Domain, response); context.Available = true; await next(); } - catch (TaskCanceledException) - { - this.logger.LogTrace($"{context.Domain} {context.Address}连接超时"); - } catch (Exception ex) { - var message = GetInnerMessage(ex); - this.logger.LogTrace($"{context.Domain} {context.Address} {message}"); + context.CancellationToken.ThrowIfCancellationRequested(); + this.logger.LogTrace($"{context.Domain} {context.Address} { GetInnerMessage(ex)}"); } } diff --git a/FastGithub.Scanner/ScanMiddlewares/StatisticsMiddleware.cs b/FastGithub.Scanner/ScanMiddlewares/StatisticsMiddleware.cs index 0f951ec..8e47c9f 100644 --- a/FastGithub.Scanner/ScanMiddlewares/StatisticsMiddleware.cs +++ b/FastGithub.Scanner/ScanMiddlewares/StatisticsMiddleware.cs @@ -32,20 +32,23 @@ namespace FastGithub.Scanner.ScanMiddlewares public async Task InvokeAsync(GithubContext context, Func next) { var stopwatch = new Stopwatch(); - stopwatch.Start(); try { + stopwatch.Start(); await next(); } finally { stopwatch.Stop(); - context.History.Add(context.Available, stopwatch.Elapsed); - if (context.History.AvailableRate > 0d) + if (context.CancellationToken.IsCancellationRequested == false) { - this.logger.LogInformation(context.ToString()); + context.History.Add(context.Available, stopwatch.Elapsed); + if (context.History.AvailableRate > 0d) + { + this.logger.LogInformation(context.ToString()); + } } } } diff --git a/FastGithub.Scanner/ScanMiddlewares/TcpScanMiddleware.cs b/FastGithub.Scanner/ScanMiddlewares/TcpScanMiddleware.cs index c4f3138..0534872 100644 --- a/FastGithub.Scanner/ScanMiddlewares/TcpScanMiddleware.cs +++ b/FastGithub.Scanner/ScanMiddlewares/TcpScanMiddleware.cs @@ -71,14 +71,17 @@ namespace FastGithub.Scanner.ScanMiddlewares { try { - using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); var timeout = this.options.CurrentValue.Scan.TcpScanTimeout; - using var cancellationTokenSource = new CancellationTokenSource(timeout); - await socket.ConnectAsync(context.Address, PORT, cancellationTokenSource.Token); + using var timeoutTokenSource = new CancellationTokenSource(timeout); + using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, context.CancellationToken); + + using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + await socket.ConnectAsync(context.Address, PORT, linkedTokenSource.Token); return true; } catch (Exception) { + context.CancellationToken.ThrowIfCancellationRequested(); return false; } } diff --git a/FastGithub/HostBuilderExtensions.cs b/FastGithub/HostBuilderExtensions.cs index 87d016a..926bff0 100644 --- a/FastGithub/HostBuilderExtensions.cs +++ b/FastGithub/HostBuilderExtensions.cs @@ -31,7 +31,7 @@ namespace FastGithub c.Service(service => service .ConstructUsing(() => hostBuilder.Build()) .WhenStarted(service => service.Start()) - .WhenStopped(service => service.StopAsync()) + .WhenStopped(service => service.StopAsync().Wait()) ); }); }