HTTP Traffic monitoring issue when using MonoTouch, HttpClient and Charles Proxy
Asked Answered
A

1

7

I'm new to HttpClient class and I'm having issue with monitoring requests using Charles Proxy. Basically what I need is to monitor the requests which are made either from simulator or actual iOS device. Here you can find a great tutorial of how to configure Charles for iOS development. I was making simple HttpClient requests for instance, just a simple authorisation

async Task<string>  authorizeUser()
        {
            HttpClient _client = new HttpClient ();
            _client.BaseAddress = new Uri("https://...../api/");
            _client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue ("bearer", token);
            var content = new FormUrlEncodedContent(new[] 
                {
                    new KeyValuePair<string, string>("grant_type", "password"),
                    new KeyValuePair<string, string>("username", "theUserName"),
                    new KeyValuePair<string, string>("password", "thePassword")
                });
            var result = await _client.PostAsync("auth", content);
            string resultContent = result.Content.ReadAsStringAsync().Result;
            return resultContent;
        }

The code works, the user is being authorised, and the bearer token is being returned. But what was the issue, that my requests on the simulator were not appearing in the Charles http traffic monitoring list.

I thought perhaps, it is because I'm using simulator, but that was not the case. I tried opening the safari and browsed some web page and the traffic immediately appeared. So the issue was not from the simulator.

I also tried installing on the device, and again the same story, when using HttpClient the traffic monitoring screen remains silent, but as soon as I open the browser, the traffic screen starts jiggling and usurping all the requests.

I thought may be it is because I use HTTPS, although in any case at least the request header should be captured, even though the body is encoded. But that was not the case, I tried opening some HTTPS site on my device safari and again the traffic appeared on my Charles screen.

The next thing that I did I downloaded monotouch HttpClient sample. And the good news is that there are several methods of sending requests, actually four of them - 1. http WebRequest, 2. https WebRequest, 3. http NSUrlConnection , 4. HttpClient.

And I tried them all, as you may guess first three perfectly appeared in charles, but the last HttpClient again I don't know why didn't show up in traffic log screen.

So I'm 100% sure that the issue is the HttpClient class, which I don't know why despite the fact that it is working normally, that is sending/receiving requests, the requests made by this class can not be captured by Charles.

And to exclude the last possible reason for this issue, that is may be the problem is in Charles, I also tried using Fiddler on Windows, which was running as a virtual machine on my Mac (here you can find how to do that), the same story was repeated - all the requests made by HttpClient were not captured, the rest (WebRequests, NSUrlConnection-s, safari web page openings) worked perfectly fine.

Please, can anybody suggest me, whether it is some kind of bug, may be there is workaround or other solution to this problem.

Thanks all for your Replies

Kind Regards Gagik

Areopagite answered 6/5, 2014 at 10:26 Comment(1)
I'm not very familiar with Charles proxy, but if you are unable to get that working, you might try using Runscope.com It works as a HTTP debugging intermediary and there is a free plan. Disclaimer, I work as a dev advocate for Runscope.Pronation
S
6

There's many ways to initialize HttpClient. Some ways won't talk with the OS (fully managed) and won't be aware of the iOS proxy settings.

The best (for iOS) is generally to use the handler that uses CFNetwork, see this blog for more details. Basically it means:

var client = new HttpClient (CFNetworkHandler ());

Otherwise you'll need to set the HttpClientHandler.Proxy to CFNetwork.GetDefaultProxy. E.g.

var handler = new HttpClientHandler {
    Proxy = CFNetwork.GetDefaultProxy (),
    UseProxy = true,
};
var client = new HttpClient(handler);
Singleton answered 15/5, 2014 at 12:42 Comment(1)
Another option, if Cookie handling or some other feature that deviates from the normal handler's behavior prevents you from using the "Modern" or native handler, is to use static methods available on WebRequest or WebProxy for getting the default/system proxies or getting proxies by Uri.Obsolesce

© 2022 - 2024 — McMap. All rights reserved.