Преглед изворни кода

windows增加git协议的代理支持

陈国伟 пре 3 година
родитељ
комит
9e559c36fe

+ 7 - 1
FastGithub.Configuration/ReverseProxyPort.cs

@@ -15,6 +15,11 @@ namespace FastGithub.Configuration
         /// </summary>
         public static int Ssh { get; }
 
+        /// <summary>
+        /// git端口
+        /// </summary>
+        public static int Git { get; }
+
         /// <summary>
         /// http端口
         /// </summary>
@@ -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);
         }

+ 19 - 0
FastGithub.HttpServer/GitReverseProxyHandler.cs

@@ -0,0 +1,19 @@
+using FastGithub.DomainResolve;
+
+namespace FastGithub.HttpServer
+{
+    /// <summary>
+    /// github的git代理处理者
+    /// </summary>
+    sealed class GitReverseProxyHandler : TcpReverseProxyHandler
+    {
+        /// <summary>
+        /// github的git代理处理者
+        /// </summary>
+        /// <param name="domainResolver"></param>
+        public GitReverseProxyHandler(IDomainResolver domainResolver)
+            : base(domainResolver, new("github.com", 9418))
+        {
+        }
+    }
+}

+ 16 - 3
FastGithub.HttpServer/KestrelServerOptionsExtensions.cs

@@ -60,10 +60,23 @@ namespace FastGithub
                 listen.UseConnectionHandler<SshReverseProxyHandler>();
             });
 
-            if (OperatingSystem.IsWindows())
+            kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort},github的ssh反向代理服务启动完成");
+        }
+
+        /// <summary>
+        /// 尝试监听git反向代理
+        /// </summary>
+        /// <param name="kestrel"></param>
+        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<GitReverseProxyHandler>();
+            });
+
+            kestrel.GetLogger().LogInformation($"已监听git://localhost:{gitPort},github的git反向代理服务启动完成");
         }
 
         /// <summary>

+ 2 - 27
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
 {
     /// <summary>
     /// github的ssh代理处理者
     /// </summary>
-    sealed class SshReverseProxyHandler : ConnectionHandler
+    sealed class SshReverseProxyHandler : TcpReverseProxyHandler
     {
-        private readonly IDomainResolver domainResolver;
-        private readonly DnsEndPoint sshOverHttpsEndPoint = new("ssh.github.com", 443);
-
         /// <summary>
         /// github的ssh代理处理者
         /// </summary>
         /// <param name="domainResolver"></param>
         public SshReverseProxyHandler(IDomainResolver domainResolver)
+            : base(domainResolver, new("ssh.github.com", 443))
         {
-            this.domainResolver = domainResolver;
-        }
-
-        /// <summary>
-        /// ssh连接后
-        /// </summary>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        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);
         }
     }
 }

+ 70 - 0
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
+{
+    /// <summary>
+    /// tcp反射代理处理者
+    /// </summary>
+    abstract class TcpReverseProxyHandler : ConnectionHandler
+    {
+        private readonly IDomainResolver domainResolver;
+        private readonly DnsEndPoint endPoint;
+
+        /// <summary>
+        /// tcp反射代理处理者
+        /// </summary>
+        /// <param name="domainResolver"></param>
+        /// <param name="endPoint"></param>
+        public TcpReverseProxyHandler(IDomainResolver domainResolver, DnsEndPoint endPoint)
+        {
+            this.domainResolver = domainResolver;
+            this.endPoint = endPoint;
+        }
+
+        /// <summary>
+        /// ssh连接后
+        /// </summary>
+        /// <param name="context"></param>
+        /// <returns></returns>
+        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);
+        }
+
+        /// <summary>
+        /// 创建连接
+        /// </summary>
+        /// <returns></returns>
+        /// <exception cref="AggregateException"></exception>
+        private async Task<Stream> CreateConnectionAsync()
+        {
+            var innerExceptions = new List<Exception>();
+            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);
+        }
+    }
+}

+ 1 - 0
FastGithub.PacketIntercept/ServiceCollectionExtensions.cs

@@ -26,6 +26,7 @@ namespace FastGithub
             services.AddHostedService<DnsInterceptHostedService>();
 
             services.AddSingleton<ITcpInterceptor, SshInterceptor>();
+            services.AddSingleton<ITcpInterceptor, GitInterceptor>();
             services.AddSingleton<ITcpInterceptor, HttpInterceptor>();
             services.AddSingleton<ITcpInterceptor, HttpsInterceptor>();
             services.AddHostedService<TcpInterceptHostedService>();

+ 22 - 0
FastGithub.PacketIntercept/Tcp/GitInterceptor.cs

@@ -0,0 +1,22 @@
+using FastGithub.Configuration;
+using Microsoft.Extensions.Logging;
+using System.Runtime.Versioning;
+
+namespace FastGithub.PacketIntercept.Tcp
+{
+    /// <summary>
+    /// git拦截器
+    /// </summary>   
+    [SupportedOSPlatform("windows")]
+    sealed class GitInterceptor : TcpInterceptor
+    {
+        /// <summary>
+        /// git拦截器
+        /// </summary>
+        /// <param name="logger"></param>
+        public GitInterceptor(ILogger<HttpInterceptor> logger)
+            : base(9418, ReverseProxyPort.Git, logger)
+        {
+        }
+    }
+}

+ 1 - 0
FastGithub/Program.cs

@@ -72,6 +72,7 @@ namespace FastGithub
                         if (OperatingSystem.IsWindows())
                         {
                             kestrel.ListenSshReverseProxy();
+                            kestrel.ListenGitReverseProxy();
                         }
                         else
                         {