Skip to content

具有生命周期管理和动态Web代理的HttpMessageHandler创建工厂

License

Notifications You must be signed in to change notification settings

xljiulang/HttpMessageHandlerFactory

Repository files navigation

HttpMessageHandlerFactory

具有生命周期管理和动态Web代理的HttpMessageHandler创建工厂

nuget包 状态 说明
HttpMessageHandlerFactory NuGet logo MIT开源
HttpMessageHandlerFactory.Polly NuGet logo MIT开源
HttpMessageHandlerFactory.Connection NuGet logo 闭源,需要授权

1 功能介绍

1.1 CreateHandler

/// <summary>
/// 创建用于请求的HttpMessageHandler
/// </summary>
/// <param name="name">别名</param>
/// <param name="proxyUri">支持携带UserInfo的代理地址</param> 
/// <returns></returns>
HttpMessageHandler CreateHandler(string name, Uri? proxyUri);

1.2 CreateClient

将CreateHandler()产生的HttpMessageHandler包装为HttpClient,适用于客户端直接请求。

1.3 CreateInvoker

将CreateHandler()产生的HttpMessageHandler包装为HttpMessageInvoker,适用于反向代理中间件(比如YARP)的请求转发。

2 使用示例

static async Task Main(string[] args)
{
    var services = new ServiceCollection();
    services.AddLogging(x => x.AddConsole());
    services.AddHttpMessageHandlerFactory("App")
        .AddHttpMessageHandler<AppHttpHandler>()
        .SetHandlerLifetime(TimeSpan.FromMinutes(1d));

    var serviceProvider = services.BuildServiceProvider();
    var factory = serviceProvider.GetRequiredService<IHttpMessageHandlerFactory>();

    var proxyUri = default(Uri);
    var httpClient = factory.CreateClient("App", proxyUri);
    var html = await httpClient.GetStringAsync("https://github.com/xljiulang/HttpMessageHandlerFactory/blob/master/README.md");
    Console.WriteLine(html);
}

3 扩展项目

3.1 HttpMessageHandlerFactory.Polly

为HttpMessageHandlerFactory提供Polly策略扩展,使得IHttpMessageHandlerBuilder拥有与IHttpClientFactory完全一致的Polly能力。

3.1.1 AddPolicyHandler能力

var retryPolicy = Policy.Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(response =>
    {
        return response.IsSuccessStatusCode == false;
    }).WaitAndRetryAsync(3, t => TimeSpan.FromSeconds(3d));

 services
    .AddHttpMessageHandlerFactory("App")
    .AddPolicyHandler(retryPolicy);    

3.1.2 AddPolicyHandlerFromRegistry能力

var retryPolicy = Policy.Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(response =>
    {
        return response.IsSuccessStatusCode == false;
    }).WaitAndRetryAsync(3, t => TimeSpan.FromSeconds(3d));

var registry = services.AddPolicyRegistry();
registry.Add("registry1", retryPolicy);

services
    .AddHttpMessageHandlerFactory("App")
    .AddPolicyHandlerFromRegistry("registry1");    

3.1.3 AddTransientHttpErrorPolicy能力

当以下任意条件成立时,触发TransientHttpErrorPolicy

  • HttpRequestException的网络故障
  • 服务端响应5XX的状态码
  • 408的状态码(request timeout)
services
    .AddHttpMessageHandlerFactory("App")
    .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[] {
        TimeSpan.FromSeconds(1d),
        TimeSpan.FromSeconds(5d),
        TimeSpan.FromSeconds(10d)
    }));  

3.2 HttpMessageHandlerFactory.Connection

为HttpMessageHandlerFactory提供自定义连接的功能。 注意此扩展项目不是免费项目,有如下限制:

  • 不开放和提供源代码
  • nuget包的程序集在应用程序运行2分钟后适用期结束
  • 适用期结束后所有的http请求响应为423 Locked
  • 需要license文件授权方可完全使用

3.2.1 自定义域名解析

  • 当无代理连接时,连接到自定义解析得到的IP
  • 当使用http代理时,让代理服务器连接到自定义解析得到的IP
  • 当使用socks代理时,让代理服务器连接到自定义解析得到的IP
services
    .AddHttpMessageHandlerFactory("App")
    .AddHostResolver<CustomHostResolver>();
sealed class CustomHostResolver : HostResolver
{
    public override ValueTask<HostPort> ResolveAsync(DnsEndPoint endpoint, CancellationToken cancellationToken)
    {
        if (endpoint.Host == "www.baidu.com")
        {
            return ValueTask.FromResult(new HostPort("14.119.104.189", endpoint.Port));
        }
        return ValueTask.FromResult(new HostPort(endpoint.Host, endpoint.Port));
    }
}

3.2.2 自定义ssl的sni

services
    .AddHttpMessageHandlerFactory("App")
    .AddSslSniProvider<CustomSslSniProvider>();
sealed class CustomSslSniProvider : SslSniProvider
{
    public override ValueTask<string> GetSslSniAsync(string host, CancellationToken cancellationToken)
    {
        return ValueTask.FromResult(string.Empty);
    }

    public override bool RemoteCertificateValidationCallback(string host, X509Certificate? cert, X509Chain? chain, SslPolicyErrors errors)
    {
        return true;
    }
}

4 开源有你

赞助

About

具有生命周期管理和动态Web代理的HttpMessageHandler创建工厂

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages