如何使HttpClient中继流量出现在Fidder或Charles?

时间:2013-07-24 03:10:21

标签: asp.net-mvc asp.net-web-api httpclient fiddler charles-proxy

我有一个基于此示例的简单web api项目: http://aspnet.codeplex.com/sourcecontrol/latest#Samples/WebApi/RelaySample/Program.cs

但是,在上面的示例中,中继正在与本地服务器一起工作,在我的项目中,中继正在与具有真实地址的外部Web服务器一起工作; companyX.com

我通过浏览器使用中继服务(或Web代理服务),例如,在浏览器请求relayService.com/companyX中。中继服务使用外部companyX.com站点的数据进行响应。

继电器运行良好,但有些标头不正确,我需要查看HttpClient发送到远程companyX.com服务器的内容。

在fiddler或Charles中,只列出了我的浏览器对relayService.com的请求/响应,从HttpClient到relayService.com的请求/响应从未显示。

relayService.com在我的机器上本地运行,在IIS7中,我使用hosts文件将流量定向到relayService.com。

在创建HttpClient时,我尝试了以下几种变体:

        var clientHandler = new HttpClientHandler
        {
            CookieContainer = cookies,
            UseCookies = true,
            UseDefaultCredentials = false,
            Proxy = new WebProxy("http://localhost:8888"),
            UseProxy = true,
            AutomaticDecompression = DecompressionMethods.GZip, 
            AllowAutoRedirect = false, 
            ClientCertificateOptions = ClientCertificateOption.Automatic
        };


        HttpClient client = new HttpClient(clientHandler);

更新

如果我更改UseProxy = false当Fiddler打开或关闭时,服务继续有效。

使用UseProxy = true,服务将失败,如果fiddler打开,我收到以下错误:

Object reference not set to an instance of an object.

at System.DomainNameHelper.IdnEquivalent(String hostname) at System.Net.HttpWebRequest.GetSafeHostAndPort(Uri sourceUri, Boolean addDefaultPort, Boolean forcePunycode) at System.Net.HttpWebRequest.GenerateProxyRequestLine(Int32 headersSize) at System.Net.HttpWebRequest.SerializeHeaders() at System.Net.HttpWebRequest.EndSubmitRequest() at System.Net.Connection.CompleteConnection(Boolean async, HttpWebRequest request)

UseProxy = true和fiddler已关闭,我收到以下(显而易见的)错误:

No connection could be made because the target machine actively refused it 127.0.0.1:8888

在同一个解决方案中,我使用HttpWebRequest从网上下载数据并且确实显示在Fiddler中,因此它似乎是HttpClient.GetAsync()的问题

我在两台机器上尝试了相同的结果。

我一整天都在苦苦挣扎,任何帮助都会非常感激。

回顾一下: * relayService.com在我的机器上本地运行,在IIS7中

  • hosts文件具有“127.0.0.1 relayService.com”

  • relayService.com是一个MVC Web API站点,它使用HttpClient.GetAsync()从实时网站下载内容

  • Fiddler / Charles在同一台机器上本地运行

  • 本地relayService.com的浏览器流量出现在Fiddler / Charles

  • HttpClient.GetAsync()实时网络流量未出现在Fiddler / Charles

  • Fiddler / Charles都是最新版本。

再次感谢

2 个答案:

答案 0 :(得分:0)

如果您使用的是Fiddler,您的HOSTS文件中不需要任何内容​​;你可以使用Fiddler的工具> HOSTS将流量重定向到你想要的任何地方。

尝试从服务帐户(例如ASP.NET帐户)捕获流量时,通常需要将该帐户配置为使用代理;有关详细信息,请参阅http://fiddler2.com/blog/blog/2013/01/08/capturing-traffic-from-.net-services-with-fiddler。如果这样做,不应直接在代码中配置代理对象。

您显示的异常表明这是GenerateProxyRequestLine函数中的错误。如果您更新此更新:new WebProxy("http://localhost:8888");new WebProxy("127.0.0.1", 8888);

一般来说,.NET应用程序将绕过指向// localhost或//127.0.0.1的URL的代理,因此在使用Fiddler进行调试时,通常使用//localhost.fiddler的服务URL以便流量为总是发送给代理。

答案 1 :(得分:0)

我通过使HttpClient静态来解决问题。

这很好(对于程序功能)但是上面描述的fiddler有问题,尝试使用代理会抛出错误:

private HttpClient _client()
{

    var clientHandler = new HttpClientHandler
    {
        UseCookies = true,
        UseDefaultCredentials = false,
        Proxy = new WebProxy("http://localhost:8888"),
        UseProxy = true,
        AutomaticDecompression = DecompressionMethods.GZip,
        AllowAutoRedirect = true,
        ClientCertificateOptions = ClientCertificateOption.Automatic
    };

    HttpClient client = new HttpClient(clientHandler);
    client.Timeout = TimeSpan.FromMinutes(20);

    return client;
}

客户端创建时使用:

using (HttpResponseMessage serviceResponse = await _client().GetAsync(getURL(), HttpCompletionOption.ResponseHeadersRead))
    {
                // Return response

    }

但是,下面也有效,所有流量都出现在Fiddler中!

private static readonly HttpClientHandler _clientHandler = new HttpClientHandler()
{
    //CookieContainer = cookies,
    UseCookies = true,
    UseDefaultCredentials = false,
    Proxy = new WebProxy("http://localhost:8888"),
    UseProxy = false,
    AutomaticDecompression = DecompressionMethods.GZip,
    AllowAutoRedirect = false,
    ClientCertificateOptions = ClientCertificateOption.Automatic, 
};

//Create a shared instance of HttpClient and set the request timeout
private static readonly HttpClient _client = new HttpClient(_clientHandler)
{
    Timeout = TimeSpan.FromMinutes(20)
};

创建客户端(唯一不同的是在上面的_client之后删除'()'):

using (HttpResponseMessage serviceResponse = await _client.GetAsync(getURL(), HttpCompletionOption.ResponseHeadersRead))
    {
                // Return response

    }

我不知道为什么会这样。任何见解将不胜感激。

谢谢,