Obtener una URL con una barra diagonal codificada


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

Desafortunadamente, puedo ver que lo que realmente se envía en el cable es:

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

So 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 ordena enviar la codificación url de una codificación base-64 cuando se usa OCSP sobre HTTP / GET, por lo que es necesario enviar un %2F real en lugar de un ' / ' para ser compatible.

EDITAR:

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

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

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

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

Author: svick, 2009-04-23

4 answers

Por defecto, la clase Uri no permitirá un carácter escapado / (%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 utilice Uri.toString para imprimir URI.)

De acuerdo con el informe de error de para este problema en Microsoft Connect, este comportamiento es por diseño, pero puede solucionarlo agregando lo siguiente a su aplicación.config o web.archivo de configuración:

<uri>
  <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
  </schemeSettings>
</uri>

(Reposted from https://stackoverflow.com/a/10415482 porque esta es la forma "oficial" de evitar este error sin usar reflexión para modificar los campos privados.)

Editar: El informe de error de Connect ya no es visible, pero la documentación de para <schemeSettings> recomienda este enfoque para permitir caracteres escapados / en URI. Tenga en cuenta (de acuerdo con ese artículo) que puede haber implicaciones de seguridad para los componentes que no manejan barras escapadas correctamente.

 24
Author: Bradley Grainger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-12 03:36:08

Este es un terrible hackeo, destinado a ser incompatible con futuras versiones del framework y así sucesivamente.

¡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);
}
 41
Author: Rasmus Faber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-04 10:10:10

Actualización sobre esto: Parece que el comportamiento predeterminado de la clase Uri fue en realidad cambiado en.NET 4.5, y ahora puede usar barras de escape 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 la traza muestra que %2F fue de hecho sin escapar como se esperaba.

Traza de violinista

Sin embargo, En. NET 4.5 / 4.5.1 puede ver que %2F no se ha escapado (observe que / %2F)

Traza de violinista

Puedes incluso usar toString() ahora en el Uri y obtendrás el mismo resultado.

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

Acabo de hacer una exploración de tratar de conseguir el mismo enfoque trabajando en Mono. He publicado mi pregunta sobre el enfoque aquí: Obtener un Uri con barras de escape en mono

 10
Author: Glenn Block,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:05

Doble codificar : %252F

Pero también si usa HttpWebRequest, puede decirle que no codifique la URL, de cualquier manera debería funcionar.

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

 -7
Author: dr. evil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-23 10:55:52