Bug 26896 - System.Uri issues with '[' or ']'
Summary: System.Uri issues with '[' or ']'
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: master
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: marcos.henrich
Depends on:
Reported: 2015-02-10 01:38 UTC by heebaek choi
Modified: 2015-03-11 14:15 UTC (History)
6 users (show)

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 GitHub or Developer Community 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 heebaek choi 2015-02-10 01:38:50 UTC
repro step is very simple.

HttpClient client = new HttpClient();
await client.GetStringAsync("http://naver.com/t[e]st.php");			
when you run this code in xamarin.ios, this works fine.(404 not found if url does not exists) but
if you run this code in xamarin.android, they throw URISyntaxException. 

it is not about GetStringAsync function..
other functions in httpclient (like SendAsync) throw same exception when a uri has '[' or ']'

i tested urlencoded string but result is same.
var url = "http://someaddress/somet[e]st.php";
var encoded = urlencode(url);
clent.GetStringAsync(encoded) -> same result
Comment 1 Ram Chandra 2015-02-10 12:05:45 UTC
I have checked this issue and with the help of attached test case I am able to reproduce this issue.

I observed that when I write the test case mentioned in bug description I am getting the following error:

[MonoDroid] Java.Net.URISyntaxException: Exception of type 'Java.Net.URISyntaxException' was thrown.

I have also checked this issue on console and iOS application and observed that on console and iOS application I am getting following exception.

>Unhandled managed exception: 404 (Not Found) (System.Net.Http.HttpRequestException)

Screenshot: http://www.screencast.com/t/F8Wg7ZtJZpR

Application Output: https://gist.github.com/saurabh360/f5a23b5896aa9bcfa473
Device logs: https://gist.github.com/saurabh360/f5a23b5896aa9bcfa473
IDE logs:  https://gist.github.com/saurabh360/7b530222b66abc7a4351

Environment Info:

=== Xamarin Studio ===

Version 5.7.1 (build 17)
Installation UUID: 6ea47b0d-1852-4aaf-808d-373ff0a5002b
	Mono 3.12.0 ((detached/a813491)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 312000068

=== Apple Developer Tools ===

Xcode 6.1 (6604)
Build 6A1052d

=== Xamarin.iOS ===

Version: (Business Edition)
Hash: 3b3ef43
Build date: 2015-01-24 09:42:21-0500

=== Xamarin.Android ===

Version: (Business Edition)
Android SDK: /Users/jatin66/Desktop/Backup/android-sdk-macosx
	Supported Android versions:
		1.6    (API level 4)
		2.1    (API level 7)
		2.2    (API level 8)
		2.3    (API level 10)
		3.1    (API level 12)
		4.0    (API level 14)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
Java SDK: /usr
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

=== Xamarin.Mac ===

Version: (Business Edition)

=== Build Information ===

Release ID: 507010017
Git revision: 0bc7d3550b6b088ac25b08dcf7bbe73bcc8658b3
Build date: 2015-02-03 19:43:29-05
Xamarin addins: f7b7d34419c9ec24501bfa7c658e80a6305613e0

=== Operating System ===

Mac OS X 10.10.0
Darwin Jatin66s-iMac.local 14.0.0 Darwin Kernel Version 14.0.0
    Fri Sep 19 00:26:44 PDT 2014
    root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64
Comment 2 heebaek choi 2015-02-11 10:22:48 UTC
this bug is very critical.
i am making an app, browsing server side resources and viewing images.
but if directory or file name contains '[' or ']', request is not fired and just throw that exception.

can i know when do i get patch about this? 

and please let me know if you have any codes for getting round this bug.

Comment 3 Jonathan Pryor 2015-03-01 20:17:18 UTC
The problem is that Mono's System.Uri type doesn't fully implement RFC 3986.

Consider this app:

  using System;
  class App {
    public static void Main ()
      var url = "http://example.com/t[e]st.txt";
      var u = new Uri (url);
      Console.WriteLine (u.AbsoluteUri);

Compile and run on Mono, and get:

> http://example.com/t[e]st.txt

Compile and run on .NET, and get:

> http://example.com/t%5Be%5Dst.txt

Notice that the '[' and ']' are hex encoded under .NET.

This is required by RFC 3986 §3.3 [0], which states that the URI `path` can consist of `segment`s, wherein:

      segment       = *pchar
      pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"

`unreserved` is in §2.3 [1]:

      unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

`pct-encoded` is percent encoded characters (§2.1), while sub-delims is §2.2:

      sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
                  / "*" / "+" / "," / ";" / "="

It likewise doesn't include '[' or ']', meaning `segment` cannot contain '[' or ']' without first percent encoding them.

[0]: https://tools.ietf.org/html/rfc3986#section-3.3
[1]: https://tools.ietf.org/html/rfc3986#section-2.3
Comment 4 Jonathan Pryor 2015-03-01 20:19:21 UTC
@heebaek choi: What is your `urlencode`  method? If I use HttpUtility.UrlEncode, it does the right thing:

> $ csharp -r:System.Web.dll
> csharp> using System.Web;
> csharp> HttpUtility.UrlEncode ("http://someaddress/somet[e]st.php");
> "http%3a%2f%2fsomeaddress%2fsomet%5be%5dst.php"

Furthermore, if I use "manually" encoded URLs within a Xamarin.Android app, I don't observe the Java.Net.URISyntaxException.
Comment 5 heebaek choi 2015-03-01 23:07:24 UTC
I used System.Net.WebUtility.UrlEncode and Uri.EscapeDataString.

and i test more cases from your reply, i found other clue. 

if i test english url (example [test].txt), it works after urlencoding.
but i test korean url (example [한글].txt), it does not work after url encoding.

I think this bug related Uri class.

Uri class may re escape input string at some condition and Uri class does not re escape '[' and ']'.

please check this again.
Comment 6 marcos.henrich 2015-03-05 08:39:01 UTC
Hi heebaek,

Thank you for the bug report.

I was able to reproduce the issue and I am currently working on a fix.

The problem is that Uri.AbsoluteUri was recently changed to support IRI as specified in RFC 3986.
But we are using a Java URI constructor does an exact parse for RFC 2396.

Until a new version with the fix is released you can use URI without IRI support by adding the following code to the start of your application:

Uri.EscapeDataString (""); //Make sure Uri static constructor is called
FieldInfo iriParsingField = typeof (Uri).GetField ("s_IriParsing", BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic);
if (iriParsingField != null)
    iriParsingField.SetValue (null, false);
Comment 7 heebaek choi 2015-03-06 03:28:08 UTC
I checked this works for me.
Can i know when 'next release'?