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
{