OBTENER una URL con una barra con encoding URL

Deseo enviar un HTTP GET a http://example.com/%2F . Mi primera suposición sería algo como esto:

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

Lamentablemente, puedo ver que lo que realmente se envía por el cable es:

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

Por lo tanto, http://example.com/%2F se traduce a http://example.com// antes de transmitirlo.

¿Hay alguna manera de enviar realmente esta solicitud GET?

El protocolo OCSP exige el envío de la encoding url de una encoding base-64 cuando se utiliza OCSP a través de HTTP / GET, por lo que es necesario enviar un% 2F real en lugar de un ‘/’ para que sea compatible.

EDITAR:

Aquí está la parte relevante del estándar de protocolo OCSP ( RFC 2560 Apéndice A.1.1):

Una solicitud OCSP que utiliza el método GET se construye de la siguiente manera:

OBTENGA {url} / {url-encoding de encoding base-64 de la encoding DER de OCSPRequest}

Estoy muy abierto a otras lecturas de esto, pero no puedo ver qué más podría significar.

Por defecto, la clase Uri no permitirá un escape / carácter ( %2f ) en un URI (aunque esto parece ser legal en mi lectura de RFC 3986 ).

 Uri uri = new Uri("http://example.com/%2F"); Console.WriteLine(uri.AbsoluteUri); // prints: http://example.com// 

(Nota: no use Uri.ToString para imprimir URI).

Según el informe de error para este problema en Microsoft Connect, este comportamiento es por diseño, pero puede solucionarlo agregando lo siguiente a su archivo app.config o web.config:

      

(Repostado de https://stackoverflow.com/a/10415482 porque esta es la forma “oficial” de evitar este error sin usar el reflection para modificar campos privados).

Editar: El informe de errores de Connect ya no está visible, pero la documentación de recomienda este enfoque para permitir el escape de caracteres en URI. Tenga en cuenta (según dicho artículo) que puede haber implicaciones de seguridad para los componentes que no manejan las barras escapó correctamente.

Este es un truco terrible, inevitablemente incompatible con las versiones futuras del marco y demás.

¡Pero funciona!

(en mi máquina …)

 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); } 

Actualice sobre esto: parece que el comportamiento predeterminado de la clase Uri realmente se modificó en .NET 4.5, y ahora puede usar barras oblicuas y no se tocarán.

Ejecuté el siguiente código en .NET 3.5, .NET 4.0, .NET 4.5 / 4.5.1

 static void Main(string[] args) { var uri = new Uri("http://www.yahooo.com/%2F"); var client = new WebClient(); client.DownloadString(uri); } 

En .NET 3.5 / 4.0, el rastreo muestra que, en realidad, el% 2F se ajustó como se esperaba.

Fiddler trace

Sin embargo, en .NET 4.5 / 4.5.1, puede ver que% 2F no se ajustó (observe el GET /% 2F)

Fiddler trace

Incluso puede usar ToString () ahora en el Uri y obtendrá el mismo resultado.

Entonces, en conclusión, parece que si está usando .NET> = .NET 4.5, entonces las cosas se comportarán como deberían en línea con el RFC.

Solo hice una exploración de intentar obtener el mismo enfoque trabajando en Mono. Publiqué mi pregunta sobre el enfoque aquí: Obteniendo un Uri con barras oblicuas en mono

Doble encoding: % 252F

Pero también si usas HttpWebRequest puedes decirle que no codifique la URL, de cualquier forma debería funcionar.

Además, si WebClient acepta URI, puede crear un nuevo URI y puede configurarlo para que no se codifique.