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

This commit is contained in:
老九 2021-09-26 20:45:43 +08:00
parent b6348133e4
commit 9086bf79f9
6 changed files with 39 additions and 32 deletions

View File

@ -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?>();

View File

@ -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>

View File

@ -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

View File

@ -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()
{

View File

@ -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);

View File

@ -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();
}
});