From 2f9827a5fd88d3bd12414469f3b2e482aa435734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Wed, 24 Nov 2021 08:57:47 +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 --- ...ler.cs => GithubGitReverseProxyHandler.cs} | 4 ++-- ...ler.cs => GithubSshReverseProxyHandler.cs} | 4 ++-- FastGithub.HttpServer/HttpProxyMiddleware.cs | 22 +++++++++++++------ .../KestrelServerOptionsExtensions.cs | 10 ++++----- .../TcpReverseProxyHandler.cs | 18 +++++++++------ 5 files changed, 35 insertions(+), 23 deletions(-) rename FastGithub.HttpServer/{GitReverseProxyHandler.cs => GithubGitReverseProxyHandler.cs} (71%) rename FastGithub.HttpServer/{SshReverseProxyHandler.cs => GithubSshReverseProxyHandler.cs} (71%) diff --git a/FastGithub.HttpServer/GitReverseProxyHandler.cs b/FastGithub.HttpServer/GithubGitReverseProxyHandler.cs similarity index 71% rename from FastGithub.HttpServer/GitReverseProxyHandler.cs rename to FastGithub.HttpServer/GithubGitReverseProxyHandler.cs index 14a6b1f..2888afc 100644 --- a/FastGithub.HttpServer/GitReverseProxyHandler.cs +++ b/FastGithub.HttpServer/GithubGitReverseProxyHandler.cs @@ -5,13 +5,13 @@ namespace FastGithub.HttpServer /// /// github的git代理处理者 /// - sealed class GitReverseProxyHandler : TcpReverseProxyHandler + sealed class GithubGitReverseProxyHandler : TcpReverseProxyHandler { /// /// github的git代理处理者 /// /// - public GitReverseProxyHandler(IDomainResolver domainResolver) + public GithubGitReverseProxyHandler(IDomainResolver domainResolver) : base(domainResolver, new("github.com", 9418)) { } diff --git a/FastGithub.HttpServer/SshReverseProxyHandler.cs b/FastGithub.HttpServer/GithubSshReverseProxyHandler.cs similarity index 71% rename from FastGithub.HttpServer/SshReverseProxyHandler.cs rename to FastGithub.HttpServer/GithubSshReverseProxyHandler.cs index 56323d3..f6325ac 100644 --- a/FastGithub.HttpServer/SshReverseProxyHandler.cs +++ b/FastGithub.HttpServer/GithubSshReverseProxyHandler.cs @@ -5,13 +5,13 @@ namespace FastGithub.HttpServer /// /// github的ssh代理处理者 /// - sealed class SshReverseProxyHandler : TcpReverseProxyHandler + sealed class GithubSshReverseProxyHandler : TcpReverseProxyHandler { /// /// github的ssh代理处理者 /// /// - public SshReverseProxyHandler(IDomainResolver domainResolver) + public GithubSshReverseProxyHandler(IDomainResolver domainResolver) : base(domainResolver, new("github.com", 22)) { } diff --git a/FastGithub.HttpServer/HttpProxyMiddleware.cs b/FastGithub.HttpServer/HttpProxyMiddleware.cs index 8283f2c..b58b526 100644 --- a/FastGithub.HttpServer/HttpProxyMiddleware.cs +++ b/FastGithub.HttpServer/HttpProxyMiddleware.cs @@ -12,6 +12,7 @@ using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -88,7 +89,8 @@ namespace FastGithub.HttpServer } else if (context.Request.Method == HttpMethods.Connect) { - using var connection = await this.CreateConnectionAsync(host); + var cancellationToken = context.RequestAborted; + using var connection = await this.CreateConnectionAsync(host, cancellationToken); var responseFeature = context.Features.Get(); if (responseFeature != null) { @@ -100,7 +102,9 @@ namespace FastGithub.HttpServer var transport = context.Features.Get()?.Transport; if (transport != null) { - await Task.WhenAny(connection.CopyToAsync(transport.Output), transport.Input.CopyToAsync(connection)); + var task1 = connection.CopyToAsync(transport.Output, cancellationToken); + var task2 = transport.Input.CopyToAsync(connection, cancellationToken); + await Task.WhenAny(task1, task2); } } else @@ -156,23 +160,26 @@ namespace FastGithub.HttpServer /// 创建连接 /// /// + /// /// /// - private async Task CreateConnectionAsync(HostString host) + private async Task CreateConnectionAsync(HostString host, CancellationToken cancellationToken) { var innerExceptions = new List(); - await foreach (var endPoint in this.GetTargetEndPointsAsync(host)) + await foreach (var endPoint in this.GetUpstreamEndPointsAsync(host, cancellationToken)) { var socket = new Socket(SocketType.Stream, ProtocolType.Tcp); try { using var timeoutTokenSource = new CancellationTokenSource(this.connectTimeout); - await socket.ConnectAsync(endPoint, timeoutTokenSource.Token); + using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token); + await socket.ConnectAsync(endPoint, linkedTokenSource.Token); return new NetworkStream(socket, ownsSocket: false); } catch (Exception ex) { socket.Dispose(); + cancellationToken.ThrowIfCancellationRequested(); innerExceptions.Add(ex); } } @@ -183,8 +190,9 @@ namespace FastGithub.HttpServer /// 获取目标终节点 /// /// + /// /// - private async IAsyncEnumerable GetTargetEndPointsAsync(HostString host) + private async IAsyncEnumerable GetUpstreamEndPointsAsync(HostString host, [EnumeratorCancellation] CancellationToken cancellationToken) { var targetHost = host.Host; var targetPort = host.Port ?? HTTPS_PORT; @@ -215,7 +223,7 @@ namespace FastGithub.HttpServer } var dnsEndPoint = new DnsEndPoint(targetHost, targetPort); - await foreach (var item in this.domainResolver.ResolveAsync(dnsEndPoint)) + await foreach (var item in this.domainResolver.ResolveAsync(dnsEndPoint, cancellationToken)) { yield return new IPEndPoint(item, targetPort); } diff --git a/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs b/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs index 5bdf6bc..f9b890f 100644 --- a/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs +++ b/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs @@ -48,7 +48,7 @@ namespace FastGithub } /// - /// 尝试监听ssh反向代理 + /// 监听ssh反向代理 /// /// public static void ListenSshReverseProxy(this KestrelServerOptions kestrel) @@ -57,14 +57,14 @@ namespace FastGithub kestrel.ListenLocalhost(sshPort, listen => { listen.UseFlowAnalyze(); - listen.UseConnectionHandler(); + listen.UseConnectionHandler(); }); kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort},github的ssh反向代理服务启动完成"); } /// - /// 尝试监听git反向代理 + /// 监听git反向代理 /// /// public static void ListenGitReverseProxy(this KestrelServerOptions kestrel) @@ -73,14 +73,14 @@ namespace FastGithub kestrel.ListenLocalhost(gitPort, listen => { listen.UseFlowAnalyze(); - listen.UseConnectionHandler(); + listen.UseConnectionHandler(); }); kestrel.GetLogger().LogInformation($"已监听git://localhost:{gitPort},github的git反向代理服务启动完成"); } /// - /// 尝试监听http反向代理 + /// 监听http反向代理 /// /// public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel) diff --git a/FastGithub.HttpServer/TcpReverseProxyHandler.cs b/FastGithub.HttpServer/TcpReverseProxyHandler.cs index e5eb39b..1456c99 100644 --- a/FastGithub.HttpServer/TcpReverseProxyHandler.cs +++ b/FastGithub.HttpServer/TcpReverseProxyHandler.cs @@ -32,38 +32,42 @@ namespace FastGithub.HttpServer } /// - /// ssh连接后 + /// tcp连接后 /// /// /// public override async Task OnConnectedAsync(ConnectionContext context) { - using var connection = await this.CreateConnectionAsync(); - var task1 = connection.CopyToAsync(context.Transport.Output); - var task2 = context.Transport.Input.CopyToAsync(connection); + var cancellationToken = context.ConnectionClosed; + using var connection = await this.CreateConnectionAsync(cancellationToken); + var task1 = connection.CopyToAsync(context.Transport.Output, cancellationToken); + var task2 = context.Transport.Input.CopyToAsync(connection, cancellationToken); await Task.WhenAny(task1, task2); } /// /// 创建连接 /// + /// /// /// - private async Task CreateConnectionAsync() + private async Task CreateConnectionAsync(CancellationToken cancellationToken) { var innerExceptions = new List(); - await foreach (var address in this.domainResolver.ResolveAsync(this.endPoint)) + await foreach (var address in this.domainResolver.ResolveAsync(this.endPoint, cancellationToken)) { var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { using var timeoutTokenSource = new CancellationTokenSource(this.connectTimeout); - await socket.ConnectAsync(address, this.endPoint.Port, timeoutTokenSource.Token); + using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token); + await socket.ConnectAsync(address, this.endPoint.Port, linkedTokenSource.Token); return new NetworkStream(socket, ownsSocket: false); } catch (Exception ex) { socket.Dispose(); + cancellationToken.ThrowIfCancellationRequested(); innerExceptions.Add(ex); } }