From 9e559c36fedd089c05ee6a2592806b5102d4f198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Tue, 23 Nov 2021 16:22:30 +0800 Subject: [PATCH] =?UTF-8?q?windows=E5=A2=9E=E5=8A=A0git=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=90=86=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.Configuration/ReverseProxyPort.cs | 8 ++- .../GitReverseProxyHandler.cs | 19 +++++ .../KestrelServerOptionsExtensions.cs | 19 ++++- .../SshReverseProxyHandler.cs | 29 +------- .../TcpReverseProxyHandler.cs | 70 +++++++++++++++++++ .../ServiceCollectionExtensions.cs | 1 + .../Tcp/GitInterceptor.cs | 22 ++++++ FastGithub/Program.cs | 1 + 8 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 FastGithub.HttpServer/GitReverseProxyHandler.cs create mode 100644 FastGithub.HttpServer/TcpReverseProxyHandler.cs create mode 100644 FastGithub.PacketIntercept/Tcp/GitInterceptor.cs diff --git a/FastGithub.Configuration/ReverseProxyPort.cs b/FastGithub.Configuration/ReverseProxyPort.cs index 644ebca..488d27d 100644 --- a/FastGithub.Configuration/ReverseProxyPort.cs +++ b/FastGithub.Configuration/ReverseProxyPort.cs @@ -15,6 +15,11 @@ namespace FastGithub.Configuration /// public static int Ssh { get; } + /// + /// git端口 + /// + public static int Git { get; } + /// /// http端口 /// @@ -31,7 +36,8 @@ namespace FastGithub.Configuration static ReverseProxyPort() { var ports = new TcpListenerPortCollection(); - Ssh = OperatingSystem.IsWindows() ? ports.GetAvailablePort(22) : ports.GetAvailablePort(3822); + Ssh = ports.GetAvailablePort(22); + Git = ports.GetAvailablePort(9418); Http = OperatingSystem.IsWindows() ? ports.GetAvailablePort(80) : ports.GetAvailablePort(3880); Https = OperatingSystem.IsWindows() ? ports.GetAvailablePort(443) : ports.GetAvailablePort(38443); } diff --git a/FastGithub.HttpServer/GitReverseProxyHandler.cs b/FastGithub.HttpServer/GitReverseProxyHandler.cs new file mode 100644 index 0000000..14a6b1f --- /dev/null +++ b/FastGithub.HttpServer/GitReverseProxyHandler.cs @@ -0,0 +1,19 @@ +using FastGithub.DomainResolve; + +namespace FastGithub.HttpServer +{ + /// + /// github的git代理处理者 + /// + sealed class GitReverseProxyHandler : TcpReverseProxyHandler + { + /// + /// github的git代理处理者 + /// + /// + public GitReverseProxyHandler(IDomainResolver domainResolver) + : base(domainResolver, new("github.com", 9418)) + { + } + } +} diff --git a/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs b/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs index 38e7fe2..5bdf6bc 100644 --- a/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs +++ b/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs @@ -60,10 +60,23 @@ namespace FastGithub listen.UseConnectionHandler(); }); - if (OperatingSystem.IsWindows()) + kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort},github的ssh反向代理服务启动完成"); + } + + /// + /// 尝试监听git反向代理 + /// + /// + public static void ListenGitReverseProxy(this KestrelServerOptions kestrel) + { + var gitPort = ReverseProxyPort.Git; + kestrel.ListenLocalhost(gitPort, listen => { - kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort},github的ssh反向代理服务启动完成"); - } + listen.UseFlowAnalyze(); + listen.UseConnectionHandler(); + }); + + kestrel.GetLogger().LogInformation($"已监听git://localhost:{gitPort},github的git反向代理服务启动完成"); } /// diff --git a/FastGithub.HttpServer/SshReverseProxyHandler.cs b/FastGithub.HttpServer/SshReverseProxyHandler.cs index 386e030..c426351 100644 --- a/FastGithub.HttpServer/SshReverseProxyHandler.cs +++ b/FastGithub.HttpServer/SshReverseProxyHandler.cs @@ -1,44 +1,19 @@ using FastGithub.DomainResolve; -using Microsoft.AspNetCore.Connections; -using System.IO.Pipelines; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; namespace FastGithub.HttpServer { /// /// github的ssh代理处理者 /// - sealed class SshReverseProxyHandler : ConnectionHandler + sealed class SshReverseProxyHandler : TcpReverseProxyHandler { - private readonly IDomainResolver domainResolver; - private readonly DnsEndPoint sshOverHttpsEndPoint = new("ssh.github.com", 443); - /// /// github的ssh代理处理者 /// /// public SshReverseProxyHandler(IDomainResolver domainResolver) + : base(domainResolver, new("ssh.github.com", 443)) { - this.domainResolver = domainResolver; - } - - /// - /// ssh连接后 - /// - /// - /// - public override async Task OnConnectedAsync(ConnectionContext context) - { - var address = await this.domainResolver.ResolveAnyAsync(this.sshOverHttpsEndPoint); - using var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - await socket.ConnectAsync(address, this.sshOverHttpsEndPoint.Port); - var targetStream = new NetworkStream(socket, ownsSocket: false); - - var task1 = targetStream.CopyToAsync(context.Transport.Output); - var task2 = context.Transport.Input.CopyToAsync(targetStream); - await Task.WhenAny(task1, task2); } } } diff --git a/FastGithub.HttpServer/TcpReverseProxyHandler.cs b/FastGithub.HttpServer/TcpReverseProxyHandler.cs new file mode 100644 index 0000000..a0b1217 --- /dev/null +++ b/FastGithub.HttpServer/TcpReverseProxyHandler.cs @@ -0,0 +1,70 @@ +using FastGithub.DomainResolve; +using Microsoft.AspNetCore.Connections; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Pipelines; +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; + +namespace FastGithub.HttpServer +{ + /// + /// tcp反射代理处理者 + /// + abstract class TcpReverseProxyHandler : ConnectionHandler + { + private readonly IDomainResolver domainResolver; + private readonly DnsEndPoint endPoint; + + /// + /// tcp反射代理处理者 + /// + /// + /// + public TcpReverseProxyHandler(IDomainResolver domainResolver, DnsEndPoint endPoint) + { + this.domainResolver = domainResolver; + this.endPoint = endPoint; + } + + /// + /// ssh连接后 + /// + /// + /// + public override async Task OnConnectedAsync(ConnectionContext context) + { + var targetStream = await this.CreateConnectionAsync(); + var task1 = targetStream.CopyToAsync(context.Transport.Output); + var task2 = context.Transport.Input.CopyToAsync(targetStream); + await Task.WhenAny(task1, task2); + } + + /// + /// 创建连接 + /// + /// + /// + private async Task CreateConnectionAsync() + { + var innerExceptions = new List(); + await foreach (var address in this.domainResolver.ResolveAllAsync(this.endPoint)) + { + var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + try + { + await socket.ConnectAsync(address, this.endPoint.Port); + return new NetworkStream(socket, ownsSocket: false); + } + catch (Exception ex) + { + socket.Dispose(); + innerExceptions.Add(ex); + } + } + throw new AggregateException($"无法连接到{this.endPoint.Host}:{this.endPoint.Port}", innerExceptions); + } + } +} diff --git a/FastGithub.PacketIntercept/ServiceCollectionExtensions.cs b/FastGithub.PacketIntercept/ServiceCollectionExtensions.cs index b3fbe5e..dfe1a7c 100644 --- a/FastGithub.PacketIntercept/ServiceCollectionExtensions.cs +++ b/FastGithub.PacketIntercept/ServiceCollectionExtensions.cs @@ -26,6 +26,7 @@ namespace FastGithub services.AddHostedService(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddHostedService(); diff --git a/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs b/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs new file mode 100644 index 0000000..fb2597b --- /dev/null +++ b/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs @@ -0,0 +1,22 @@ +using FastGithub.Configuration; +using Microsoft.Extensions.Logging; +using System.Runtime.Versioning; + +namespace FastGithub.PacketIntercept.Tcp +{ + /// + /// git拦截器 + /// + [SupportedOSPlatform("windows")] + sealed class GitInterceptor : TcpInterceptor + { + /// + /// git拦截器 + /// + /// + public GitInterceptor(ILogger logger) + : base(9418, ReverseProxyPort.Git, logger) + { + } + } +} diff --git a/FastGithub/Program.cs b/FastGithub/Program.cs index 8a724c7..94b4b87 100644 --- a/FastGithub/Program.cs +++ b/FastGithub/Program.cs @@ -72,6 +72,7 @@ namespace FastGithub if (OperatingSystem.IsWindows()) { kestrel.ListenSshReverseProxy(); + kestrel.ListenGitReverseProxy(); } else {