Bug 16960 - System.Uri class does not match behavior in 4.5 for allowing escaped slashes in Uris
Summary: System.Uri class does not match behavior in 4.5 for allowing escaped slashes ...
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: 3.2.x
Hardware: All Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Miguel de Icaza [MSFT]
Depends on:
Reported: 2013-12-24 20:46 UTC by Glenn Block
Modified: 2014-08-06 13:24 UTC (History)
3 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 Glenn Block 2013-12-24 20:46:23 UTC
In .NET 4.5, the Uri class has been revised to allow unescaped slashes by default in order to align with RFC3986 (http://msdn.microsoft.com/en-us/library/hh367887%28v=vs.110%29.aspx#core).

For example, take the following code, compile in .NET 4.5 and run it.

static void Main(string[] args)
    var uri = new Uri("http://www.yahoo.com/%2F");

and the output will be "http://www.yahoo.com/%2F".

Running in < .NET 4.5 or in Mono 3.x will yield "http://www.yahoo.com//".

Certain API for example Splunk's API rely on being able to send escape encoded paths, which this change allows. Prior to this fix, customer have been hacking into the Uri internals (http://stackoverflow.com/questions/781205/getting-a-url-with-an-url-encoded-slash) on .NET to get the desired behavior. We do this in the Splunk SDK as well.
Comment 1 Glenn Block 2013-12-24 20:49:59 UTC
Clarification above: The Uri class has been revised to allow ESCAPED slashes by default.
Comment 2 Miguel de Icaza [MSFT] 2014-01-03 08:19:13 UTC
The easy answer is to fix this bug.

The question is whether we want to provide support for different profiles.

Currently Mono installs 2.0, 4.5 and mobile based profiles.

I think that we should bit the bullet and fix this for 4.5 and MObile profiles.   The question is whether we should allow some sort of backwards compatibility setting to be set on those or not.
Comment 3 Glenn Block 2014-01-03 14:23:20 UTC
Great that you are going to fix this.

On the switch, I don't really have a sense on who would depend on the old behavior. It's more limiting if anything meaning you would probably just design your system to not encode those chars. However to be safe having a switch might be there right thing. The question is should the switch enable the new behavior, or enable the old....
Comment 4 Miguel de Icaza [MSFT] 2014-01-03 17:55:46 UTC
My take is that we embrace the brave new world, and document the change.

As part of the documented change, we offer a way of enabling the old behavior.

For Mono hackers:

(a) Let us implement the new behavior

(b) Let us expose an internal factory method on Uri that provides the old behavior, users that want to use the old behavior would thus do:

typeof (Uri).GetMethod ("CreateUriEscaped").Invoke (null, myUri)
Comment 5 Glenn Block 2014-01-03 18:28:36 UTC
OK, sounds good to me.

Adding the CreateUriEscaped will provide a second benefit in allowing a Uri helper library (like Purify) to make its behavior no-op if it is running on a newer build of Mono. We do something similar for detecting 4.5: https://github.com/glennblock/PUrify/blob/master/src/PUrify/Purify.cs#L23
Comment 6 marcos.henrich 2014-07-28 08:11:25 UTC

The pull request with fixes for this issue can be found in the link below.

The new behavior will be enable by default on .NET 4.5 and disabled on .NET 4.0 and lower.

We will be able to change the default behavior by using an environment variable (currently MONO_URI_IRIPARSING), or by using reflection to set the private field s_IriParsing. 
The following reflection code shall be used to change behavior in .NET and Mono.

FieldInfo iriParsingField = typeof (Uri).GetField ("s_IriParsing",
    BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic);

iriParsingField.SetValue (null, false);
Comment 7 Miguel de Icaza [MSFT] 2014-07-28 22:03:41 UTC
Hello Marcos,

Does it mean that in NET 4.5 scenarios we will default to the new parsing scheme?

Comment 8 marcos.henrich 2014-07-29 02:01:49 UTC
Hello Miguel,

Yes, it means that in NET 4.5 we will default to the new parsing scheme unless when the environment variable MONO_URI_IRIPARSING is set to false.
Comment 9 marcos.henrich 2014-08-06 13:24:08 UTC
Fixed in master 1f1dc988ad7b165603a1175bf0a92156c4372c43.