From 82a816e40d683ad7e02959a2c033019b553cb9e0 Mon Sep 17 00:00:00 2001 From: xljiulang <366193849@qq.com> Date: Sat, 24 Jul 2021 04:08:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E7=A6=BB=E5=92=8C=E5=A4=8D=E7=94=A8Ht?= =?UTF-8?q?tpClient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DomainResolver.cs | 4 +- FastGithub.Http/FastGithub.Http.csproj | 14 ++++ FastGithub.Http/HttpClient.cs | 56 ++++++++++++++ FastGithub.Http/HttpClientFactory.cs | 35 +++++++++ .../HttpClientHandler.cs | 12 +-- .../HttpClientServiceCollectionExtensions.cs | 25 +++++++ FastGithub.Http/IDomainResolver.cs | 20 +++++ FastGithub.Http/IHttpClientFactory.cs | 15 ++++ .../RequestContext.cs | 2 +- .../RequestContextExtensions.cs | 2 +- .../FastGithub.ReverseProxy.csproj | 2 +- FastGithub.ReverseProxy/HttpClientFactory.cs | 73 ------------------- .../ReverseProxyMiddleware.cs | 7 +- ...ReverseProxyServiceCollectionExtensions.cs | 3 +- FastGithub.Upgrade/FastGithub.Upgrade.csproj | 1 + FastGithub.Upgrade/GithubRequestMessage.cs | 17 +++++ FastGithub.Upgrade/ReverseProxyHttpHandler.cs | 46 ------------ FastGithub.Upgrade/UpgradeService.cs | 37 +++++++--- .../UpgradeServiceCollectionExtensions.cs | 1 + FastGithub.sln | 6 ++ 20 files changed, 232 insertions(+), 146 deletions(-) rename {FastGithub.ReverseProxy => FastGithub.Http}/DomainResolver.cs (98%) create mode 100644 FastGithub.Http/FastGithub.Http.csproj create mode 100644 FastGithub.Http/HttpClient.cs create mode 100644 FastGithub.Http/HttpClientFactory.cs rename FastGithub.ReverseProxy/HttpClientHanlder.cs => FastGithub.Http/HttpClientHandler.cs (95%) create mode 100644 FastGithub.Http/HttpClientServiceCollectionExtensions.cs create mode 100644 FastGithub.Http/IDomainResolver.cs create mode 100644 FastGithub.Http/IHttpClientFactory.cs rename {FastGithub.ReverseProxy => FastGithub.Http}/RequestContext.cs (94%) rename {FastGithub.ReverseProxy => FastGithub.Http}/RequestContextExtensions.cs (97%) delete mode 100644 FastGithub.ReverseProxy/HttpClientFactory.cs create mode 100644 FastGithub.Upgrade/GithubRequestMessage.cs delete mode 100644 FastGithub.Upgrade/ReverseProxyHttpHandler.cs diff --git a/FastGithub.ReverseProxy/DomainResolver.cs b/FastGithub.Http/DomainResolver.cs similarity index 98% rename from FastGithub.ReverseProxy/DomainResolver.cs rename to FastGithub.Http/DomainResolver.cs index 2b40391..98bb782 100644 --- a/FastGithub.ReverseProxy/DomainResolver.cs +++ b/FastGithub.Http/DomainResolver.cs @@ -8,12 +8,12 @@ using System.Net; using System.Threading; using System.Threading.Tasks; -namespace FastGithub.ReverseProxy +namespace FastGithub.Http { /// /// 域名解析器 /// - sealed class DomainResolver + sealed class DomainResolver : IDomainResolver { private readonly IMemoryCache memoryCache; private readonly FastGithubConfig fastGithubConfig; diff --git a/FastGithub.Http/FastGithub.Http.csproj b/FastGithub.Http/FastGithub.Http.csproj new file mode 100644 index 0000000..e5cca58 --- /dev/null +++ b/FastGithub.Http/FastGithub.Http.csproj @@ -0,0 +1,14 @@ + + + + net5.0 + + + + + + + + + + diff --git a/FastGithub.Http/HttpClient.cs b/FastGithub.Http/HttpClient.cs new file mode 100644 index 0000000..8a8d4c5 --- /dev/null +++ b/FastGithub.Http/HttpClient.cs @@ -0,0 +1,56 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace FastGithub.Http +{ + /// + /// 表示http客户端 + /// + public class HttpClient : HttpMessageInvoker + { + private readonly DomainConfig domainConfig; + + /// + /// http客户端 + /// + /// + /// + public HttpClient(DomainConfig domainConfig, IDomainResolver domainResolver) + : this(domainConfig, new HttpClientHandler(domainResolver), disposeHandler: true) + { + this.domainConfig = domainConfig; + } + + /// + /// http客户端 + /// + /// + /// + /// + internal HttpClient(DomainConfig domainConfig, HttpClientHandler handler, bool disposeHandler) + : base(handler, disposeHandler) + { + this.domainConfig = domainConfig; + } + + /// + /// 发送数据 + /// + /// + /// + /// + public override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + request.SetRequestContext(new RequestContext + { + Host = request.RequestUri?.Host, + IsHttps = request.RequestUri?.Scheme == Uri.UriSchemeHttps, + TlsSniPattern = this.domainConfig.GetTlsSniPattern(), + TlsIgnoreNameMismatch = this.domainConfig.TlsIgnoreNameMismatch + }); + return base.SendAsync(request, cancellationToken); + } + } +} \ No newline at end of file diff --git a/FastGithub.Http/HttpClientFactory.cs b/FastGithub.Http/HttpClientFactory.cs new file mode 100644 index 0000000..387388e --- /dev/null +++ b/FastGithub.Http/HttpClientFactory.cs @@ -0,0 +1,35 @@ +using Microsoft.Extensions.Options; + +namespace FastGithub.Http +{ + /// + /// HttpClient工厂 + /// + sealed class HttpClientFactory : IHttpClientFactory + { + private HttpClientHandler httpClientHanlder; + + /// + /// HttpClient工厂 + /// + /// + /// + public HttpClientFactory( + IDomainResolver domainResolver, + IOptionsMonitor options) + { + this.httpClientHanlder = new HttpClientHandler(domainResolver); + options.OnChange(opt => this.httpClientHanlder = new HttpClientHandler(domainResolver)); + } + + /// + /// 创建httpClient + /// + /// + /// + public HttpClient CreateHttpClient(DomainConfig domainConfig) + { + return new HttpClient(domainConfig, this.httpClientHanlder, disposeHandler: false); + } + } +} \ No newline at end of file diff --git a/FastGithub.ReverseProxy/HttpClientHanlder.cs b/FastGithub.Http/HttpClientHandler.cs similarity index 95% rename from FastGithub.ReverseProxy/HttpClientHanlder.cs rename to FastGithub.Http/HttpClientHandler.cs index 9ece290..c493f8a 100644 --- a/FastGithub.ReverseProxy/HttpClientHanlder.cs +++ b/FastGithub.Http/HttpClientHandler.cs @@ -9,20 +9,20 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; -namespace FastGithub.ReverseProxy +namespace FastGithub.Http { /// - /// YARP的HttpClientHandler + /// HttpClientHandler /// - class HttpClientHanlder : DelegatingHandler + class HttpClientHandler : DelegatingHandler { - private readonly DomainResolver domainResolver; + private readonly IDomainResolver domainResolver; /// - /// YARP的HttpClientHandler + /// HttpClientHandler /// /// - public HttpClientHanlder(DomainResolver domainResolver) + public HttpClientHandler(IDomainResolver domainResolver) { this.domainResolver = domainResolver; this.InnerHandler = CreateSocketsHttpHandler(); diff --git a/FastGithub.Http/HttpClientServiceCollectionExtensions.cs b/FastGithub.Http/HttpClientServiceCollectionExtensions.cs new file mode 100644 index 0000000..6648b3b --- /dev/null +++ b/FastGithub.Http/HttpClientServiceCollectionExtensions.cs @@ -0,0 +1,25 @@ +using FastGithub.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace FastGithub +{ + /// + /// httpClient的服务注册扩展 + /// + public static class HttpClientServiceCollectionExtensions + { + /// + /// 添加HttpClient相关服务 + /// + /// + /// + public static IServiceCollection AddHttpClient(this IServiceCollection services) + { + services.AddMemoryCache(); + services.TryAddSingleton(); + services.TryAddSingleton(); + return services; + } + } +} diff --git a/FastGithub.Http/IDomainResolver.cs b/FastGithub.Http/IDomainResolver.cs new file mode 100644 index 0000000..760e6aa --- /dev/null +++ b/FastGithub.Http/IDomainResolver.cs @@ -0,0 +1,20 @@ +using System.Net; +using System.Threading; +using System.Threading.Tasks; + +namespace FastGithub.Http +{ + /// + /// 域名解析器 + /// + public interface IDomainResolver + { + /// + /// 解析域名 + /// + /// + /// + /// + Task ResolveAsync(string domain, CancellationToken cancellationToken); + } +} \ No newline at end of file diff --git a/FastGithub.Http/IHttpClientFactory.cs b/FastGithub.Http/IHttpClientFactory.cs new file mode 100644 index 0000000..ce71e74 --- /dev/null +++ b/FastGithub.Http/IHttpClientFactory.cs @@ -0,0 +1,15 @@ +namespace FastGithub.Http +{ + /// + /// httpClient工厂 + /// + public interface IHttpClientFactory + { + /// + /// 创建httpClient + /// + /// + /// + HttpClient CreateHttpClient(DomainConfig domainConfig); + } +} diff --git a/FastGithub.ReverseProxy/RequestContext.cs b/FastGithub.Http/RequestContext.cs similarity index 94% rename from FastGithub.ReverseProxy/RequestContext.cs rename to FastGithub.Http/RequestContext.cs index 509526a..83a0d41 100644 --- a/FastGithub.ReverseProxy/RequestContext.cs +++ b/FastGithub.Http/RequestContext.cs @@ -1,4 +1,4 @@ -namespace FastGithub.ReverseProxy +namespace FastGithub.Http { /// /// 表示请求上下文 diff --git a/FastGithub.ReverseProxy/RequestContextExtensions.cs b/FastGithub.Http/RequestContextExtensions.cs similarity index 97% rename from FastGithub.ReverseProxy/RequestContextExtensions.cs rename to FastGithub.Http/RequestContextExtensions.cs index 68e6291..5388ca6 100644 --- a/FastGithub.ReverseProxy/RequestContextExtensions.cs +++ b/FastGithub.Http/RequestContextExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Net.Http; -namespace FastGithub.ReverseProxy +namespace FastGithub.Http { /// /// 请求上下文扩展 diff --git a/FastGithub.ReverseProxy/FastGithub.ReverseProxy.csproj b/FastGithub.ReverseProxy/FastGithub.ReverseProxy.csproj index 57a0ed9..2a1696b 100644 --- a/FastGithub.ReverseProxy/FastGithub.ReverseProxy.csproj +++ b/FastGithub.ReverseProxy/FastGithub.ReverseProxy.csproj @@ -6,13 +6,13 @@ - + diff --git a/FastGithub.ReverseProxy/HttpClientFactory.cs b/FastGithub.ReverseProxy/HttpClientFactory.cs deleted file mode 100644 index 57b66d7..0000000 --- a/FastGithub.ReverseProxy/HttpClientFactory.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Microsoft.Extensions.Options; -using System; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace FastGithub.ReverseProxy -{ - /// - /// HttpClient工厂 - /// - sealed class HttpClientFactory - { - private HttpClientHanlder httpClientHanlder; - - /// - /// HttpClient工厂 - /// - /// - /// - public HttpClientFactory( - DomainResolver domainResolver, - IOptionsMonitor options) - { - this.httpClientHanlder = new HttpClientHanlder(domainResolver); - options.OnChange(opt => this.httpClientHanlder = new HttpClientHanlder(domainResolver)); - } - - /// - /// 创建httpClient - /// - /// - /// - public HttpMessageInvoker CreateHttpClient(DomainConfig domainConfig) - { - return new HttpClient(this.httpClientHanlder, domainConfig, disposeHandler: false); - } - - /// - /// http客户端 - /// - private class HttpClient : HttpMessageInvoker - { - private readonly DomainConfig domainConfig; - - public HttpClient( - HttpMessageHandler handler, - DomainConfig domainConfig, - bool disposeHandler = false) : base(handler, disposeHandler) - { - this.domainConfig = domainConfig; - } - - /// - /// 发送数据 - /// - /// - /// - /// - public override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - request.SetRequestContext(new RequestContext - { - Host = request.RequestUri?.Host, - IsHttps = request.RequestUri?.Scheme == Uri.UriSchemeHttps, - TlsSniPattern = this.domainConfig.GetTlsSniPattern(), - TlsIgnoreNameMismatch = this.domainConfig.TlsIgnoreNameMismatch - }); - return base.SendAsync(request, cancellationToken); - } - } - } -} diff --git a/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs b/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs index 7b28119..88008c0 100644 --- a/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs +++ b/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Http; +using FastGithub.Http; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; @@ -12,13 +13,13 @@ namespace FastGithub.ReverseProxy sealed class ReverseProxyMiddleware { private readonly IHttpForwarder httpForwarder; - private readonly HttpClientFactory httpClientFactory; + private readonly IHttpClientFactory httpClientFactory; private readonly FastGithubConfig fastGithubConfig; private readonly ILogger logger; public ReverseProxyMiddleware( IHttpForwarder httpForwarder, - HttpClientFactory httpClientFactory, + IHttpClientFactory httpClientFactory, FastGithubConfig fastGithubConfig, ILogger logger) { diff --git a/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs b/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs index 3ec02e4..b027f57 100644 --- a/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs +++ b/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs @@ -18,8 +18,7 @@ namespace FastGithub return services .AddMemoryCache() .AddHttpForwarder() - .AddSingleton() - .AddTransient() + .AddHttpClient() .AddSingleton() .AddSingleton(); } diff --git a/FastGithub.Upgrade/FastGithub.Upgrade.csproj b/FastGithub.Upgrade/FastGithub.Upgrade.csproj index a870eac..c3cc728 100644 --- a/FastGithub.Upgrade/FastGithub.Upgrade.csproj +++ b/FastGithub.Upgrade/FastGithub.Upgrade.csproj @@ -10,6 +10,7 @@ + diff --git a/FastGithub.Upgrade/GithubRequestMessage.cs b/FastGithub.Upgrade/GithubRequestMessage.cs new file mode 100644 index 0000000..8428d5b --- /dev/null +++ b/FastGithub.Upgrade/GithubRequestMessage.cs @@ -0,0 +1,17 @@ +using System.Net.Http; +using System.Net.Http.Headers; + +namespace FastGithub.Upgrade +{ + /// + /// github请求消息 + /// + class GithubRequestMessage : HttpRequestMessage + { + public GithubRequestMessage() + { + this.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*")); + this.Headers.UserAgent.Add(new ProductInfoHeaderValue(nameof(FastGithub), "1.0")); + } + } +} diff --git a/FastGithub.Upgrade/ReverseProxyHttpHandler.cs b/FastGithub.Upgrade/ReverseProxyHttpHandler.cs deleted file mode 100644 index 60b0e5d..0000000 --- a/FastGithub.Upgrade/ReverseProxyHttpHandler.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Net; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace FastGithub.Upgrade -{ - /// - /// 本机反向代理的httpHandler - /// - sealed class ReverseProxyHttpHandler : DelegatingHandler - { - /// - /// 本机反向代理的httpHandler - /// - public ReverseProxyHttpHandler() - { - this.InnerHandler = new HttpClientHandler - { - ServerCertificateCustomValidationCallback = delegate { return true; } - }; - } - - /// - /// 替换为Loopback - /// - /// - /// - /// - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - var uri = request.RequestUri; - if (uri != null && uri.HostNameType == UriHostNameType.Dns) - { - var domain = uri.Host; - var builder = new UriBuilder(uri) { Host = IPAddress.Loopback.ToString() }; - - request.RequestUri = builder.Uri; - request.Headers.Host = domain; - } - - return await base.SendAsync(request, cancellationToken); - } - } -} diff --git a/FastGithub.Upgrade/UpgradeService.cs b/FastGithub.Upgrade/UpgradeService.cs index 94c54b3..35813ff 100644 --- a/FastGithub.Upgrade/UpgradeService.cs +++ b/FastGithub.Upgrade/UpgradeService.cs @@ -1,8 +1,7 @@ -using Microsoft.Extensions.Logging; +using FastGithub.Http; +using Microsoft.Extensions.Logging; using System; using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; @@ -14,15 +13,20 @@ namespace FastGithub.Upgrade /// sealed class UpgradeService { + private readonly IDomainResolver domainResolver; private readonly ILogger logger; - private const string ReleasesUri = "https://api.github.com/repos/xljiulang/fastgithub/releases"; + private readonly Uri releasesUri = new("https://api.github.com/repos/xljiulang/fastgithub/releases"); /// /// 升级服务 /// + /// /// - public UpgradeService(ILogger logger) + public UpgradeService( + IDomainResolver domainResolver, + ILogger logger) { + this.domainResolver = domainResolver; this.logger = logger; } @@ -48,9 +52,13 @@ namespace FastGithub.Upgrade var lastedVersion = lastRelease.GetProductionVersion(); if (lastedVersion.CompareTo(currentVersion) > 0) { - this.logger.LogInformation($"您正在使用{currentVersion}版本{Environment.NewLine}请前往{lastRelease.HtmlUrl}下载新版本"); + this.logger.LogInformation($"当前版本{currentVersion}为老版本{Environment.NewLine}请前往{lastRelease.HtmlUrl}下载新版本"); this.logger.LogInformation(lastRelease.ToString()); } + else + { + this.logger.LogInformation($"当前版本{currentVersion}为最新版本"); + } } /// @@ -59,14 +67,21 @@ namespace FastGithub.Upgrade /// public async Task GetLastedReleaseAsync(CancellationToken cancellationToken) { - using var httpClient = new HttpClient(new ReverseProxyHttpHandler()) + var domainConfig = new DomainConfig { - Timeout = TimeSpan.FromSeconds(30d), + TlsSni = false, + TlsIgnoreNameMismatch = true, + Timeout = TimeSpan.FromSeconds(30d) }; - httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*")); - httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(nameof(FastGithub), "1.0")); - var releases = await httpClient.GetFromJsonAsync(ReleasesUri, cancellationToken); + using var request = new GithubRequestMessage + { + RequestUri = this.releasesUri + }; + + using var httpClient = new HttpClient(domainConfig, this.domainResolver); + var response = await httpClient.SendAsync(request, cancellationToken); + var releases = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken); return releases?.FirstOrDefault(item => item.Prerelease == false); } } diff --git a/FastGithub.Upgrade/UpgradeServiceCollectionExtensions.cs b/FastGithub.Upgrade/UpgradeServiceCollectionExtensions.cs index a3fd0ec..600fd9b 100644 --- a/FastGithub.Upgrade/UpgradeServiceCollectionExtensions.cs +++ b/FastGithub.Upgrade/UpgradeServiceCollectionExtensions.cs @@ -16,6 +16,7 @@ namespace FastGithub public static IServiceCollection AddAppUpgrade(this IServiceCollection services) { return services + .AddHttpClient() .AddSingleton() .AddHostedService(); } diff --git a/FastGithub.sln b/FastGithub.sln index 3d702f8..24bdbd6 100644 --- a/FastGithub.sln +++ b/FastGithub.sln @@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.ReverseProxy", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.DnscryptProxy", "FastGithub.DnscryptProxy\FastGithub.DnscryptProxy.csproj", "{26BB826F-4117-4746-9BD0-C6D8043E2808}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Http", "FastGithub.Http\FastGithub.Http.csproj", "{B5DCB3E4-5094-4170-B844-6F395002CA42}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,6 +47,10 @@ Global {26BB826F-4117-4746-9BD0-C6D8043E2808}.Debug|Any CPU.Build.0 = Debug|Any CPU {26BB826F-4117-4746-9BD0-C6D8043E2808}.Release|Any CPU.ActiveCfg = Release|Any CPU {26BB826F-4117-4746-9BD0-C6D8043E2808}.Release|Any CPU.Build.0 = Release|Any CPU + {B5DCB3E4-5094-4170-B844-6F395002CA42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5DCB3E4-5094-4170-B844-6F395002CA42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5DCB3E4-5094-4170-B844-6F395002CA42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5DCB3E4-5094-4170-B844-6F395002CA42}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE