12

I know there are many of questions/answers, blogs about this, not talking about Telerik's FAQ. Still I could not find this diagnosed and solved in a clear pure way:

Context:

I have a Web API app, and I have a (unit test) client, which uses HttpClient to send requests to the API. Web API app listens in http://localhost:8631/ Sometimes I use Fiddler to see what's going on.

Issue:

Traffic between my HttpClient and Web API is not captured by Fiddler. After launching Fiddler traffic is still OK, but not shown in Fiddler.

Diagnostics so far:

  • Important: Using any browser and sending requests to http://localhost:8631/ is working, I mean: traffic captured by Fiddler
  • Configuring HttpClient explicitly to use Fiddler as proxy does not help.
  • Changing HttpClient url from http://localhost:8631/ to http://localhost.fiddler:8631/ helps, regardless of proxy was configured or not.

Conclusions: At least my case: It is not about HttpClient is configured explicitly to using Fiddler as proxy or not. It is about HttpClient's and/or Fiddler's localhost behaviour.

Issue again:

One may ask: Problem solved, then what is the question? Well...

Q1: This is still a painful issue, because the url is coded or configured somewhere (I mean http://localhost:8631/ or http://localhost.fiddler:8631 so every start and stop of fiddler it must be updated. More: Checking in the source to source control, and checking out on an other machine by a teammate may cause issue. So: Is there any less painful workaround for this?

Hard coding my machine name (which also could work) causes the very same pain and issue when working in a team and using source control

Q2: Why is this inconsistent behaviour: Pure http://localhost:8631/ works from any browser but not from HttpClient.

I think answering Q2 can get us closer to a more usable workaround.

Code Exhibit

    // 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)
        };
        // ...
g.pickardou
  • 32,346
  • 36
  • 123
  • 268
  • You *don't* need to do anything to use Fiddler with HttpClient. Fiddler sets/resets the default OS proxy so you *don't* need to modify any applications to use it. You can run into problems only if you ... fiddle with the proxy settings or terminate Fiddler before it has a chance to reset the OS proxy, eg by shutting down – Panagiotis Kanavos Mar 29 '16 at 07:22
  • In order to get help with specific problems you need to post the actual code, including any modifications to the system.net proxy settings in app.config – Panagiotis Kanavos Mar 29 '16 at 07:24
  • 1
    Have you tried the fiddler docs for .NET? http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/ConfigureDotNETApp – Phil Cooper Mar 29 '16 at 13:12
  • @PhilCooper: That is what I trying to not to do, because it is painful: "Hard coding (either in code or configuration) an explicit proxy setting (to fiddler or my machine name)." This is painful a) source control/team considerations, b) because you have to switch always when start fiddler or stop fiddler. – g.pickardou Mar 29 '16 at 13:39
  • http://stackoverflow.com/questions/214308/how-do-i-get-fiddler-to-stop-ignoring-traffic-to-localhost – CathalMF Mar 29 '16 at 15:58
  • http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/MonitorLocalTraffic – CathalMF Mar 29 '16 at 15:59

2 Answers2

8

The problem is that the Microsoft implementation of the WebProxy class has a static check for loopback urls (based on a list of names like "localhost") and will bypass any proxy for uris identified as loopback. Even the BypassProxyOnLocal setting will not matter. This setting only has an effect if you use the local machine name or another machine name in the local network. The host localhost or the ip address 127.0.0.1 are always recogized as loopback and will lead to bypassing the proxy.

Relevant part of the .net framework code is in WebProxy.IsBypassedManual:

if (host.IsLoopback) {
    return true; // bypass localhost from using a proxy.
}

Write your own descendant of the WebProxy class and overwrite the GetProxy and IsBypassed methods to return an uri using the proxy even for loopback urls. Then assign an instance of that class to the HttpClientHandler you use to create the HttpClient.

Doesn't seem to work because the .net code expects to work with objects that implement IAutoWebProxy, but IAutoWebProxy is declared internal and cannot be used in our own code.

The easiest solution I see is to have a feature that replaces "localhost" with the local machine name in ApiUrl at runtime. The local machine name will work regardless of whether Fiddler is running or not.

NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • 2
    This is the correct answer. See also https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/6359204-support-the-loopback-token-in-proxy-bypass-lists – EricLaw Mar 31 '16 at 21:14
  • 1
    I use machinename - and fiddler still ignores my httpclient calls to local AND web based web services?! – niico Mar 22 '17 at 16:45
  • @niico Start a new question with details on your code. Maybe you have code that prevents the client from using any proxy or you set a specific proxy yourself? – NineBerry Mar 22 '17 at 17:11
-2

Just define the default proxy to your HttpClient instance and it works like a charm. You do not have to change any URL in your code.

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

We use the same behavior without any issues (Windows 10, Fiddler4).

Benjamin Abt
  • 1,730
  • 18
  • 33
  • Thanks, tried. Unfortunately this does not help. Please note in Diagnostics part I wrote about even explicitly setting the proxy to Fiddler does not help either. However using *localhost.fiddler* instead of localhost helps. The weird thing when using from browser it *works* without the .fiddler doman too. – g.pickardou Mar 29 '16 at 08:39
  • @g.pickardou is your Proxy a SOCK oder HTTP Proxy? Normally Fiddler should create a HTTP Proxy. We use a HTTP Proxy and this works 100% on all machines. Also at customers with Enterprise Proxies. – Benjamin Abt Mar 29 '16 at 09:59
  • I have no proxy at all. Fiddler is a proxy when it is running. – g.pickardou Mar 29 '16 at 10:50