Bug 43411 - HTTP Bad Request (400) when encoding space (%20) in URL with AndroidClientHandler
Summary: HTTP Bad Request (400) when encoding space (%20) in URL with AndroidClientHan...
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 6.0.2 (C6SR2)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Marek Habersack
Depends on:
Reported: 2016-08-16 12:36 UTC by Thomas Van den Bossche
Modified: 2017-12-05 16:53 UTC (History)
9 users (show)

Is this bug a regression?: ---
Last known good build:

Test project to validate the issue. (30.72 KB, application/zip)
2016-08-16 12:37 UTC, Thomas Van den Bossche
Charles proxy output (47.42 KB, image/jpeg)
2016-08-19 12:19 UTC, Thomas Van den Bossche

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 Thomas Van den Bossche 2016-08-16 12:36:20 UTC
When calling a URL with a space in the URL or with the space encoded (%20) the response is always a 400 (Bad Request).
When switching to the .NET HttpClientHandler, the error does not occur.

Test URL: http://ipinfo.io/?example=value%20_value

I've added a test project to reproduce this error.
Comment 1 Thomas Van den Bossche 2016-08-16 12:37:12 UTC
Created attachment 17041 [details]
Test project to validate the issue.
Comment 2 Thomas Van den Bossche 2016-08-19 12:19:01 UTC
Created attachment 17124 [details]
Charles proxy output
Comment 3 Thomas Van den Bossche 2016-08-19 12:19:56 UTC
It strips the part after the space from the URL and uses it as a protocol it seems? (see new attachement of the output from Charles)
Comment 4 Marek Habersack 2016-08-19 14:12:18 UTC
@Thomas, I'm about to look at this. The problem is in the Java client our handler uses underneath, so I'll need to find a way to work around this issue.
Comment 5 Marek Habersack 2016-08-19 16:23:32 UTC
@Thomas, so it appears to be a combination of issues in both our code and Java's. .NET's Uri class didn't encode the URL in its ToString() method and we passed the unencoded result to Java's URL class which, in turn, doesn't properly encode the passed URL and that in turn leads to the broken behavior you reported.

Fixed in https://github.com/xamarin/xamarin-android/commit/3675c5c6a6a5b9f0c65106e7ab5b08358c5fc82a
Comment 10 Marek Habersack 2016-09-14 09:02:58 UTC
A PR which fixes the query case is up: https://github.com/xamarin/xamarin-android/pull/222
Comment 11 Marek Habersack 2016-09-14 17:58:18 UTC
Fixed in xamarin-android/master, commit 4f6a0af7da6a0da75aaf14b28e9380784916db23
Comment 12 Marek Habersack 2016-09-14 18:13:47 UTC
Fixed in monodroid/master, commit 5258d8782f6b7de922bebf8da8d30fddc8e61177
Comment 15 Mohit Kheterpal 2016-09-19 15:17:28 UTC
I have checked this issue with latest build of C8SR0 xamarin.android-7.0.0-23_dd519cec902b100f06dc2e618003855b249a5318 and observed that this issue has been fixed as shown in screencast : http://www.screencast.com/t/UP05z0UYru

Hence, closing this issue by marking it as Verified.

Comment 16 Justin Toth 2017-12-05 16:53:12 UTC
I think this bug has resurfaced... I just switched from ModernHttpClient to AndroidHttpClient (because ModernHttpClient doesn't support HTTP/2), and now I'm seeing this exact issue. 

If I call our api with an encoded space in the url, it works fine:


However if I add in an encoded comma, it gives a 400 bad request error:


If I don't encode the comma, it works:

https://mobileapi-int.narrpr.com/v14/searches/properties/Irvine, CA

However, then I get into trouble if trying to use other symbols. For example when trying to use a #, both of these error:

https://mobileapi-int.narrpr.com/v14/searches/properties/20 pine bark ct #20 cockeysville md

https://mobileapi-int.narrpr.com/v14/searches/properties/20 pine bark ct %2320 cockeysville md

Going back to the first example... The interesting thing is that if I debug the request and response, when I pass in the request uri (which has an AbsolutePath of "/v14/searches/properties/irvine%2C%20ca") to the http client's GetAsync method, when I check the erroring task's Result.RequestMessage.RequestUri.AbsolutePath it is set to  "/v14/searches/properties/irvine%252C%20ca". So it looks like Xamarin is updating "%2C%20" to "%252C%20", which isn't right and causes the bad request.

public Task<QueryResponse<TResult>> GetAsync<TResult> (UriBuilder uriBuilder, CancellationToken cancellationToken) {
            var uri = GetUri (uriBuilder);
            var antecedent = base.GetAsync (uri).ObserveFailures ();
            return antecedent.ContinueWith (a => {
                var response = new QueryResponse<TResult> (a.Result.StatusCode);
                if (!a.Result.HasServerError (response, uri.AbsolutePath))
                    response.Response = ReadResponseContent<TResult> (a.Result);
                return response;
            }, cancellationToken).ObserveFailures ();