using FastGithub.Scanner.ScanMiddlewares; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace FastGithub.Scanner { /// /// github扫描服务 /// [Service(ServiceLifetime.Singleton)] sealed class GithubScanService { private readonly GithubLookupFacotry domainAddressFactory; private readonly GithubContextCollection scanResults; private readonly ILogger logger; private readonly InvokeDelegate fullScanDelegate; private readonly InvokeDelegate resultScanDelegate; /// /// github扫描服务 /// /// /// /// /// public GithubScanService( GithubLookupFacotry domainAddressFactory, GithubContextCollection scanResults, IServiceProvider appService, ILogger logger) { this.domainAddressFactory = domainAddressFactory; this.scanResults = scanResults; this.logger = logger; this.fullScanDelegate = new PipelineBuilder(appService, ctx => Task.CompletedTask) .Use() .Use() .Use() .Use() .Build(); this.resultScanDelegate = new PipelineBuilder(appService, ctx => Task.CompletedTask) .Use() .Use() .Build(); } /// /// 扫描所有的ip /// /// public async Task ScanAllAsync(CancellationToken cancellationToken) { this.logger.LogInformation("完整扫描开始.."); var domainAddresses = await this.domainAddressFactory.CreateDomainAddressesAsync(cancellationToken); var scanTasks = domainAddresses .Select(item => new GithubContext(item.Domain, item.Address, cancellationToken)) .Select(ctx => ScanAsync(ctx)); var results = await Task.WhenAll(scanTasks); var successCount = results.Count(item => item); this.logger.LogInformation($"完整扫描结束,成功{successCount}条共{results.Length}条"); async Task ScanAsync(GithubContext context) { await this.fullScanDelegate(context); if (context.Available == true) { this.scanResults.Add(context); } return context.Available; } } /// /// 扫描曾经扫描到的结果 /// /// public async Task ScanResultAsync() { this.logger.LogInformation("结果扫描开始.."); var results = this.scanResults.ToArray(); var contexts = results .OrderByDescending(item => item.History.AvailableRate) .ThenBy(item => item.History.AvgElapsed); foreach (var context in contexts) { await this.resultScanDelegate(context); } this.logger.LogInformation($"结果扫描结束,共扫描{results.Length}条记录"); } } }