修复代理到自身的循环问题

This commit is contained in:
老九 2021-09-18 21:21:56 +08:00
parent 9ea75853bb
commit a2b6fcc1ab
6 changed files with 44 additions and 26 deletions

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net.Sockets; using System.Net.Sockets;
@ -10,12 +9,7 @@ namespace FastGithub.Configuration
/// 提供本机设备信息 /// 提供本机设备信息
/// </summary> /// </summary>
public static class LocalMachine public static class LocalMachine
{ {
/// <summary>
/// 获取设备名
/// </summary>
public static string Name => Environment.MachineName;
/// <summary> /// <summary>
/// 获取可用的随机Tcp端口 /// 获取可用的随机Tcp端口
/// </summary> /// </summary>

View File

@ -181,7 +181,7 @@ namespace FastGithub.HttpServer
yield break; yield break;
} }
yield return LocalMachine.Name; yield return Environment.MachineName;
yield return IPAddress.Loopback.ToString(); yield return IPAddress.Loopback.ToString();
} }
} }

View File

@ -3,6 +3,7 @@ using FastGithub.DomainResolve;
using Microsoft.AspNetCore.Connections.Features; using Microsoft.AspNetCore.Connections.Features;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Options;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
@ -18,9 +19,13 @@ namespace FastGithub.HttpServer
/// </summary> /// </summary>
sealed class HttpProxyMiddleware sealed class HttpProxyMiddleware
{ {
private const string LOOPBACK = "127.0.0.1";
private const string LOCALHOST = "localhost";
private readonly FastGithubConfig fastGithubConfig; private readonly FastGithubConfig fastGithubConfig;
private readonly IDomainResolver domainResolver; private readonly IDomainResolver domainResolver;
private readonly IHttpForwarder httpForwarder; private readonly IHttpForwarder httpForwarder;
private readonly IOptions<FastGithubOptions> options;
private readonly HttpMessageInvoker httpClient; private readonly HttpMessageInvoker httpClient;
/// <summary> /// <summary>
@ -29,14 +34,17 @@ namespace FastGithub.HttpServer
/// <param name="fastGithubConfig"></param> /// <param name="fastGithubConfig"></param>
/// <param name="domainResolver"></param> /// <param name="domainResolver"></param>
/// <param name="httpForwarder"></param> /// <param name="httpForwarder"></param>
/// <param name="options"></param>
public HttpProxyMiddleware( public HttpProxyMiddleware(
FastGithubConfig fastGithubConfig, FastGithubConfig fastGithubConfig,
IDomainResolver domainResolver, IDomainResolver domainResolver,
IHttpForwarder httpForwarder) IHttpForwarder httpForwarder,
IOptions<FastGithubOptions> options)
{ {
this.fastGithubConfig = fastGithubConfig; this.fastGithubConfig = fastGithubConfig;
this.domainResolver = domainResolver; this.domainResolver = domainResolver;
this.httpForwarder = httpForwarder; this.httpForwarder = httpForwarder;
this.options = options;
this.httpClient = new HttpMessageInvoker(CreateHttpHandler(), disposeHandler: false); this.httpClient = new HttpMessageInvoker(CreateHttpHandler(), disposeHandler: false);
} }
@ -47,15 +55,17 @@ namespace FastGithub.HttpServer
/// <returns></returns> /// <returns></returns>
public async Task InvokeAsync(HttpContext context) public async Task InvokeAsync(HttpContext context)
{ {
if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/proxy.pac") var host = context.Request.Host;
if (this.IsFastGithubServer(host) == true)
{ {
var proxyPac = this.GetProxyPacString(host);
context.Response.ContentType = "application/x-ns-proxy-autoconfig"; context.Response.ContentType = "application/x-ns-proxy-autoconfig";
var pacString = this.GetProxyPacString(context); context.Response.Headers.Add("Content-Disposition", $"attachment;filename=proxy.pac");
await context.Response.WriteAsync(pacString); await context.Response.WriteAsync(proxyPac);
} }
else if (context.Request.Method == HttpMethods.Connect) else if (context.Request.Method == HttpMethods.Connect)
{ {
var endpoint = await this.GetTargetEndPointAsync(context.Request); var endpoint = await this.GetTargetEndPointAsync(host);
using var targetSocket = new Socket(SocketType.Stream, ProtocolType.Tcp); using var targetSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
await targetSocket.ConnectAsync(endpoint); await targetSocket.ConnectAsync(endpoint);
@ -80,16 +90,30 @@ namespace FastGithub.HttpServer
} }
/// <summary>
/// 是否为fastgithub服务
/// </summary>
/// <param name="host"></param>
/// <returns></returns>
private bool IsFastGithubServer(HostString host)
{
if (host.Host == LOOPBACK || host.Host == LOCALHOST)
{
return host.Port == this.options.Value.HttpProxyPort;
}
return false;
}
/// <summary> /// <summary>
/// 获取proxypac脚本 /// 获取proxypac脚本
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="host"></param>
/// <returns></returns> /// <returns></returns>
private string GetProxyPacString(HttpContext context) private string GetProxyPacString(HostString host)
{ {
var buidler = new StringBuilder(); var buidler = new StringBuilder();
buidler.AppendLine("function FindProxyForURL(url, host){"); buidler.AppendLine("function FindProxyForURL(url, host){");
buidler.AppendLine($" var proxy = 'PROXY {context.Request.Host}';"); buidler.AppendLine($" var proxy = 'PROXY {host.Host}';");
foreach (var domain in this.fastGithubConfig.GetDomainPatterns()) foreach (var domain in this.fastGithubConfig.GetDomainPatterns())
{ {
buidler.AppendLine($" if (shExpMatch(host, '{domain}')) return proxy;"); buidler.AppendLine($" if (shExpMatch(host, '{domain}')) return proxy;");
@ -102,13 +126,13 @@ namespace FastGithub.HttpServer
/// <summary> /// <summary>
/// 获取目标终节点 /// 获取目标终节点
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="host"></param>
/// <returns></returns> /// <returns></returns>
private async Task<EndPoint> GetTargetEndPointAsync(HttpRequest request) private async Task<EndPoint> GetTargetEndPointAsync(HostString host)
{ {
const int HTTPS_PORT = 443; const int HTTPS_PORT = 443;
var targetHost = request.Host.Host; var targetHost = host.Host;
var targetPort = request.Host.Port ?? HTTPS_PORT; var targetPort = host.Port ?? HTTPS_PORT;
if (IPAddress.TryParse(targetHost, out var address) == true) if (IPAddress.TryParse(targetHost, out var address) == true)
{ {

View File

@ -62,7 +62,7 @@ namespace FastGithub
await Task.Delay(TimeSpan.FromSeconds(1d), stoppingToken); await Task.Delay(TimeSpan.FromSeconds(1d), stoppingToken);
if (await this.UseFastGithubProxyAsync() == false) if (await this.UseFastGithubProxyAsync() == false)
{ {
this.logger.LogWarning($"请手工设置系统http/https代理为127.0.0.1:38457或自动代理为http://127.0.0.1:38457/proxy.pac"); this.logger.LogWarning($"请手工设置系统http/https代理为127.0.0.1:38457或自动代理为http://127.0.0.1:38457");
} }
} }
} }

View File

@ -380,13 +380,13 @@ code {
<ul> <ul>
<li>执行<code>sudo ./fastgithub</code></li> <li>执行<code>sudo ./fastgithub</code></li>
<li>手工安装cacert/fastgithub.cer到受信任的根证书颁发机构</li> <li>手工安装cacert/fastgithub.cer到受信任的根证书颁发机构</li>
<li>手工设置系统http/https代理为<code>127.0.0.1:38457</code>或自动代理为<code>http://127.0.0.1:38457/proxy.pac</code></li> <li>手工设置系统http/https代理为<code>127.0.0.1:38457</code>或自动代理为<code>http://127.0.0.1:38457</code></li>
</ul> </ul>
<h4 id="23-macos-x64">2.3 macOS-x64</h4> <h4 id="23-macos-x64">2.3 macOS-x64</h4>
<ul> <ul>
<li>双击运行fastgithub程序</li> <li>双击运行fastgithub程序</li>
<li>手工安装cacert/fastgithub.cer并设置信任</li> <li>手工安装cacert/fastgithub.cer并设置信任</li>
<li>手工设置系统http/https代理为<code>127.0.0.1:38457</code>或自动代理为<code>http://127.0.0.1:38457/proxy.pac</code></li> <li>手工设置系统http/https代理为<code>127.0.0.1:38457</code>或自动代理为<code>http://127.0.0.1:38457</code></li>
</ul> </ul>
<h3 id="3-%E8%AF%81%E4%B9%A6%E9%AA%8C%E8%AF%81">3 证书验证</h3> <h3 id="3-%E8%AF%81%E4%B9%A6%E9%AA%8C%E8%AF%81">3 证书验证</h3>
<h4 id="31-git">3.1 git</h4> <h4 id="31-git">3.1 git</h4>

View File

@ -13,12 +13,12 @@ github加速神器解决github打不开、用户头像无法加载、releases
#### 2.2 linux-x64 #### 2.2 linux-x64
* 执行`sudo ./fastgithub` * 执行`sudo ./fastgithub`
* 手工安装cacert/fastgithub.cer到受信任的根证书颁发机构 * 手工安装cacert/fastgithub.cer到受信任的根证书颁发机构
* 手工设置系统http/https代理为`127.0.0.1:38457`或自动代理为`http://127.0.0.1:38457/proxy.pac` * 手工设置系统http/https代理为`127.0.0.1:38457`或自动代理为`http://127.0.0.1:38457`
#### 2.3 macOS-x64 #### 2.3 macOS-x64
* 双击运行fastgithub程序 * 双击运行fastgithub程序
* 手工安装cacert/fastgithub.cer并设置信任 * 手工安装cacert/fastgithub.cer并设置信任
* 手工设置系统http/https代理为`127.0.0.1:38457`或自动代理为`http://127.0.0.1:38457/proxy.pac` * 手工设置系统http/https代理为`127.0.0.1:38457`或自动代理为`http://127.0.0.1:38457`
### 3 证书验证 ### 3 证书验证