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);
}
}