diff --git a/FastGithub.Configuration/FastGithubConfig.cs b/FastGithub.Configuration/FastGithubConfig.cs index 21ba6c0..0ed4576 100644 --- a/FastGithub.Configuration/FastGithubConfig.cs +++ b/FastGithub.Configuration/FastGithubConfig.cs @@ -102,5 +102,14 @@ namespace FastGithub.Configuration return key == null ? null : this.domainConfigs[key]; } } + + /// + /// 获取所有域名表达式 + /// + /// + public string[] GetDomainPatterns() + { + return this.domainConfigs.Keys.Select(item => item.ToString()).ToArray(); + } } } diff --git a/FastGithub.Dns/ProxyConflictValidtor.cs b/FastGithub.Dns/ProxyConflictValidtor.cs index 42ed126..2cab07a 100644 --- a/FastGithub.Dns/ProxyConflictValidtor.cs +++ b/FastGithub.Dns/ProxyConflictValidtor.cs @@ -50,11 +50,15 @@ namespace FastGithub.Dns return; } + var httpProxyPort = this.options.Value.HttpProxyPort; + var loopbackProxyUri = new Uri($"http://127.0.0.1:{httpProxyPort}"); + var localhostProxyUri = new Uri($"http://localhost:{httpProxyPort}"); + foreach (var domain in this.options.Value.DomainConfigs.Keys) { var destination = new Uri($"https://{domain.Replace('*', 'a')}"); var proxyServer = systemProxy.GetProxy(destination); - if (proxyServer != null) + if (proxyServer != null && proxyServer != loopbackProxyUri && proxyServer != localhostProxyUri) { this.logger.LogError($"由于系统配置了{proxyServer}代理{domain},{nameof(FastGithub)}无法加速相关域名"); } diff --git a/FastGithub.ReverseProxy/HttpProxyMiddleware.cs b/FastGithub.ReverseProxy/HttpProxyMiddleware.cs index 224e134..6a87873 100644 --- a/FastGithub.ReverseProxy/HttpProxyMiddleware.cs +++ b/FastGithub.ReverseProxy/HttpProxyMiddleware.cs @@ -7,6 +7,7 @@ using System.IO.Pipelines; using System.Net; using System.Net.Http; using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; using Yarp.ReverseProxy.Forwarder; @@ -20,7 +21,7 @@ namespace FastGithub.ReverseProxy private readonly FastGithubConfig fastGithubConfig; private readonly IDomainResolver domainResolver; private readonly IHttpForwarder httpForwarder; - private readonly SocketsHttpHandler socketsHttpHandler = new() { UseCookies = false, UseProxy = false, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.None }; + private readonly HttpMessageInvoker httpClient; /// /// http代理中间件 @@ -36,6 +37,7 @@ namespace FastGithub.ReverseProxy this.fastGithubConfig = fastGithubConfig; this.domainResolver = domainResolver; this.httpForwarder = httpForwarder; + this.httpClient = new HttpMessageInvoker(CreateHttpHandler(), disposeHandler: false); } /// @@ -45,11 +47,26 @@ namespace FastGithub.ReverseProxy /// public async Task InvokeAsync(HttpContext context) { - if (context.Request.Method != HttpMethods.Connect) + if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/proxy.pac") + { + var buidler = new StringBuilder(); + buidler.AppendLine("function FindProxyForURL(url, host){"); + buidler.AppendLine($" var proxy = 'PROXY {context.Request.Host}';"); + foreach (var domain in this.fastGithubConfig.GetDomainPatterns()) + { + buidler.AppendLine($" if (shExpMatch(host, '{domain}')) return proxy;"); + } + buidler.AppendLine(" return 'DIRECT';"); + buidler.AppendLine("}"); + var pacString = buidler.ToString(); + + context.Response.ContentType = "application/x-ns-proxy-autoconfig"; + await context.Response.WriteAsync(pacString); + } + else if (context.Request.Method != HttpMethods.Connect) { - var httpClient = new HttpMessageInvoker(this.socketsHttpHandler, false); var destinationPrefix = $"{context.Request.Scheme}://{context.Request.Host}"; - await this.httpForwarder.SendAsync(context, destinationPrefix, httpClient); + await this.httpForwarder.SendAsync(context, destinationPrefix, this.httpClient); } else { @@ -102,5 +119,21 @@ namespace FastGithub.ReverseProxy address = await this.domainResolver.ResolveAsync(new DnsEndPoint(targetHost, targetPort)); return new IPEndPoint(address, targetPort); } + + /// + /// 创建httpHandler + /// + /// + private static SocketsHttpHandler CreateHttpHandler() + { + return new() + { + Proxy = null, + UseProxy = false, + UseCookies = false, + AllowAutoRedirect = false, + AutomaticDecompression = DecompressionMethods.None + }; + } } } \ No newline at end of file diff --git a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs index ad99cd4..cc0247f 100644 --- a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs +++ b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Net; +using System.Runtime.CompilerServices; namespace FastGithub { diff --git a/FastGithub/Startup.cs b/FastGithub/Startup.cs index c321732..c83c781 100644 --- a/FastGithub/Startup.cs +++ b/FastGithub/Startup.cs @@ -49,25 +49,17 @@ namespace FastGithub /// public void Configure(IApplicationBuilder app) { - if (OperatingSystem.IsWindows()) + var httpProxyPort = app.ApplicationServices.GetRequiredService>().Value.HttpProxyPort; + app.MapWhen(context => context.Connection.LocalPort == httpProxyPort, appBuilder => { - app.UseRequestLogging(); - app.UseHttpReverseProxy(); - } - else - { - var httpProxyPort = app.ApplicationServices.GetRequiredService>().Value.HttpProxyPort; - app.MapWhen(context => context.Connection.LocalPort == httpProxyPort, appBuilder => - { - appBuilder.UseHttpProxy(); - }); + appBuilder.UseHttpProxy(); + }); - app.MapWhen(context => context.Connection.LocalPort != httpProxyPort, appBuilder => - { - appBuilder.UseRequestLogging(); - appBuilder.UseHttpReverseProxy(); - }); - } + app.MapWhen(context => context.Connection.LocalPort != httpProxyPort, appBuilder => + { + appBuilder.UseRequestLogging(); + appBuilder.UseHttpReverseProxy(); + }); } } }