论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
后端开发
›
.Net
›
dotnet 6 为什么网络请求不跟随系统网络代理变化而动态 ...
dotnet 6 为什么网络请求不跟随系统网络代理变化而动态切换代理 ...
东湖之滨
金牌会员
|
2022-9-19 16:07:38
|
显示全部楼层
|
阅读模式
楼主
主题
810
|
帖子
810
|
积分
2434
本文记录在 dotnet 6 的网络和在 .NET Framework 的行为的变更。在 dotnet 6 下,默认的网络请求在系统网络代理变更的时候,是不会动态切换代理的。例如在应用运行进行网络通讯之后,打开 Fiddler 抓包,此时将会发现 Fiddler 抓不到包,只有在应用重启之后才能抓到。或者是开着 Fiddler 抓包,然后退出 Fiddler 之后应用就断网了
如此行为是因为 Fiddler 抓包其中的一个原理就是设置系统的本机网络代理,而由于 dotnet 6 下,应用不会动态切换代理,如果在应用启动进行网络通讯之后,再打开 Fiddler 抓包,在 Fiddler 打开之后,将会修改系统的本机网络代理,但是 dotnet 6 的应用由于默认不会动态切换代理从而不走 Fiddler 的代理,因此 Fiddler 抓不到包。同理,在开着 Fiddler 抓包之后,退出了 Fiddler 将会修改本机的网络代理,但是由于 dotnet 6 的应用默认不会动态切换代理,在 Fiddler 修改了本机网络代理之后,依然 dotnet 6 的应用还在使用着被关闭的 Fiddler 的网络代理从而断网
核心原因是在 dotnet 6 下变更了网络代理动态切换的行为。其实考古找到这个行为在 .NET Core 2.0 就是默认不支持自动跟随系统代理切换而修改代理
在 .NET Framework 的 4.0 开始,通过监听注册表的 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections 的变更,在变更之后进行刷新网络请求的代理。详细请看
https://referencesource.microsoft.com/#System/net/System/Net/_AutoWebProxyScriptEngine.cs,395
在 .NET Core 下,网络代理的获取只有一次,获取到的代理没有再去监听注册表的变更,也就没有再次刷新。此问题已反馈给官方,详细请看
https://github.com/dotnet/runtime/issues/46910
在 .NET Core 将会在首次获取 HttpClient.DefaultProxy 时进行初始化,值得一提的是在 .NET Core 调用的 WebRequest.GetSystemWebProxy 方法底层也是调用 HttpClient.DefaultProxy 属性
public static IWebProxy GetSystemWebProxy() => HttpClient.DefaultProxy;
复制代码
以上的 GetSystemWebProxy 实现请看
Make WebRequest.GetSystemWebProxy() return a working proxy by stephentoub · Pull Request #41692 · dotnet/corefx
在 HttpClient.DefaultProxy 里面,将会调用到 SystemProxyInfo.cs 的 ConstructSystemProxy 方法获取对应平台的代理。这个 ConstructSystemProxy 在 OSX 和 Unix 和 Windows 有各自的实现
在 Windows 实现如下
public static IWebProxy ConstructSystemProxy()
{
if (!HttpEnvironmentProxy.TryCreate(out IWebProxy? proxy))
{
HttpWindowsProxy.TryCreate(out proxy);
}
return proxy ?? new HttpNoProxy();
}
复制代码
在 HttpEnvironmentProxy 里面,将尝试通过环境变量获取代理的配置,也就是说 dotnet 6 应用是支持通过环境变量设置代理,如此更加方便调试。获取的环境变量分别是 ALL_PROXY 和 HTTP_PROXY 和 HTTPS_PROXY 这几个惯例变量
如上面代码,如果获取不到环境变量,那么就进入 HttpWindowsProxy 的代码。在 WinInetProxyHelper 将会读取系统的代理
如上面代码,可以看到,实际上在 HttpClient.DefaultProxy 里面只会获取一次,没有通过注册表的变更再次刷新
这就是网络请求不跟随本机网络代理变化的原因
一个解决方法就是拷贝 dotnet runtime 的读取系统的配置方法,再加上监听注册表变更进行刷新配置,从而实现动态跟随系统代理变化而变化。我拷贝了代码,写了一个版本,使用方法是
var dynamicHttpWindowsProxy = new DynamicHttpWindowsProxy();
HttpClient.DefaultProxy = dynamicHttpWindowsProxy;
复制代码
代码的实现放在
github
和
gitee
欢迎访问
可以通过如下方式获取源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 8c64e9676c4205e55fad227a86d5d8d95a5ebe91
复制代码
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 8c64e9676c4205e55fad227a86d5d8d95a5ebe91
复制代码
获取代码之后,进入 NilerlanaihikaWhurreeberhalur 文件夹,具体实现放在 Proxy 文件里面,在 Program.cs 包含了测试逻辑,可以不断尝试访问百度。可以测试在使用 HttpClient.DefaultProxy = dynamicHttpWindowsProxy; 时,切换 Fiddler 代理配置,和不使用 DynamicHttpWindowsProxy 切换配置的行为
以上代码基本都是从 dotnet runtime 里面抄的,可以放心用在正式的项目。监听注册表变更是从
https://www.codeproject.com/Articles/4502/RegistryMonitor-a-NET-wrapper-class-for-RegNotifyC
抄的,这是一段比较古老稳定的代码,只不过需要多开启一个线程用来监听注册表。这就是为什么在例子代码里面,会延迟去启动监听注册表
参考文档:
c# - Default proxy in .net core 2.0 - Stack Overflow
AutoWebProxyScriptEngine.cs
Make WebRequest.GetSystemWebProxy() return a working proxy by stephentoub · Pull Request #41692 · dotnet/corefx
WinHttpWebProxyDataBuilder.cs
runtime/HttpConnectionPoolManager.cs at 1d9e50cb4735df46d3de0cee5791e97295eaf588 · dotnet/runtime
HttpClient.DefaultProxy should respect IE proxy changes · Issue #46910 · dotnet/runtime
how to set default proxy with .NET core 3.1 for HTTP client for any request? - Stack Overflow
How to change Global Windows Proxy using C# .NET with Immediate Effect - Stack Overflow
How to auto reset Fiddler when 'system proxy was changed' in Fiddler | Telerik Forums
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
东湖之滨
金牌会员
这个人很懒什么都没写!
楼主热帖
《HarmonyOS开发 - 小凌派-RK2206开发 ...
VMware虚拟机安装黑群晖7.1
当我们在聊「开源大数据调度系统Taier ...
ABP Framework 7.0 RC 新增功能简介 ...
MySQL视图
从0到1实现一套CICD流程之CD
[ARM 汇编]高级部分—ARM汇编编程实战 ...
大二C#实现酒店管理系统(C端展示、前 ...
测试大姐提了个bug,为什么你多了个opti ...
MySQL8.0 优化器介绍(二)
标签云
挺好的
服务器
快速回复
返回顶部
返回列表