Pregunta

Tengo el siguiente problema. Pongo en contacto con una dirección que sé que emplea una redirección 301.

usando HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl); y loHttp.AllowAutoRedirect = false; por lo que no estoy redirigido.

Ahora tengo la cabecera de la respuesta con el fin de identificar la nueva URL.

usando loWebResponse.GetResponseHeader("Location");

El problema es que desde esta URL contiene caracteres griegos la cadena devuelta está todo revuelto (debido a la codificación).

El codewise imagen completa:

HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl);
loHttp.ContentType = "application/x-www-form-urlencoded";
loHttp.Method = "GET";

Timeout = 10000;

loHttp.AllowAutoRedirect = false;
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();

string url= loWebResponse.Headers["Location"];
¿Fue útil?

Solución

Si deja que el comportamiento por defecto (loHttp.AllowAutoRedirect = true) y su código no funciona (no te redirige al nuevo recurso) que significa que el servidor no está codificando la cabecera Location correctamente. Es la redirección trabajando en el navegador?

Por ejemplo, si la URL de redireccionamiento se http://site/Μία_Σελίδα la cabecera Location debe parecerse http://site/%CE%95%CE%BD%CE%B9%CE%B1%CE%AF%CE%BF_%CE%94%CE%B5%CE%.


ACTUALIZACIÓN:

Después de investigar más el asunto empiezo a sospechar que hay algo extraña con HttpWebRequest. Cuando la solicitud se envía al servidor envía la respuesta siguiente:

HTTP/1.1 301 Moved Permanently
Date: Fri, 11 Dec 2009 17:01:04 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Location: http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/
Content-Length: 112
Content-Type: text/html; Charset=UTF-8
Cache-control: private
Connection: close
Set-Cookie: BIGipServerpool_webserver_gr=1007732746.36895.0000; path=/


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Como podemos ver en la cabecera Location contiene caracteres griegos que no están codificados URL. No estoy muy seguro de si esto es válido de acuerdo con el especificación HTTP . Lo que podemos decir con certeza es que un navegador web interpreta correctamente.

Aquí viene la parte interesante. Parece que HttpWebRequest no utiliza codificación UTF-8 para analizar las cabeceras de respuesta debido a la hora de analizar la cabecera Location da: http://www.site.com/buy/κινηÏή-ÏÏαθεÏή-ÏηλεÏÏνία/c/cn69569/, que por supuesto está mal y cuando se intenta redirigir a esta ubicación el servidor responde con una nueva redirección y así sucesivamente hasta que se alcanza el número máximo de redirecciones y se produce una excepción.

No pude encontrar ninguna manera de especificar la codificación utilizado por HttpWebRequest al analizar las cabeceras de respuesta. Si utilizamos TCPClient manualmente funciona perfectamente bien :

using (var client = new TcpClient())
{
    client.Connect("www.site.com", 80);

    using (var stream = client.GetStream())
    {
        var writer = new StreamWriter(stream);
        writer.WriteLine("GET /default/defaultcatg.asp?catg=69569 HTTP/1.1");
        writer.WriteLine("Host: www.site.com");
        writer.WriteLine("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090805 Shiretoko/3.5.2");
        writer.WriteLine("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        writer.WriteLine("Accept-Language: en-us,en;q=0.5");
        writer.WriteLine("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7");
        writer.WriteLine("Connection: close");
        writer.WriteLine(string.Empty);
        writer.WriteLine(string.Empty);
        writer.WriteLine(string.Empty);
        writer.Flush();

        var reader = new StreamReader(stream);
        var response = reader.ReadToEnd();
        // When looking at the response it correctly reads 
        // Location: http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/
    }
}

Así que estoy realmente sorprendido por este comportamiento. ¿Hay alguna manera de especificar la codificación correcta utilizado por HttpWebRequest? Tal vez se debe establecer algún encabezado de la solicitud?

Como solución alternativa podría intentar modificar la página asp que realiza la redirección y urlencode la cabecera Location. Por ejemplo, cuando en una aplicación ASP.NET que realiza una Response.Redirect(location), la ubicación será automáticamente HTML codificados y los caracteres no estándar se convertirán en sus entidades correspondientes.

Por ejemplo, si usted: Response.Redirect("http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/"); en una aplicación ASP.NET la cabecera Location se establecerá en:

http://www.site.com/buy/%ce%ba%ce%b9%ce%bd%ce%b7%cf%84%ce%ae-%cf%83%cf%84%ce%b1%ce%b8%ce%b5%cf%81%ce%ae-%cf%84%ce%b7%ce%bb%ce%b5%cf%86%cf%89%ce%bd%ce%af%ce%b1/c/cn69569

Parece que este no es el caso con ASP clásico.

Otros consejos

Yo no esperaría que la cadena devuelta a ser malformado ... ¿cómo se determine que es mal formado? La cadena debe estar en un formato Unicode, como UTF-8 que sería capaz de representar la cadena griega fácilmente.

Podría ser que simplemente no tienen las fuentes griegas para representar la cadena?

Como explica Darin Dimitrov, creo que la codificación de encabezado es causado por un error en la clase HttpWebResponse. Hemos tenido el mismo problema por el que queremos añadir una galleta a la cabecera (Set-Cookie) y esta cookie sería contener caracteres no ASCII. En nuestro caso esto sería spesific las letras de Noruega Æ ', 'O' y 'A'(en mayúscula y minúscula). No pudimos encontrar la manera de obtener el HeaderEncoding para trabajar, pero encontramos una solución alternativa usando Base64 codificación de la cookie. Tenga en cuenta que esto sólo funcionará si usted está en control tanto del cliente y del lado del servidor (o se puede convencer a la gente a cargo del código del lado del servidor para agregar la codificación Base64 para usted ... )

En el lado del servidor:

var cookieData = "This text contains Norwegian letters; ÆØÅæøå";
var cookieDataAsUtf8Bytes = System.Text.Encoding.UTF8.GetBytes(cookieData);
var cookieDataAsUtf8Base64Encoded = Convert.ToBase64String(cookieDataAsUtf8Bytes);
var cookie = new HttpCookie("MyCookie", cookieDataAsUtf8Base64Encoded);
response.Cookies.Add(cookie);

En el lado del cliente:

var cookieDataAsUtf8Bytes = Convert.FromBase64String(cookieDataAsUtf8Base64Encoded);
var cookieData = System.Text.Encoding.UTF8.GetString(cookieDataAsUtf8Bytes);

Tenga en cuenta que cookieDataAsUtf8Base64Encoded en el lado del cliente es la parte de datos de la cookie (es decir 'MyCookie = [Datos]', donde 'MyCookie =' es despojado de distancia).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top