Skip to content

Itoktsnhc/Itok.ProxyMediator

Repository files navigation

Itok.ProxyMediator

Nuget

Nuget:Itok.ProxyMediator.Core + Itok.ProxyMediator.Extension

一个本地的可配置的切换代理服务,将本地请求按需转发到对于的代理上。Inspired by https://github.com/agabani/PassThroughProxy

UserRequest -----> ProxyMediator ----->[ExternalProxy1,ExternalProxy2]

示例代码:

var ext = new HostBuilder().ConfigureServices(svc =>
    {
        svc.AddProxyMediator(IPEndPoint.Parse("127.0.0.1:0"),// 端口为0,让系统自动分配一个空闲端口
        (session, proxyMediatorHandler) =>//当连接到远端之前,尝试获取目标转发代理
        {
            var host = session.Header.Host.Hostname;
            var external = proxyMediatorHandler.OutBoundMap.OrderByDescending(s => s.Key.Length)//
                .FirstOrDefault(s =>
                    host.Contains(s.Key)
                    || host == s.Key).Value;
            return Task.FromResult(external);
        });
        svc.AddHttpClient(nameof(ProxyMediator))//注册HttpClient,并配置代理为本地服务。
        .ConfigurePrimaryHttpMessageHandler(ctx =>
        {
            var proxyMediatorHandler = ctx.GetRequiredService<ProxyMediatorHandler>();
            var httpClientHandler = new HttpClientHandler();
            while (proxyMediatorHandler.EndPoint.Port == 0)//当系统自动分配的时候,需要等待后台服务启动
            {
                Thread.Sleep(100);
            }

            httpClientHandler.UseProxy = true;
            httpClientHandler.Proxy = new WebProxy(proxyMediatorHandler.EndPoint.ToString());
            return httpClientHandler;
        });
    }
).Build();
ext.Start();
var factory = ext.Services.GetRequiredService<IHttpClientFactory>();
var client = factory.CreateClient(nameof(ProxyMediator));
var handler = ext.Services.GetRequiredService<ProxyMediatorHandler>();
foreach (var unused in Enumerable.Range(1, 3))
{
    client.GetStringAsync("https://ip.42.pl/raw").Wait();
}

foreach (var item in handler.Pool.ContextContainer.Values)//清空现有的两端链接
{
    item.Dispose();
}

Console.ReadLine();
var ds = client.GetStringAsync("http://ip.42.pl/raw").Result;
Console.WriteLine(ds);
ds = client.GetStringAsync("http://ip.42.pl/raw").Result;
Console.WriteLine(ds);