.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
Setting | Type | Default Value |
---|---|---|
Timeout | TimeSpan? | 100 seconds |
HttpVersion | string | "1.1" |
AllowedHttpStatusRange | string | null ("2xx,3xx", effectively) |
Redirects.Enabled | bool | true |
Redirects.AllowSecureToInsecure | bool | false |
Redirects.ForwardHeaders | bool | false |
Redirects.ForwardAuthorizationHeader | bool | false |
Redirects.MaxAutoRedirects | int | 10 |
JsonSerializer | ISerializer | DefaultJsonSerializer |
UrlEncodedSerializer | ISerializer | UrlEncodedSerializer |
所有属性都是读/写的,可以直接设置:
// 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:
-
您更喜欢3.x 及更早版本的基于Newtonsoft的版本。(4.0 将其替换为基于System.Text.Json的版本。)这可以通过 Flurl.Http.Newtsonsoft配套包获得。
-
您想要使用默认实现,但使用自定义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);}
}
还有依赖注入模式经过测试也是可以的:
希望本文对你有帮助。
相关文章:

.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.…...

【每周AI简讯】GPT-5将有指数级提升,GPT Store正式上线
AI7 - Chat中文版最强人工智能 OpenAI的CEO奥特曼表示GPT-5将有指数级提升 GPT奥特曼参加Y-Combinator W24启动会上表示,我们已经非常接近AGI。GPT-5将具有更好的推理能力、更高的准确性和视频支持。 GPT Store正式上线 OpenAI正式推出GPT store,目前…...

QT上位机开发(MFC vs QT)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 在qt之前,上位机开发的主要方法就是mfc。后来出现了c#语言之后,上位机的开发就有一部分人转成了c#。这些开发都是在windows平台完成的,而linux上面的界面,则都是通过各种小众库…...

线性代数:矩阵的定义
目录 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行(列)矩阵 七、同型矩阵 八、矩阵相等 九、零矩阵 十、方阵的行列式 一、定义 二、方阵 三、对角阵 四、单位阵 五、数量阵 六、行(列)矩阵 七、同型矩…...

k8s 使用cert-manager证书管理自签
个人建议使用安装更快,比helm快,还要等待安装crd kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml#官网 https://cert-manager.io/docs/installation/kubectl/#创建自签的ClusterIssuer c…...

SpringSecurity+JWT前后端分离架构登录认证
目录 1. 数据库设计 2. 代码设计 登录认证过滤器 认证成功处理器AuthenticationSuccessHandler 认证失败处理器AuthenticationFailureHandler AuthenticationEntryPoint配置 AccessDeniedHandler配置 UserDetailsService配置 Token校验过滤器 登录认证过滤器接口配置…...

笔试面试题——二叉树进阶(一)
📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、根据二叉树创建字符串1、题目讲解2、思路讲解3、代码实现 二、二叉树的分层遍历1、题目讲…...
Java反射示例
Java反射示例 创建数据类型ReflectPoint.java package com.reflection;import java.util.Date;public class ReflectPoint {private Date birthday new Date();private int x;public int y;public String str1 "ball";public String str2 "basketball"…...
【WinForm.NET开发】实现使用后台操作的窗体
本文内容 创建使用后台操作的窗体使用设计器创建 BackgroundWorker添加异步事件处理程序添加进度报告和取消支持Checkpoint 如果某项操作需要很长的时间才能完成,并且不希望用户界面 (UI) 停止响应或阻塞,则可以使用 BackgroundWorker 类在另一个线程上…...

【操作系统和计网从入门到深入】(四)基础IO和文件系统
前言 这个专栏其实是博主在复习操作系统和计算机网络时候的笔记,所以如果是博主比较熟悉的知识点,博主可能就直接跳过了,但是所有重要的知识点,在这个专栏里面都会提到!而且我也一定会保证这个专栏知识点的完整性&…...

四.Winform使用Webview2加载本地HTML页面并互相通信
Winform使用Webview2加载本地HTML页面并互相通信 往期目录本节目标核心代码实现HTML代码实现的窗体Demo2代码效果图 往期目录 往期相关文章目录 专栏目录 本节目标 实现刷新按钮点击 C# winform按钮可以调用C# winform代码显示到html上点击HTML按钮可以调用C# winform代码更…...
如何有效清理您的Python环境:清除Pip缓存
Python是一个广泛使用的高级编程语言,以其强大的库和框架而闻名。然而,随着时间的推移和不断安装新的包,Python环境可能会变得混乱不堪,尤其是pip缓存可能占用大量的磁盘空间。本文将向您展示如何有效地清理pip缓存,保…...

Jira 母公司全面停服 Server 产品,用户如何迁移至极狐GitLab
Jira 母公司即将全面停服旗下部分 Server 端产品的销售和服务支持! Jira 母公司 Atlassian 在几年前确定了公司的战略为“全面上云”,为此做出了停止 Server 产品的销售和支持。整个时间线从 2021 年 2 月 2 日开始,直到今年 2 月 15 日&…...

Docker安装配置OnlyOffice
OnlyOffice 是一款强大的办公套件,你可以通过 Docker 轻松安装和部署它。本文将指导你完成安装过程。 步骤 1:拉取 OnlyOffice Docker 镜像 首先,使用以下命令从 Docker Hub 拉取 OnlyOffice Document Server 镜像: sudo docke…...

启动低轨道卫星LEO通讯产业与6G 3GPP NTN标准
通讯技术10年一个大跃进,从1990年的2G至2000年的3G网路,2010年的4G到近期2020年蓬勃发展的5G,当通讯技术迈入融合网路,当前的 5G 技术不仅可提供高频宽、低延迟,同时可针对企业与特殊需求以 5G 专网的模式提供各式服务…...

PICO Developer Center 创建和调试 ADB 命令
PICO 开发者中心概览 ADB 是一个轻量级的 Android 调试桥(Android Debug Bridge,简称 ADB),用于与 Android 设备进行通信和调试。ADB提供了许多有用的功能,使开发人员能够轻松地管理和调试设备上的应用程序。 你可以使用 PDC 工具来调试系统…...
【VRTK】【PICO】如何快速创建一个用VRTK开发的PICO项目
【背景】 每次新建一个VRTK的PICO项目总是做一些重复工作,于是就想着搞成一个基本的包,把基本的设置都放进去,今后新做项目直接导这个包就行了。 完整资源包请见本篇博客的绑定资源。 【内容简介】 这个包是我为了快速开发基于VRTK的PICO应用设置的基础项目包。每次开发…...

国产操作系统:VirtualBox安装openKylin-1.0.1虚拟机并配置网络
国产操作系统:VirtualBox安装openKylin-1.0.1虚拟机并配置网络 openKylin 操作系统目前适配支持X86、ARM、RISC-V三个架构的个人电脑、平板电脑及教育开发板,可以满足绝大多数个人用户及开发者的使用需求。适用于在VirtualBox平台上安装openKylin-1.0.1…...

本地git切换地区后,无法使用ssh访问github 22端口解决方案
问题 由于放假回家,发现之前一直使用正常的git,与github无法通讯,pull和push都无法连接。报错如下: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 原因 可能是所…...
Chat2DB:AI赋能的多数据库客户端工具,开源领航未来数据库管理
Chat2DB:开源多数据库客户端的AI革新 Chat2DB使用教程:Chat2DB使用教程_哔哩哔哩_bilibili 引言: 随着企业数据的快速膨胀,数据库管理的复杂性也在增加。此时,一个能够跨越数据库边界、并且集成先进的AI功能的工具,不…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...

从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...