如何在HttpClient中使用Fiddler?

12

我知道有很多关于这个问题的问题/答案、博客,不谈 Telerik 的常见问题解答。但是我仍然无法找到一个清晰纯粹的方法来诊断和解决:

背景:

我有一个 Web API 应用程序,还有一个(单元测试)客户端,该客户端使用 HttpClient 发送请求到 API。Web API 应用程序侦听 http://localhost:8631/。 有时我使用 Fiddler 查看发生了什么。

问题:

我的 HttpClient 和 Web API 之间的流量没有被 Fiddler 捕获。启动 Fiddler 后,流量仍然正常,但在 Fiddler 中不显示。

迄今为止的诊断:

  • 重要提示:使用任何浏览器并发送请求到 http://localhost:8631/ 都可以工作,我的意思是:流量被 Fiddler 捕获了
  • 明确地配置 HttpClient 使用 Fiddler 作为代理没有帮助。
  • 将 HttpClient 的 url 从http://localhost:8631/ 更改为 http://localhost.fiddler:8631/ 可以帮助解决问题,无论代理是否配置。

结论: 至少在我的情况下:这不是关于 HttpClient 是否被明确配置为使用 Fiddler 作为代理。这是关于 HttpClient 和/或 Fiddler 的 localhost 行为。

问题再次提出:

有人可能会问:问题解决了,那问题是什么?好的...

Q1: 这仍然是一个令人痛苦的问题,因为 URL 在某个地方被编码或配置(我的意思是http://localhost:8631/http://localhost.fiddler:8631),所以每次启动和停止 Fiddler 都必须更新它。 更多:将其检入源代码控制中,并由队友在其他计算机上进行检查可能会导致问题。 因此:是否有任何更少痛苦的解决方法?

硬编码我的机器名称(也可能起作用)会在团队合作并使用源代码控制时引起同样的痛苦和问题。

Q2:为什么这种不一致的行为:纯http://localhost:8631/ 从任何浏览器中都可以工作,但从 HttpClient 中却不行。

我认为回答 Q2 可以让我们更接近一个更可用的解决方法。

代码示例

    // Using the following url  w o r k s  regardless of any proxy setting
    // ...but it is a pain to hardcode or configure this and change    depending on Fiddler is running or not

    //private const string ApiUrl = "http://localhost.fiddler:8631/"; 

    // This is not working regardless any proxy setting. Trafic bypasses Fiddler
    private const string ApiUrl = "http://localhost:8631/";

    protected HttpClient GetClient()
    {
        var httpClientHandler = new HttpClientHandler
        {
            // Does not work 
            //Proxy = new WebProxy("http://localhost:8888", false),

            // Does not work
            Proxy = WebRequest.DefaultWebProxy,
            UseProxy = true
        };


        var client = new HttpClient(httpClientHandler)
        {
            BaseAddress = new Uri(ApiUrl)
        };
        // ...

您无需进行任何操作即可使用Fiddler与HttpClient。Fiddler设置/重置默认的操作系统代理,因此您无需修改任何应用程序即可使用它。只有在您更改代理设置或在Fiddler有机会重置操作系统代理之前终止Fiddler(例如关闭)时,才可能遇到问题。 - Panagiotis Kanavos
为了获得特定问题的帮助,您需要发布实际代码,包括在app.config中对system.net代理设置所做的任何修改。 - Panagiotis Kanavos
1
你尝试过查看.NET的Fiddler文档吗?http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/ConfigureDotNETApp - Phil Cooper
@PhilCooper:这就是我试图避免的,因为它很痛苦:“硬编码(无论是在代码还是配置中)显式代理设置(到Fiddler或我的机器名称)。” 这很痛苦,a)源代码控制/团队考虑,b)因为你必须始终在启动Fiddler或停止Fiddler时切换。 - g.pickardou
https://dev59.com/fXVC5IYBdhLWcg3wsTRi - CathalMF
http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/MonitorLocalTraffic - CathalMF
2个回答

8
问题在于,Microsoft的WebProxy类实现中有一个静态检查回路地址(基于像“localhost”这样的名称列表),并且将绕过任何被识别为回路的URI的代理。即使设置了BypassProxyOnLocal也没有关系。此设置仅在使用本地机器名称或本地网络中的另一个机器名称时才有效。主机名localhost或IP地址127.0.0.1始终被认为是回路,并将导致绕过代理。
.NET框架代码的相关部分在WebProxy.IsBypassedManual中:
if (host.IsLoopback) {
    return true; // bypass localhost from using a proxy.
}

写一个继承自WebProxy类的子类,并覆盖GetProxy和IsBypassed方法,以返回一个uri,即使是回环url也要使用代理。然后将该类的实例分配给您用于创建HttpClient的HttpClientHandler。
似乎不起作用,因为.net代码希望与实现IAutoWebProxy的对象一起使用,但是IAutoWebProxy被声明为内部的,不能在我们自己的代码中使用。
我看到的最简单的解决方案是具有在运行时将“localhost”替换为ApiUrl中的本地计算机名称的功能。无论Fiddler是否运行,本地计算机名称都可以正常工作。

2
这是正确的答案。详见https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/6359204-support-the-loopback-token-in-proxy-bypass-lists - EricLaw
1
我使用machinename - 但是fiddler仍然忽略了我的httpclient调用本地和基于web的网络服务?! - niico
@niico 请用您的代码提出一个新问题,并详细描述。也许您有防止客户使用任何代理或自己设置特定代理的代码? - NineBerry

-2

只需将默认代理定义为您的HttpClient实例,它就能像魔法一样工作。您不必更改代码中的任何URL。

HttpClientHandler handler = new HttpClientHandler( );
handler.Proxy = WebRequest.DefaultWebProxy;
HttpClient client = new HttpClient( handler as HttpMessageHandler );

我们在使用相同的行为时没有任何问题(Windows 10,Fiddler4)。


谢谢,我已经尝试了。不幸的是这并没有帮助到我。请注意,在诊断部分中,我写到即使明确将代理设置为Fiddler也没有帮助。然而,使用localhost.fiddler代替localhost可以解决问题。奇怪的是,当从浏览器中使用时,即使没有.fiddler域名也可以正常工作。 - g.pickardou
@g.pickardou 您的代理是 SOCK 还是 HTTP 代理?通常 Fiddler 应该创建一个 HTTP 代理。我们使用的是 HTTP 代理,在所有机器上都能百分之百地正常工作,包括使用企业代理的客户端。 - Benjamin Abt
我没有任何代理。Fiddler在运行时是一个代理。 - g.pickardou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接