Bug 55305 - AndroidClientHandler ignores timeout value when trying to connect on misconfigured networks.
Summary: AndroidClientHandler ignores timeout value when trying to connect on misconfi...
Alias: None
Product: Android
Classification: Xamarin
Component: Android+BCL Integration ()
Version: 7.2 (15.1)
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Marek Habersack
Depends on:
Reported: 2017-04-17 20:24 UTC by Jeremy Cook
Modified: 2017-11-02 17:35 UTC (History)
7 users (show)

Tags: xamexttriage, xamextfollowed
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Jeremy Cook 2017-04-17 20:24:10 UTC
This is a new issue related to (but not fixed in)  https://bugzilla.xamarin.com/show_bug.cgi?id=44673.

The latest changes in Android 7.2 release still do not work if using a misconfigured network (incorrect proxy settings, network requires login to use, etc).  On these networks, all HTTP connect calls block on the Connect() call for 2 minutes or more, regardless of the timeout specified.  In this case, I do see the httpConnection.Disconnect() call made when the token is cancelled, but that has no effect.  

The only way I am able to get around this is to specify a ConnectTimeout to the HttpURLConnection in AndroidClientHandler's SendAsync() method.  For example (around line 210 of AndroidClientHandler.cs):
            while (true)
                URL java_url = new URL(EncodeUrl(redirectState.NewUrl));
                URLConnection java_connection = java_url.OpenConnection();
                java_connection.ConnectTimeout = 10000; // 10 seconds
                HttpURLConnection httpConnection = await SetupRequestInternal(request, java_connection).ConfigureAwait(continueOnCapturedContext: false); ;
                HttpResponseMessage response = await ProcessRequest(request, java_url, httpConnection, cancellationToken, redirectState).ConfigureAwait(continueOnCapturedContext: false); ;

This workaround isn't perfect.  For example, when I specify a 10 second timeout like above, most of the Android devices I test in take 20-30 seconds for the timeout to happen.  A few others take longer.   We need a reliable way of specifying a timeout here, as misconfigured networks are common in our environment and a 2 minute wait is not acceptable.

Comment 2 Marek Habersack 2017-06-08 09:37:44 UTC
The fix will be available in the next Xamarin.Android release.
Comment 3 Luis Aguilera 2017-06-23 05:02:04 UTC
this should be fixed in the Xamarin.Android build currently in beta,
Comment 4 Luis Aguilera 2017-06-23 05:05:30 UTC
comment 3 is not entirely correct... while the change is available in the Android build on macOS (and that build is in the beta channel) it is not yet available on Windows. Instead, it should be present in the upcoming VS2017 15.3 Preview 3 build, which is expected to release sometime during the week of June 26
Comment 5 Jeremy Cook 2017-11-02 17:35:05 UTC
@Jonathan, you mention it's fixed *in part* by that commit in AndroidClientHander.cs.   My recent testing on this shows no difference in behavior.. i still observe the timeout taking 2x to 4x the amount specified in the connection value.   What other change(s) were a part of this fix?    If I write a native Android app that does the same thing, the timeout works correctly.