HttpClient not fetching auto proxy configuration

TristanSchneiderTristanSchneider Tristan SchneiderUSMember

I'm making an Http post request using HttpClient in a Xamarin Mac project. I have found that this does not pick up on the OS proxy settings that require fetching a proxy auto configuration file from the proxy server. Looking in to the topic I found CFNetworkHandler and NSURLHandler (or something like that). I have tried all combinations of properties exposed on these objects, but none of them will fetch the file properly. However, using CFNetworkHandler at least does pick up on explicit OS proxy settings, whereas using no network handler wouldn't.

To test, I had two machines, (windows) A and (mac) B. I configured the proxy settings of B in Network->Advanced->Proxies, setting "Automatic Proxy Configuration", "Http" and "HTTPS" to all go through machine A. I had wireshark on A capturing all packets from B. I set up a proxy server on A. At all times traffic proxied as expected through A. During normal browsing I could see the Http GET requests fetching the configuration file. However, when doing the http request with HttpClient, there is no configuration file fetch, it instead seems to fall back on the explicit "Https" option, and if that isn't set, it would ignore the proxy entirely.

I found that this feature was implemented here:
https://github.com/mono/mono/commit/f5f69e540e19bae73021c71ff769b98878a478be
So I updated my Mono to 5.2.0.215 (and the Xamarin.Mac to whatever goes with that), but the issue persists.

Is there something that I'm missing? Should this work, or is it a known bug? All similar topics I've seen only concern themselves with local proxies like Charles or Fiddler, which don't use auto configuration. At this point the only alternative I see is to do the query in objective C and make a wrapper project in csharp, which does work, but it's terrible.

The mac project is using target framework .net 4.5. I tried the latest "Unsupported" version which was 4.7, but with no luck. The mac project contains our UI implementation, while we depend on a shared project that targets .net 4.5.1. The query happens as part of the shared code, but the mac portion constructs the network handler to be used for the HttpClient. I get the feeling perhaps I'm using the wrong version somehow that doesn't have proper proxy discovery.

It doesn't matter how complex the Http request is, but here's a stripped down version of what I'm doing that hits the issue.

private async Task<UserGuidResult> DoQuery(string bodyContent, string requestUri) {
    CFNetworkHandler handler = new CFNetworkHandler();
    handler.UseSystemProxy = true;
    using(HttpClient client = new HttpClient(handler)) {
        string appJson = "application/json";
        client.BaseAddress = new Uri(sMUTSUrl);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(appJson));

        HttpResponseMessage response;
        try {
            response = await client.PostAsync(requestUri, new StringContent(bodyContent, Encoding.UTF8, appJson));
        }
        catch(Exception) {
            return null;
        }
        // Do things with response...
}

Best Answer

  • TristanSchneiderTristanSchneider Tristan Schneider USMember
    Accepted Answer

    Ah, thanks for the tip Chris. After further investigation, I found that my initial assumption was wrong. Sending an HTTP request does not necessarily need to cause a PAC file fetch, as this file can be cached.

    It seems that CFNetworkHandler does under some circumstances cause the file fetch, but either way it ignores the contents. I replicated this by setting up a proxy server that serves a PAC file that tells the user to always connect to the proxy, and this is ignored when using CFNetworkHandler.

    Trying this same proxy setup with NSURLSessionHandler worked properly in that the request then went through the proxy. I'm not sure if this behavior is expected in CFNetworkHandler or if it's a bug, but using NSURLSessionHandler is a good enough solution for me.

Answers

  • TristanSchneiderTristanSchneider Tristan Schneider USMember

    Also, please let me know if there is a more appropriate place to ask this question, I'm not too familiar with this forum.

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    So I updated my Mono to 5.2.0.215 (and the Xamarin.Mac to whatever goes with that), but the issue persists.

    Unless you are using "System Mono" target framework then updating your system mono will have no effect. Xamarin.Mac builds in copies of the relevant assemblies and does not link against your system copy in the supported default case.

    You could try swapping to system mono and seeing if that mono has a fix.

    In general this forum is for discussions on the user of Xamarin.Mac. If you believe this is a bug, filing a bug at bugzilla.xamarin.com/index.cgi may also be appropriate.

  • TristanSchneiderTristanSchneider Tristan Schneider USMember
    Accepted Answer

    Ah, thanks for the tip Chris. After further investigation, I found that my initial assumption was wrong. Sending an HTTP request does not necessarily need to cause a PAC file fetch, as this file can be cached.

    It seems that CFNetworkHandler does under some circumstances cause the file fetch, but either way it ignores the contents. I replicated this by setting up a proxy server that serves a PAC file that tells the user to always connect to the proxy, and this is ignored when using CFNetworkHandler.

    Trying this same proxy setup with NSURLSessionHandler worked properly in that the request then went through the proxy. I'm not sure if this behavior is expected in CFNetworkHandler or if it's a bug, but using NSURLSessionHandler is a good enough solution for me.

Sign In or Register to comment.