Bug in Uri class?

  • Thread starter Thread starter Dan Ruehle
  • Start date Start date
D

Dan Ruehle

I believe I have found a bug in the Uri class. I believe it is incorrectly
removing periods that appear at the end of segments in the path. The
following code shows what I mean:

public void TestUriAndPeriods()
{
const string urlWithoutPeriod =
"http://my.domain.com/top.level.folder/top.level.folder/my.cool.picture.jpg";
const string urlWithPeriod =
"http://my.domain.com/top.level.folder/top.level.folder./my.cool.picture.jpg";

Uri uriWithoutPeriod = new Uri(urlWithoutPeriod);
Uri uriWithPeriod = new Uri(urlWithPeriod);

if (uriWithoutPeriod.ToString() == uriWithPeriod.ToString())
{
throw new ApplicationException("These Uri's should NOT be equal ");
}
}

The Uri class removes the period at the end of the "second.level.folder."
segment of the path. Per RFC 2396 <http://www.ietf.org/rfc/rfc2396.txt>,
the "./" should only be removed where "." is a complete path segment. Since
it is not in this scenario, it should not be removed.

Normally, this would not be a problem, however I have an application where
customers can provide Uri's to download content. We have some customers
that use Apache and they are somehow generating Uri's that have this
scenario and we have no way to actually hit these Uri's via .Net. Of
course, they respond incorrectly to these requests by returning a zero byte
response body with a 200 HTTP response, but that is another matter for our
customer. Putting the same Uri in IE 7 or FireFox 3 works fine.

I have attempted encoding the period as %2e and that does not seem to help
at all. It just converts it to a period and removes it.

The only workaround I can think of right now means rewriting the WebRequest
and associated classes to manage the underlying TCP connection as they all
utilize the Uri class even when passing in a string to the static creator.
I'd really rather to not have to do this.

Any ideas would be greatly appreciated.
 
Did you ever come up with a work-around for this issue? I'm running into the same thing where the period at the end or a path segment is being removed. I too tried replacing the period with %2E, but to no avail. I even tried replacing "." with ".." thinking it may only remove the last one, but both were removed.

Any help would be greatly appreciated. Thanks.
 
Actually, yes. I opened a case with Microsoft and they would not issue a hotfix based on our business need. They did come up with a workaround:

Per our conversation, our framework dev team will not grant this hotfix due to high-risk impact and the complexity of the Uri parsing logic, but our dev team found a perfect workaround for it yesterday.

The key part is to create your own UriParser rule without CompressPath in Uri, which will override the internal Uri parsing logic.

Here is the sample code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Reflection;

namespace dotUrlApp
{
//The key part is to create your own UriParser rule without CompressPath
class MyUriParser : GenericUriParser
{
public MyUriParser()
: base(GenericUriParserOptions.DontCompressPath)
{
}

//override the GetComponents method to stripe my keyword when sending the request
protected override string GetComponents(Uri uri, UriComponents components, UriFormat format)
{
string rval = base.GetComponents(uri, components, format);

if ((components & UriComponents.Scheme) != 0 && rval.StartsWith("my", StringComparison.OrdinalIgnoreCase))
{
rval = rval.Substring(2);
}

return rval;
}
}


class Program
{
static void Main(string[] args)
{

//Using our own Uri Parser
UriParser.Register(new MyUriParser(), "myhttp", 80);
UriParser.Register(new MyUriParser(), "myhttps", 443);

//getting http://my.domain.com/my.folder./my.file.jpg
Uri myUri = new Uri("myhttp://www.microsoft.com/my.folder./my.file./default.html");

HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(myUri);

//Get the response from the server
HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();

StreamReader sr = new StreamReader(webResp.GetResponseStream(), Encoding.ASCII);

Console.Write(sr.ReadToEnd());
sr.Close();
webResp.Close();
}
}
}

This requires registering new URI Schemes and modifying URI's as you parse them, essentially appending "my" in this example to each URI before parsing. I chose not to implement this solution and strong-armed the company I was dealing with to stop the madness. I have not checked to see if this is fixed in .Net 4.0.

Submitted via EggHeadCafe
Serializing Excel data for input to any Google visualization
http://www.eggheadcafe.com/tutorial...ta-for-input-to-any-google-visualization.aspx
 
Back
Top