优化反向代理
This commit is contained in:
parent
310406d77c
commit
c33d904013
@ -1,61 +0,0 @@
|
|||||||
using FastGithub.Scanner;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FastGithub.ReverseProxy
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Github的dns解析的httpHandler
|
|
||||||
/// 使扫描索结果作为github的https请求的域名解析
|
|
||||||
/// </summary>
|
|
||||||
sealed class GithubDnsHttpHandler : DelegatingHandler
|
|
||||||
{
|
|
||||||
private readonly IGithubScanResults scanResults;
|
|
||||||
private readonly ILogger logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Github的dns解析的httpHandler
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scanResults"></param>
|
|
||||||
/// <param name="innerHandler"></param>
|
|
||||||
public GithubDnsHttpHandler(
|
|
||||||
IGithubScanResults scanResults,
|
|
||||||
HttpMessageHandler innerHandler,
|
|
||||||
ILogger logger)
|
|
||||||
: base(innerHandler)
|
|
||||||
{
|
|
||||||
this.scanResults = scanResults;
|
|
||||||
this.logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发送消息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var uri = request.RequestUri;
|
|
||||||
if (uri != null && uri.HostNameType == UriHostNameType.Dns)
|
|
||||||
{
|
|
||||||
var address = this.scanResults.FindBestAddress(uri.Host);
|
|
||||||
if (address != null)
|
|
||||||
{
|
|
||||||
this.logger.LogInformation($"使用{address}请求{uri.Host}");
|
|
||||||
var builder = new UriBuilder(uri)
|
|
||||||
{
|
|
||||||
Host = address.ToString()
|
|
||||||
};
|
|
||||||
request.RequestUri = builder.Uri;
|
|
||||||
request.Headers.Host = uri.Host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return await base.SendAsync(request, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
114
FastGithub.ReverseProxy/GithubHttpClientHanlder.cs
Normal file
114
FastGithub.ReverseProxy/GithubHttpClientHanlder.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
using FastGithub.Scanner;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FastGithub.ReverseProxy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用于请求github的HttpClientHandler
|
||||||
|
/// </summary>
|
||||||
|
[Service(ServiceLifetime.Transient)]
|
||||||
|
sealed class GithubHttpClientHanlder : DelegatingHandler
|
||||||
|
{
|
||||||
|
private readonly IGithubScanResults githubScanResults;
|
||||||
|
private readonly ILogger<GithubHttpClientHanlder> logger;
|
||||||
|
private readonly IMemoryCache memoryCache;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求github的HttpClientHandler
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="githubScanResults"></param>
|
||||||
|
/// <param name="logger"></param>
|
||||||
|
public GithubHttpClientHanlder(
|
||||||
|
IGithubScanResults githubScanResults,
|
||||||
|
ILogger<GithubHttpClientHanlder> logger,
|
||||||
|
IMemoryCache memoryCache)
|
||||||
|
{
|
||||||
|
this.githubScanResults = githubScanResults;
|
||||||
|
this.logger = logger;
|
||||||
|
this.memoryCache = memoryCache;
|
||||||
|
this.InnerHandler = CreateNoneSniHttpHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建无Sni发送的httpHandler
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static HttpMessageHandler CreateNoneSniHttpHandler()
|
||||||
|
{
|
||||||
|
return new SocketsHttpHandler
|
||||||
|
{
|
||||||
|
Proxy = null,
|
||||||
|
UseProxy = false,
|
||||||
|
AllowAutoRedirect = false,
|
||||||
|
ConnectCallback = async (ctx, ct) =>
|
||||||
|
{
|
||||||
|
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
await socket.ConnectAsync(ctx.DnsEndPoint, ct);
|
||||||
|
var stream = new NetworkStream(socket, ownsSocket: true);
|
||||||
|
if (ctx.InitialRequestMessage.Headers.Host == null)
|
||||||
|
{
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sslStream = new SslStream(stream, leaveInnerStreamOpen: false);
|
||||||
|
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
|
||||||
|
{
|
||||||
|
TargetHost = string.Empty,
|
||||||
|
RemoteCertificateValidationCallback = delegate { return true; }
|
||||||
|
}, ct);
|
||||||
|
return sslStream;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找最快的ip来发送消息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var uri = request.RequestUri;
|
||||||
|
if (uri != null && uri.HostNameType == UriHostNameType.Dns)
|
||||||
|
{
|
||||||
|
var address = this.Resolve(uri.Host);
|
||||||
|
if (address != null)
|
||||||
|
{
|
||||||
|
this.logger.LogInformation($"使用{address}请求{uri.Host}");
|
||||||
|
var builder = new UriBuilder(uri)
|
||||||
|
{
|
||||||
|
Host = address.ToString()
|
||||||
|
};
|
||||||
|
request.RequestUri = builder.Uri;
|
||||||
|
request.Headers.Host = uri.Host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await base.SendAsync(request, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析域名
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="domain"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private IPAddress? Resolve(string domain)
|
||||||
|
{
|
||||||
|
return this.memoryCache.GetOrCreate(typeof(GithubHttpClientHanlder), e =>
|
||||||
|
{
|
||||||
|
e.SetAbsoluteExpiration(TimeSpan.FromSeconds(1d));
|
||||||
|
return this.githubScanResults.FindBestAddress(domain);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,11 +13,6 @@ namespace FastGithub.ReverseProxy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enable { get; set; } = true;
|
public bool Enable { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 每个服务的最大代理连接数
|
|
||||||
/// </summary>
|
|
||||||
public int MaxConnectionsPerServer { get; set; } = int.MaxValue;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 请求配置
|
/// 请求配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace FastGithub.ReverseProxy
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 表示自主管理生命周期的的HttpMessageHandler
|
|
||||||
/// </summary>
|
|
||||||
[DebuggerDisplay("LifeTime = {lifeTime}")]
|
|
||||||
sealed class LifetimeHttpHandler : DelegatingHandler
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 生命周期
|
|
||||||
/// </summary>
|
|
||||||
private readonly TimeSpan lifeTime;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Token取消源
|
|
||||||
/// </summary>
|
|
||||||
private readonly CancellationTokenSource tokenSource = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 具有生命周期的HttpHandler
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">HttpHandler</param>
|
|
||||||
/// <param name="lifeTime">拦截器的生命周期</param>
|
|
||||||
/// <param name="deactivateAction">失效回调</param>
|
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
|
||||||
public LifetimeHttpHandler(HttpMessageHandler handler, TimeSpan lifeTime, Action<LifetimeHttpHandler> deactivateAction)
|
|
||||||
: base(handler)
|
|
||||||
{
|
|
||||||
if (deactivateAction == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(deactivateAction));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lifeTime = lifeTime;
|
|
||||||
|
|
||||||
this.tokenSource.Token.Register(() =>
|
|
||||||
{
|
|
||||||
this.tokenSource.Dispose();
|
|
||||||
deactivateAction.Invoke(this);
|
|
||||||
}, useSynchronizationContext: false);
|
|
||||||
|
|
||||||
this.tokenSource.CancelAfter(lifeTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 这里不释放资源
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing"></param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FastGithub.ReverseProxy
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 表示LifetimeHttpHandler清理器
|
|
||||||
/// </summary>
|
|
||||||
sealed class LifetimeHttpHandlerCleaner
|
|
||||||
{
|
|
||||||
private readonly ILogger logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前监视生命周期的记录的数量
|
|
||||||
/// </summary>
|
|
||||||
private int trackingEntryCount = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 监视生命周期的记录队列
|
|
||||||
/// </summary>
|
|
||||||
private readonly ConcurrentQueue<TrackingEntry> trackingEntries = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取或设置清理的时间间隔
|
|
||||||
/// 默认10s
|
|
||||||
/// </summary>
|
|
||||||
public TimeSpan CleanupInterval { get; set; } = TimeSpan.FromSeconds(10d);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// LifetimeHttpHandler清理器
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
public LifetimeHttpHandlerCleaner(ILogger logger)
|
|
||||||
{
|
|
||||||
this.logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 添加要清除的httpHandler
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">httpHandler</param>
|
|
||||||
public void Add(LifetimeHttpHandler handler)
|
|
||||||
{
|
|
||||||
var entry = new TrackingEntry(handler);
|
|
||||||
this.trackingEntries.Enqueue(entry);
|
|
||||||
|
|
||||||
// 从0变为1,要启动清理作业
|
|
||||||
if (Interlocked.Increment(ref this.trackingEntryCount) == 1)
|
|
||||||
{
|
|
||||||
this.StartCleanup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 启动清理作业
|
|
||||||
/// </summary>
|
|
||||||
private async void StartCleanup()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
await Task.Delay(this.CleanupInterval);
|
|
||||||
if (this.Cleanup() == true)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
this.logger.LogError(ex, "清理HttpMessageHandler出现不可预期的异常");
|
|
||||||
// 这是应该不可能发生的
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清理失效的拦截器
|
|
||||||
/// 返回是否完全清理
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool Cleanup()
|
|
||||||
{
|
|
||||||
var cleanCount = this.trackingEntries.Count;
|
|
||||||
this.logger.LogTrace($"尝试清理{cleanCount}条HttpMessageHandler");
|
|
||||||
|
|
||||||
for (var i = 0; i < cleanCount; i++)
|
|
||||||
{
|
|
||||||
this.trackingEntries.TryDequeue(out var entry);
|
|
||||||
Debug.Assert(entry != null);
|
|
||||||
|
|
||||||
if (entry.CanDispose == false)
|
|
||||||
{
|
|
||||||
this.trackingEntries.Enqueue(entry);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.LogTrace($"释放了{entry.GetHashCode()}@HttpMessageHandler");
|
|
||||||
entry.Dispose();
|
|
||||||
if (Interlocked.Decrement(ref this.trackingEntryCount) == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 表示监视生命周期的记录
|
|
||||||
/// </summary>
|
|
||||||
private class TrackingEntry : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用于释放资源的对象
|
|
||||||
/// </summary>
|
|
||||||
private readonly IDisposable disposable;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 监视对象的弱引用
|
|
||||||
/// </summary>
|
|
||||||
private readonly WeakReference weakReference;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取是否可以释放资源
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool CanDispose => this.weakReference.IsAlive == false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 监视生命周期的记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">激活状态的httpHandler</param>
|
|
||||||
public TrackingEntry(LifetimeHttpHandler handler)
|
|
||||||
{
|
|
||||||
this.disposable = handler.InnerHandler!;
|
|
||||||
this.weakReference = new WeakReference(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放资源
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.disposable.Dispose();
|
|
||||||
}
|
|
||||||
catch (Exception) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,111 +0,0 @@
|
|||||||
using FastGithub.Scanner;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Security;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
|
|
||||||
namespace FastGithub.ReverseProxy
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 禁用tls sni的HttpClient工厂
|
|
||||||
/// </summary>
|
|
||||||
[Service(ServiceLifetime.Singleton)]
|
|
||||||
sealed class NoneSniHttpClientFactory
|
|
||||||
{
|
|
||||||
private readonly IGithubScanResults githubScanResults;
|
|
||||||
private readonly IOptionsMonitor<GithubReverseProxyOptions> options;
|
|
||||||
private readonly ILogger<NoneSniHttpClientFactory> logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生命周期
|
|
||||||
/// </summary>
|
|
||||||
private readonly TimeSpan lifeTime = TimeSpan.FromMinutes(2d);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 具有生命周期的httpHandler延时创建对象
|
|
||||||
/// </summary>
|
|
||||||
private volatile Lazy<LifetimeHttpHandler> lifeTimeHttpHandlerLazy;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// HttpHandler清理器
|
|
||||||
/// </summary>
|
|
||||||
private readonly LifetimeHttpHandlerCleaner httpHandlerCleaner;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 禁用tls sni的HttpClient工厂
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="githubScanResults"></param>
|
|
||||||
public NoneSniHttpClientFactory(
|
|
||||||
IGithubScanResults githubScanResults,
|
|
||||||
IOptionsMonitor<GithubReverseProxyOptions> options,
|
|
||||||
ILogger<NoneSniHttpClientFactory> logger)
|
|
||||||
{
|
|
||||||
this.githubScanResults = githubScanResults;
|
|
||||||
this.options = options;
|
|
||||||
this.logger = logger;
|
|
||||||
this.lifeTimeHttpHandlerLazy = new Lazy<LifetimeHttpHandler>(this.CreateHttpHandler, true);
|
|
||||||
this.httpHandlerCleaner = new LifetimeHttpHandlerCleaner(logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建HttpClient
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public HttpMessageInvoker CreateHttpClient()
|
|
||||||
{
|
|
||||||
var handler = this.lifeTimeHttpHandlerLazy.Value;
|
|
||||||
return new HttpMessageInvoker(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建具有生命周期控制的httpHandler
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private LifetimeHttpHandler CreateHttpHandler()
|
|
||||||
{
|
|
||||||
var noneSniHandler = new SocketsHttpHandler
|
|
||||||
{
|
|
||||||
Proxy = null,
|
|
||||||
UseProxy = false,
|
|
||||||
AllowAutoRedirect = false,
|
|
||||||
MaxConnectionsPerServer = this.options.CurrentValue.MaxConnectionsPerServer,
|
|
||||||
ConnectCallback = async (ctx, ct) =>
|
|
||||||
{
|
|
||||||
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
|
||||||
await socket.ConnectAsync(ctx.DnsEndPoint, ct);
|
|
||||||
var stream = new NetworkStream(socket, ownsSocket: true);
|
|
||||||
if (ctx.InitialRequestMessage.Headers.Host == null)
|
|
||||||
{
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sslStream = new SslStream(stream, leaveInnerStreamOpen: false);
|
|
||||||
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
|
|
||||||
{
|
|
||||||
TargetHost = string.Empty,
|
|
||||||
RemoteCertificateValidationCallback = delegate { return true; }
|
|
||||||
}, ct);
|
|
||||||
return sslStream;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var dnsHandler = new GithubDnsHttpHandler(this.githubScanResults, noneSniHandler, this.logger);
|
|
||||||
return new LifetimeHttpHandler(dnsHandler, this.lifeTime, this.OnHttpHandlerDeactivate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当有httpHandler失效时
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">httpHandler</param>
|
|
||||||
private void OnHttpHandlerDeactivate(LifetimeHttpHandler handler)
|
|
||||||
{
|
|
||||||
// 切换激活状态的记录的实例
|
|
||||||
this.lifeTimeHttpHandlerLazy = new Lazy<LifetimeHttpHandler>(this.CreateHttpHandler, true);
|
|
||||||
this.httpHandlerCleaner.Add(handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,8 +4,7 @@ using Microsoft.AspNetCore.Builder;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using System.Net.Http;
|
||||||
using System.Linq;
|
|
||||||
using Yarp.ReverseProxy.Forwarder;
|
using Yarp.ReverseProxy.Forwarder;
|
||||||
|
|
||||||
namespace FastGithub
|
namespace FastGithub
|
||||||
@ -23,7 +22,7 @@ namespace FastGithub
|
|||||||
public static IApplicationBuilder UseGithubReverseProxy(this IApplicationBuilder app)
|
public static IApplicationBuilder UseGithubReverseProxy(this IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
var httpForwarder = app.ApplicationServices.GetRequiredService<IHttpForwarder>();
|
var httpForwarder = app.ApplicationServices.GetRequiredService<IHttpForwarder>();
|
||||||
var httpClientFactory = app.ApplicationServices.GetRequiredService<NoneSniHttpClientFactory>();
|
var httpClientHanlder = app.ApplicationServices.GetRequiredService<GithubHttpClientHanlder>();
|
||||||
var lookupOptions = app.ApplicationServices.GetRequiredService<IOptionsMonitor<GithubLookupFactoryOptions>>();
|
var lookupOptions = app.ApplicationServices.GetRequiredService<IOptionsMonitor<GithubLookupFactoryOptions>>();
|
||||||
var options = app.ApplicationServices.GetRequiredService<IOptionsMonitor<GithubReverseProxyOptions>>();
|
var options = app.ApplicationServices.GetRequiredService<IOptionsMonitor<GithubReverseProxyOptions>>();
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ namespace FastGithub
|
|||||||
{
|
{
|
||||||
var port = context.Request.Host.Port ?? 443;
|
var port = context.Request.Host.Port ?? 443;
|
||||||
var destinationPrefix = $"http://{host}:{port}/";
|
var destinationPrefix = $"http://{host}:{port}/";
|
||||||
var httpClient = httpClientFactory.CreateHttpClient();
|
var httpClient = new HttpMessageInvoker(httpClientHanlder, disposeHandler: false);
|
||||||
var requestConfig = options.CurrentValue.ForwarderRequestConfig;
|
var requestConfig = options.CurrentValue.ForwarderRequestConfig;
|
||||||
await httpForwarder.SendAsync(context, destinationPrefix, httpClient, requestConfig);
|
await httpForwarder.SendAsync(context, destinationPrefix, httpClient, requestConfig);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ namespace FastGithub
|
|||||||
var assembly = typeof(ReverseProxyServiceCollectionExtensions).Assembly;
|
var assembly = typeof(ReverseProxyServiceCollectionExtensions).Assembly;
|
||||||
return services
|
return services
|
||||||
.AddServiceAndOptions(assembly, configuration)
|
.AddServiceAndOptions(assembly, configuration)
|
||||||
|
.AddMemoryCache()
|
||||||
.AddHttpForwarder();
|
.AddHttpForwarder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,6 @@ namespace FastGithub.Scanner
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 反查的域名
|
/// 反查的域名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string [] Domains { get; set; } = new string[0];
|
public HashSet<string> Domains { get; set; } = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
},
|
},
|
||||||
"ReverseProxy": {
|
"ReverseProxy": {
|
||||||
"Enable": true, // 是否使用反向代理访问github,
|
"Enable": true, // 是否使用反向代理访问github,
|
||||||
"MaxConnectionsPerServer": 100, // 代理最大连接数
|
|
||||||
"ForwarderRequestConfig": {
|
"ForwarderRequestConfig": {
|
||||||
"Timeout": "00:02:00" // 代理超时时间
|
"Timeout": "00:02:00" // 代理超时时间
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user