.NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接

Flurl.Http-3.2.4 升级到 4.0.0 版本后,https请求异常:Call failed. The SSL connection could not be established.

如下图:

Flurl.Http-3.2.4版本绕过https的代码,对于 Flurl.Http-4.0.0 版本来说方法不再适用,3.2.4及4.0.0版本绕过https代码成果在文章最后有展示

查看了Flurl.Http4.0的文档,地址:Configuration - Flurl

配置相关文档内容简单翻译(翻译可能不够精准,请点击上面链接查看官方文档)如下:

配置
Flurl.Http 包含一组强大的选项和技术,用于在各个级别配置其行为。

设置
Flurl 主要通过 Settings上可用的属性进行配置。以下是可用的设置:IFlurlClient IFlurlRequest IFlurlClientBuilder HttpTest

SettingTypeDefault Value
TimeoutTimeSpan?100 seconds
HttpVersionstring"1.1"
AllowedHttpStatusRangestringnull ("2xx,3xx", effectively)
Redirects.Enabledbooltrue
Redirects.AllowSecureToInsecureboolfalse
Redirects.ForwardHeadersboolfalse
Redirects.ForwardAuthorizationHeaderboolfalse
Redirects.MaxAutoRedirectsint10
JsonSerializerISerializerDefaultJsonSerializer
UrlEncodedSerializerISerializerUrlEncodedSerializer

所有属性都是读/写的,可以直接设置:

// set default on the client:
var client = new FlurlClient("https://some-api.com");
client.Settings.Timeout = TimeSpan.FromSeconds(600);
client.Settings.Redirects.Enabled = false;

// override on the request:
var request = client.Request("endpoint");
request.Settings.Timeout = TimeSpan.FromSeconds(1200);
request.Settings.Redirects.Enabled = true;

您还可以流畅地配置它们:

clientOrRequest.WithSettings(settings => {
    settings.Timeout = TimeSpan.FromSeconds(600);
    settings.AllowedHttpStatusRange = "*";
    settings.Redirects.Enabled = false;
})...


或者在很多情况下甚至更流利:

clientOrRequest
    .WithTimeout(600)
    .AllowAnyHttpStatus()
    .WithAutoRedirect(false)
    ...


当同时使用客户端、请求和流畅配置时,您需要密切关注正在配置的对象,因为它可以确定对该客户端的后续调用是否受到影响:

await client
    .WithSettings(...) // configures the client, affects all subsequent requests
    .Request("endpoint") // creates and returns a request
    .WithSettings(...) // configures just this request
    .GetAsync();


无客户端模式支持所有相同的扩展方法。配置并发送请求而无需显式引用客户端:

var result = await "https://some-api.com/endpoint"
    .WithSettings(...) // configures just this request
    .WithTimeout(...) // ditto
    .GetJsonAsync<T>();


上述所有设置和扩展方法也可以在 上使用IFlurlClientBuilder,这对于在启动时进行配置非常有用:

// clientless pattern, all clients:
FlurlHttp.Clients.WithDefaults(builder =>
    builder.WithSettings(...));

// clientless pattern, for a specific site/service:
FlurlHttp.ConfigureClientForUrl("https://some-api.com")
    .WtihSettings(...);

// DI pattern:
services.AddSingleton<IFlurlClientCache>(_ => new FlurlClientCache()
    // all clients:
    .WithDefaults(builder =>
        builder.WithSettings(...))
    // specific named client:
    .Add("MyClient", "https://some-api.com", builder =>
        builder.WithSettings(...))


Settings支持(以及所有相关的流畅优点)的第四个也是最后一个对象是HttpTest,并且它优先于所有内容:

using var test = new HttpTest.AllowAnyHttpStatus();
await sut.DoThingAsync(); // no matter how things are configured in the SUT,
                          // test settings always win 


序列化器
和设置值得特别注意JsonSerializer。UrlEncodedSerializer正如您所料,它们分别控制(反)序列化 JSON 请求和响应以及 URL 编码的表单帖子的详细信息。两者都实现了ISerializer,定义了 3 个方法:

string Serialize(object obj);
T Deserialize<T>(string s);
T Deserialize<T>(Stream stream);
Flurl 为两者提供了默认实现。您不太可能需要使用不同的UrlEncodedSerializer,但您可能出于以下几个原因想要更换JsonSerializer:

  1. 您更喜欢3.x 及更早版本的基于Newtonsoft的版本。(4.0 将其替换为基于System.Text.Json的版本。)这可以通过 Flurl.Http.Newtsonsoft配套包获得。

  2. 您想要使用默认实现,但使用自定义JsonSerializerOptions。这可以通过提供您自己的实例来完成:

clientOrRequest.Settings.JsonSerializer = new DefaultJsonSerializer(new JsonSerializerOptions {PropertyNameCaseInsensitive = true,IgnoreReadOnlyProperties = true
});

事件处理程序
将日志记录和错误处理等横切关注点与正常逻辑流程分开通常会产生更清晰的代码。Flurl.Http 定义了 4 个事件 - BeforeCall、AfterCall、OnError和OnRedirect- 以及、和EventHandlers上的集合。(与 不同,事件处理程序在 上不可用。)IFlurlClient IFlurlRequest IFlurlClientBuilder Settings HttpTest

与 类似Settings,所有具有EventHandlers属性的东西都会带来一些流畅的快捷方式:

clientOrRequest.BeforeCall(call => DoSomething(call)) // attach a synchronous handler.OnError(call => LogErrorAsync(call))  // attach an async handler

在上面的示例中,call是 的一个实例FlurlCall,其中包含与请求和响应的各个方面相关的一组可靠的信息和选项:

IFlurlRequest Request
HttpRequestMessage HttpRequestMessage
string RequestBody
IFlurlResponse Response
HttpResponseMessage HttpResponseMessage
FlurlRedirect Redirect
Exception Exception
bool ExceptionHandled
DateTime StartedUtc
DateTime? EndedUtc
TimeSpan? Duration
bool Completed
bool Succeeded


OnError在 之前触发AfterCall,并让您有机会决定是否允许异常冒泡:

clientOrRequest.OnError(async call => {await LogTheErrorAsync(call.Exception);call.ExceptionHandled = true; // otherwise, the exeption will bubble up
});

OnRedirect允许精确处理 3xx 响应:

clientOrRequest.OnRedirect(call => {if (call.Redirect.Count > 5) {call.Redirect.Follow = false;}else {log.WriteInfo($"redirecting from {call.Request.Url} to {call.Redirect.Url}");call.Redirect.ChangeVerbToGet = (call.Response.Status == 301);call.Redirect.Follow = true;}
});

在较低级别,事件处理程序是实现 的对象IFlurlEventHandler,它定义了 2 个方法:

void Handle(FlurlEventType eventType, FlurlCall call);
Task HandleAsync(FlurlEventType eventType, FlurlCall call);


通常,您只需要实现一个或另一个,因此 Flurl 提供了一个默认实现 ,FlurlEventHanler它构成了一个方便的基类 - 两种方法都是虚拟无操作的,因此只需重写您需要的方法即可。处理程序可以这样分配:

clientOrRequest.EventHandlers.Add((FlurlEventType.BeforeCall, new MyEventHandler()));


请注意,EventHanlers项目的类型为Tuple<EventType, IFlurlEventHandler>。保持处理程序与偶数类型分离意味着给定的处理程序可以重用于不同的事件类型。

您可能更喜欢基于对象的方法而不是前面描述的更简单的基于 lambda 的方法,原因之一是如果您使用 DI 并且您的处理程序需要注入某些依赖项:

public interface IFlurlErrorLogger : IFlurlEventHandler { }public class FlurlErrorLogger : FlurlEventHandler, IFlurlErrorLogger
{private readonly ILogger _logger;public FlurlErrorLogger(ILogger logger) {_logger = logger;}
}

以下是如何使用 Microsoft 的 DI 框架进行连接:

// register ILogger:
services.AddLogging();
// register service that implements IFlurlEventHander and has dependency on ILogger
services.AddSingleton<IFlurlErrorLogger, FlurlErrorLogger>();// register event hanlder with Flurl, using IServiceProvider to wire up dependencies:
services.AddSingleton<IFlurlClientCache>(sp => new FlurlClientCache().WithDefaults(builder =>builder.EventHandlers.Add((FlurlEventType.OnError, sp.GetService<IFlurlErrorLogger>()))

消息处理程序
Flurl.Http 构建于 之上HttpClient,它(默认情况下)使用它HttpClientHandler来完成大部分繁重的工作。IFlurlClientBuilder公开配置两者的方法:

// clientless pattern:
FlurlHttp.Clients.WithDefaults(builder => builder.ConfigureHttpClient(hc => ...).ConfigureInnerHandler(hch => {hch.Proxy = new WebProxy("https://my-proxy.com");hch.UseProxy = true;}));// DI pattern: 
services.AddSingleton<IFlurlClientCache>(_ => new FlurlClientCache().WithDefaults(builder => builder..ConfigureHttpClient(hc => ...).ConfigureInnerHandler(hch => ...)));

温馨提示:

1、Flurl 禁用AllowAutoRedirect和UseCookies以便重新实现自己的这些功能概念。如果您将 via 设置为 true ConfigureInnerHander,则可能会破坏 Flurl 中的这些功能。
2、DefaultRequestHeaders Flurl 还实现了自己的和概念Timeout,因此您可能不需要配置HttpClient.

也许您已经阅读过SocketsHttpHandler并且想知道如何在 Flurl 中使用它。您可能会惊讶地发现您可能已经是这样了。如前所述,FlurlClient将其大部分工作委托给HttpClient,而后者又将其大部分工作委托给HttpClientHandler。但鲜为人知的是,自 .NET Core 2.1 以来,HttpClientHandler几乎将所有工作委托给SocketsHttpHandler所有支持它的平台,这基本上是除基于浏览器(即 Blazor)平台之外的所有平台。(如果需要说服力,请浏览源代码。) 

FlurlClient → HttpClient → HttpClientHandler → SocketsHttpHandler (on all supported platforms) 

HttpClientHandler尽管如此,您可能还是想绕过并直接使用,有一个原因SocketsHttpHander:它的某些可配置性HttpClientHandler在. 只要您不需要支持 Blazor,您就可以这样做: 

// clientless pattern:
FlurlHttp.Clients.WithDefaults(builder =>builder.UseSocketsHttpHandler(shh => {shh.PooledConnectionLifetime = TimeSpan.FromMinutes(10);...}));// DI pattern: 
services.AddSingleton<IFlurlClientCache>(_ => new FlurlClientCache().WithDefaults(builder => builder.UseSocketsHttpHandler(shh => {...})));

注意:在同一构建器上调用ConfigureInnerHandler和UseSocketsHttpHandler会导致运行时异常。使用其中之一,切勿同时使用。

Flurl 直接支持的最后一种消息处理程序类型是DelegatingHandler,这是一种可链接的处理程序类型,通常称为中间件,通常由第三方库实现。

// clientless pattern:
FlurlHttp.Clients.WithDefaults(builder => builder.AddMiddleare(new MyDelegatingHandler()));// DI pattern: 
services.AddSingleton<IFlurlClientCache>(sp => new FlurlClientCache().WithDefaults(builder => builder.AddMiddleware(sp.GetService<IMyDelegatingHandler>())

此示例使用流行的弹性库Polly以及在 DI 场景中配置 Flurl:

using Microsoft.Extensions.Http;var policy = Policy.Handle<HttpRequestException>()...services.AddSingleton<IFlurlClientCache>(_ => new FlurlClientCache().WithDefaults(builder => builder.AddMiddleware(() => new PolicyHttpMessageHandler(policy))));

 上面的示例需要安装Microsoft.Extensions.Http.Polly。

以上是配置相关的文档,我并没有在文档中发现关于https的相关配置。

Flurl.Http-3.2.4版本绕过https证书代码:

//Startup的ConfigureServices方法中配置
Flurl.Http.FlurlHttp.ConfigureClient(AppSettings.SFGZAPI.serversUrl, cli =>cli.Settings.HttpClientFactory = new UntrustedCertClientFactory()); //此类建立你觉得方便的地方即可
public class UntrustedCertClientFactory : DefaultHttpClientFactory
{public override HttpMessageHandler CreateMessageHandler(){return new HttpClientHandler{ServerCertificateCustomValidationCallback = (a, b, c, d) => true};}
}

 对于4.0.0版本,经过一番阅读源代码【https://github.com/tmenier/Flurl】并测试,测试如下图:

上面截图代码均测试,依然还是:无法建立SSL连接。

又一次阅读文档无客户端使用,发现FlurlHttp.UseClientCachingStrategy说明:

看到可以在这个方法中设置FlurlHttp,一直以为是配置,原来我自己进入了坑,请阅读管理客户端相关文档:Managing Clients - Flurl 或阅读译文:.NetCore Flurl.Http 4.0.0 以上管理客户端-CSDN博客,于是开始了尝试并可以正常访问:

//无客户端使用
FlurlHttp.UseClientCachingStrategy(request =>
{FlurlHttp.Clients.GetOrAdd("https://xxx", "https://xxx", builder =>builder.ConfigureInnerHandler(hch =>{hch.ServerCertificateCustomValidationCallback = (a, b, c, d) => true;}));return "https://xxx";
});

测试:

/// <summary>
/// 无客户端模式
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("FlurlHttp")]
public async Task<ActionResult> FlurlHttp()
{try{var a = await "https://xxx".WithHeader("xx", "xxx").PostAsync().ReceiveJson<dynamic>();return Ok(a);}catch (Exception ex){return BadRequest(ex.Message);}
}

 还有依赖注入模式经过测试也是可以的:

希望本文对你有帮助。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/631127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【萤火虫系列教程】3/5-Adobe Firefly 创意填充

003-Adobe Firefly 创意填充 创意填充 登录账号后&#xff0c;在主页点击创意填充的【生成】按钮&#xff0c;进入到创意填充页面 我们可以上传自己的图像 一键抠图 点击【背景】就可以把主图抠出来 点击【反转】就可以把背景抠出来 点击【清除】就可以恢复到图片原来…

表的增删改查 进阶(一)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 数据库约束 约束类型 NOT NUll 约束 UNIQUE 约束 D…

K8S对外服务ingress

Sevice作用体现在两个方面 集群内部 不断跟踪pod的变化&#xff0c;更新endpoint中的pod对象&#xff0c;基于pod的ip地址不断发现的一种服务发现机制 集群外部 类似负载均衡器&#xff0c;把流量&#xff08;ip端口&#xff09;&#xff0c;不涉及转发url&#xff08;http ht…

STM32WLE5JC介绍

32位 ARM Cotrex-M4 CPU 32MHz晶体振荡器 32 kHz RTC振荡器与校准 20x32位备份寄存器 引导程序支持USART和SPI接口 介绍 STM32WLE5/E4xx远程无线和超低功耗器件嵌入了强大的超低功耗LPWAN兼容无线电解决方案&#xff0c;支持以下调制&#xff1a;LoRa&#xff0c;&#xff08…

设计模式-简单工厂

设计模式-简单工厂 简单工厂模式是一个集中管理对象创建&#xff0c;并根据条件生成所需类型对象的设计模式&#xff0c;有助于提高代码的复用性和维护性&#xff0c;但可能会导致工厂类过于复杂且违反开闭原则。 抽象提取理论&#xff1a; 封装对象创建过程解耦客户端与产品…

读书笔记-《数据结构与算法》-摘要8[桶排序]

桶排序和归并排序有那么点点类似&#xff0c;也使用了归并的思想。大致步骤如下&#xff1a; 设置一个定量的数组当作空桶。Divide - 从待排序数组中取出元素&#xff0c;将元素按照一定的规则塞进对应的桶子去。对每个非空桶进行排序&#xff0c;通常可在塞元素入桶时进行插入…

JAVA SECS发送Report C#处理SECS Report SECS发送事件资料大全 S6F11 建立通讯S1F13

发送S6F11非常简单&#xff0c;只需5~6行代码&#xff0c;最核心是代码清晰易懂。 任何人都可以一看就能上手&#xff0c;如果说用代码可读性作为不可替代性的壁垒就无话可说了。 private void buttonS6F11_Click(object sender, EventArgs e) {int nTransaction 0;// 数据部…

数据守护盾牌:敏感数据扫描与脱敏,让安全合规无忧

前言 在信息时代&#xff0c;数据已经成为企业和组织的核心资产&#xff0c;其价值与日俱增。然而&#xff0c;随着数据使用的普及和复杂度的提升&#xff0c;数据安全与合规问题也变得越来越突出。敏感数据的保护显得尤为重要&#xff0c;因为这些数据一旦泄露或被不当使用&a…

文件操作解析(一)

前言 很多非计科的专业并未对文件操作这点做出详细解释&#xff0c;今天复习到这里就想趁此机会记录一下自己学到的知识&#xff0c;也希望能对大家有所帮助。 一.为什么使用文件 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的 内存中&#xff0c; 如果程序退出…

电脑屏幕横过来了怎么恢复?这4个方法好用又简单!

“我在用电脑的时候不知道为什么&#xff0c;电脑屏幕一整个都横过来了。导致我无法正常使用电脑&#xff0c;应该怎么解决这个问题呢&#xff1f;希望大家帮我出出主意&#xff01;” 在现代社会中&#xff0c;电脑已经成为了我们工作、学习和生活中不可或缺的工具。然而&…

搭建开源数据库中间件MyCat2-配置mysql数据库双主双从

mycat2官网&#xff1a;MyCat2 前言&#xff1a;mycat2下载地址无法访问&#xff0c;不知道是不是被DNS污染了&#xff0c;还是需要搭梯子访问&#xff0c;所以我只能找到1.21的版本进行安装。搭建mycat2的前提是搭建数据库主从复制。 架构&#xff1a;双主双从 配置&#xf…

汽车芯片「新变量」

编者按&#xff1a;汽车行业的格局重构和技术革新&#xff0c;也在推动芯片赛道进入变革周期。不同商业模式的博弈&#xff0c;持续升温。 对于智能汽车来说&#xff0c;过去几年经历了多轮硬件和软件的性能迭代&#xff0c;甚至是革新&#xff0c;如今&#xff0c;市场正在进…

云原生场景下,AIGC 模型服务的工程挑战和应对

作者&#xff1a;徐之浩、车漾 “成本”、“性能”和 “效率”正在成为影响大模型生产和应用的三个核心因素&#xff0c;也是企业基础设施在面临生产、使用大模型时的全新挑战。AI 领域的快速发展不仅需要算法的突破&#xff0c;也需要工程的创新。 大模型推理对基础设施带来…

测试开发(5)测试分类标准 :按测试对像划分、按是否查看代码划分、按开发阶段划分、按测试实施组织、按是否运行划分、按是否手工划分、按测试地域划分

接上次博客&#xff1a; 测试开发&#xff08;4&#xff09;测试用例基本要素、好处、测试用例设计方法 &#xff1a;基于需求进行测试用例的设计&#xff1b;具体的设计方法【等价类、边界值、错误猜测法、场景设计法、因果图/测试表法、正交排列】、万能公式、有效性、粒度和…

关于FET等效电路电容模型中的能量非守恒问题

标题&#xff1a;On the Energy Nonconservation in the FET’s Equivalent Circuit Capacitance Model 摘要 摘要——本文回答了长期以来关于如何在场效应晶体管&#xff08;FET&#xff09;等效电路模型中非互易电容形式与能量守恒原理之间达成调和的问题。通过对模拟和测量…

FPGA引脚物理电平(内部资源,Select IO)-认知2

引脚电平 The SelectIO pins can be configured to various I/O standards, both single-ended and differential. • Single-ended I/O standards (e.g., LVCMOS, LVTTL, HSTL, PCI, and SSTL) • Differential I/O standards (e.g., LVDS, Mini_LVDS, RSDS, PPDS, BLVDS, and…

spring常见漏洞(5)

CVE-2018-1273 Spring Data Commons远程命令执行(CVE-2018-1273)&#xff0c;当用户在项目中利用了Spring-data的相关web特性对用户的输入参数进行自动匹配的时候&#xff0c;会将用户提交的form表单的key值作为Spel的执行内容而产生漏洞 影响版本 Spring Data Commons 1.13…

微信小程序的springboot高校新生报道管理系统

考虑到实际生活中在毕业论文选题管理方面的需要以及对该系统认真的分析,将小程序权限按管理员和用户这两类涉及用户划分。 (a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有系统首页、个人中心、学生管理、指导教师管理、课题信息管理、选题信息管理、论文信息管理、疑…

Erlang/OTP中的日志与事件处理(二)

用gen_event编写自定义事件处理器 可能你并不喜欢错误日志记录器的默认输出格式。它与所有其他系统所使用的格式确实有较大的差异。你所在的企业可能已经围绕自己的日志格式开发了大量工具&#xff0c;这些工具无法与Erlang的日志格式兼容。这时你该怎么办呢?还好&#xff0c…

前端面试题-html5新增特性有哪些

HTML html5新增特性有哪些 1.新增了语义化标签 标签用法header定义文档或区块的页眉&#xff0c;通常包含标题&#xff0c;导航和其他有关信息nav定义导航链接的容器&#xff0c;用于包裹网站的导航部分section定义文档的一个独立节或区块&#xff0c;用于组织相关的内容art…