views:

1078

answers:

4

I want to send a HTTP GET to http://example.com/%2F. My first guess would be something like this:

using (WebClient webClient = new WebClient())
{
  webClient.DownloadData("http://example.com/%2F");
}

Unfortunately, I can see that what is actually sent on the wire is:

GET // HTTP/1.1
Host: example.com
Connection: Keep-Alive

So http://example.com/%2F gets translated into http://example.com// before transmitting it.

Is there a way to actually send this GET-request?

The OCSP-protocol mandates sending the url-encoding of a base-64-encoding when using OCSP over HTTP/GET, so it is necessary to send an actual %2F rather than an '/' to be compliant.

EDIT:

Here is the relevant part of the OCSP protocol standard (RFC 2560 Appendix A.1.1):

An OCSP request using the GET method is constructed as follows:

GET {url}/{url-encoding of base-64 encoding of the DER encoding of the OCSPRequest}

I am very open to other readings of this, but I cannot see what else could be meant.

A: 

%2F can not be used in path, however it can be used after query string like

/?%2F <-- this will be correct one...

Akash Kava
Do you mean that http://example.com/%2F is an illegal path? Or just that .NET cannot handle it?
Rasmus Faber
A: 

Double encode it : %252F

But also if you use HttpWebRequest you can actually tell not to encode the URL, either way it should work.

Also If WebClient accepts URI then you can create a new URI and you can set it to not encode.

dr. evil
If I try to get http://example.com/%252F, it actually sends GET /%252F, so that does not work. The URI-constructor with dontEscape is deprecated since 2.0 and according to the documentation, the dontEscape-parameter is ignored. Was that what you meant about using HttpWebRequest?
Rasmus Faber
Check if the problem is in URI constructor? or the actual sending process? this can help to diagnose to exact problem.
dr. evil
A: 

Sounds like a bug in the OCSP protocol to me (or, alternatively, a misinterpretation of it).

Julian Reschke
+3  A: 

This is a terrible hack, bound to be uncompatible with future versions of the framework and so on.

But it works!

(on my machine...)

Uri uri = new Uri("http://example.com/%2F");
ForceCanonicalPathAndQuery(uri);
using (WebClient webClient = new WebClient())
{
  webClient.DownloadData(uri);
}

void ForceCanonicalPathAndQuery(Uri uri){
  string paq = uri.PathAndQuery; // need to access PathAndQuery
  FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
  ulong flags = (ulong) flagsFieldInfo.GetValue(uri);
  flags &= ~((ulong) 0x30); // Flags.PathNotCanonical|Flags.QueryNotCanonical
  flagsFieldInfo.SetValue(uri, flags);
}
Rasmus Faber
+1. Perfect! I needed this to get the Google Webmaster Tools API to work.
David
works indeed. I wonder what the reason is for them not allowing the 'dontEscape' parameter?
Patrick Klug