Ver código fonte

代理的http流量应用域名配置

老九 3 anos atrás
pai
commit
9086bf79f9

+ 7 - 0
FastGithub.Configuration/FastGithubConfig.cs

@@ -15,6 +15,11 @@ namespace FastGithub.Configuration
         private SortedDictionary<DomainPattern, DomainConfig> domainConfigs;
         private ConcurrentDictionary<string, DomainConfig?> domainConfigCache;
 
+        /// <summary>
+        /// http代理端口
+        /// </summary>
+        public int HttpProxyPort { get; set; }
+
         /// <summary>
         /// 回退的dns
         /// </summary>
@@ -29,6 +34,7 @@ namespace FastGithub.Configuration
         {
             var opt = options.CurrentValue;
 
+            this.HttpProxyPort = opt.HttpProxyPort;
             this.FallbackDns = ConvertToIPEndPoints(opt.FallbackDns).ToArray();
             this.domainConfigs = ConvertDomainConfigs(opt.DomainConfigs);
             this.domainConfigCache = new ConcurrentDictionary<string, DomainConfig?>();
@@ -42,6 +48,7 @@ namespace FastGithub.Configuration
         /// <param name="options"></param>
         private void Update(FastGithubOptions options)
         {
+            this.HttpProxyPort = options.HttpProxyPort;
             this.FallbackDns = ConvertToIPEndPoints(options.FallbackDns).ToArray();
             this.domainConfigs = ConvertDomainConfigs(options.DomainConfigs);
             this.domainConfigCache = new ConcurrentDictionary<string, DomainConfig?>();

+ 2 - 2
FastGithub.DomainResolve/DomainResolver.cs

@@ -38,13 +38,13 @@ namespace FastGithub.DomainResolve
         /// <param name="domain">域名</param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public async Task<IPAddress?> ResolveAsync(string domain, CancellationToken cancellationToken = default)
+        public async Task<IPAddress> ResolveAsync(string domain, CancellationToken cancellationToken = default)
         {
             await foreach (var address in this.ResolveAllAsync(domain, cancellationToken))
             {
                 return address;
             }
-            return default;
+            throw new FastGithubException($"解析不到{domain}的IP");
         }
 
         /// <summary>

+ 1 - 1
FastGithub.DomainResolve/IDomainResolver.cs

@@ -16,7 +16,7 @@ namespace FastGithub.DomainResolve
         /// <param name="domain">域名</param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        Task<IPAddress?> ResolveAsync(string domain, CancellationToken cancellationToken = default);
+        Task<IPAddress> ResolveAsync(string domain, CancellationToken cancellationToken = default);
 
         /// <summary>
         /// 解析所有ip

+ 24 - 18
FastGithub.HttpServer/HttpProxyMiddleware.cs

@@ -3,7 +3,6 @@ using FastGithub.DomainResolve;
 using Microsoft.AspNetCore.Connections.Features;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http.Features;
-using Microsoft.Extensions.Options;
 using System.IO.Pipelines;
 using System.Net;
 using System.Net.Http;
@@ -25,8 +24,9 @@ namespace FastGithub.HttpServer
         private readonly FastGithubConfig fastGithubConfig;
         private readonly IDomainResolver domainResolver;
         private readonly IHttpForwarder httpForwarder;
-        private readonly IOptions<FastGithubOptions> options;
-        private readonly HttpMessageInvoker httpClient;
+        private readonly HttpReverseProxyMiddleware httpReverseProxy;
+
+        private readonly HttpMessageInvoker defaultHttpClient;
 
         /// <summary>
         /// http代理中间件
@@ -34,18 +34,19 @@ namespace FastGithub.HttpServer
         /// <param name="fastGithubConfig"></param>
         /// <param name="domainResolver"></param>
         /// <param name="httpForwarder"></param>
-        /// <param name="options"></param>
+        /// <param name="httpReverseProxy"></param>
         public HttpProxyMiddleware(
             FastGithubConfig fastGithubConfig,
             IDomainResolver domainResolver,
             IHttpForwarder httpForwarder,
-            IOptions<FastGithubOptions> options)
+            HttpReverseProxyMiddleware httpReverseProxy)
         {
             this.fastGithubConfig = fastGithubConfig;
             this.domainResolver = domainResolver;
             this.httpForwarder = httpForwarder;
-            this.options = options;
-            this.httpClient = new HttpMessageInvoker(CreateHttpHandler(), disposeHandler: false);
+            this.httpReverseProxy = httpReverseProxy;
+
+            this.defaultHttpClient = new HttpMessageInvoker(CreateDefaultHttpHandler(), disposeHandler: false);
         }
 
         /// <summary>
@@ -84,12 +85,14 @@ namespace FastGithub.HttpServer
             }
             else
             {
-                var destinationPrefix = $"{context.Request.Scheme}://{context.Request.Host}";
-                await this.httpForwarder.SendAsync(context, destinationPrefix, this.httpClient);
+                await this.httpReverseProxy.InvokeAsync(context, async ctx =>
+                {
+                    var destinationPrefix = $"{ctx.Request.Scheme}://{ctx.Request.Host}";
+                    await this.httpForwarder.SendAsync(ctx, destinationPrefix, this.defaultHttpClient);
+                });
             }
         }
 
-
         /// <summary>
         /// 是否为fastgithub服务
         /// </summary>
@@ -99,7 +102,7 @@ namespace FastGithub.HttpServer
         {
             if (host.Host == LOOPBACK || host.Host == LOCALHOST)
             {
-                return host.Port == this.options.Value.HttpProxyPort;
+                return host.Port == this.fastGithubConfig.HttpProxyPort;
             }
             return false;
         }
@@ -130,6 +133,7 @@ namespace FastGithub.HttpServer
         /// <returns></returns>
         private async Task<EndPoint> GetTargetEndPointAsync(HostString host)
         {
+            const int HTTP_PORT = 80;
             const int HTTPS_PORT = 443;
             var targetHost = host.Host;
             var targetPort = host.Port ?? HTTPS_PORT;
@@ -145,24 +149,26 @@ namespace FastGithub.HttpServer
                 return new DnsEndPoint(targetHost, targetPort);
             }
 
-            // 目标端口为443,走https代理中间人           
-            if (targetPort == HTTPS_PORT && targetHost != "ssh.github.com")
+            if (targetPort == HTTP_PORT)
+            {
+                return new IPEndPoint(IPAddress.Loopback, ReverseProxyPort.Http);
+            }
+
+            if (targetPort == HTTPS_PORT)
             {
                 return new IPEndPoint(IPAddress.Loopback, ReverseProxyPort.Https);
             }
 
-            // dns优选
+            // 不使用系统dns
             address = await this.domainResolver.ResolveAsync(targetHost);
-            return address == null
-                ? throw new FastGithubException($"解析不到{targetHost}的IP")
-                : new IPEndPoint(address, targetPort);
+            return new IPEndPoint(address, targetPort);
         }
 
         /// <summary>
         /// 创建httpHandler
         /// </summary>
         /// <returns></returns>
-        private static SocketsHttpHandler CreateHttpHandler()
+        private static SocketsHttpHandler CreateDefaultHttpHandler()
         {
             return new()
             {

+ 1 - 7
FastGithub.HttpServer/SshReverseProxyHandler.cs

@@ -1,5 +1,4 @@
-using FastGithub.Configuration;
-using FastGithub.DomainResolve;
+using FastGithub.DomainResolve;
 using Microsoft.AspNetCore.Connections;
 using System.IO.Pipelines;
 using System.Net.Sockets;
@@ -33,11 +32,6 @@ namespace FastGithub.HttpServer
         public override async Task OnConnectedAsync(ConnectionContext context)
         {
             var address = await this.domainResolver.ResolveAsync(SSH_GITHUB_COM);
-            if (address == null)
-            {
-                throw new FastGithubException($"解析不到{SSH_GITHUB_COM}的IP");
-            }
-
             using var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
             await socket.ConnectAsync(address, SSH_OVER_HTTPS_PORT);
             var targetStream = new NetworkStream(socket, ownsSocket: false);

+ 4 - 4
FastGithub/Program.cs

@@ -27,7 +27,7 @@ namespace FastGithub
         {
             return Host
                 .CreateDefaultBuilder(args)
-                .UseWindowsService() 
+                .UseWindowsService()
                 .UseDefaultServiceProvider(c =>
                 {
                     c.ValidateOnBuild = false;
@@ -51,15 +51,15 @@ namespace FastGithub
                     webBuilder.UseKestrel(kestrel =>
                     {
                         kestrel.NoLimit();
+                        kestrel.ListenHttpsReverseProxy();
+                        kestrel.ListenHttpReverseProxy();
+
                         if (OperatingSystem.IsWindows())
                         {
-                            kestrel.ListenHttpsReverseProxy();
-                            kestrel.ListenHttpReverseProxy();
                             kestrel.ListenSshReverseProxy();
                         }
                         else
                         {
-                            kestrel.ListenHttpsReverseProxy();
                             kestrel.ListenHttpProxy();
                         }
                     });