Domanda

Ho il seguente problema. A contattare un indirizzo che so si avvale di un reindirizzamento 301.

utilizzando HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(lcUrl); e loHttp.AllowAutoRedirect = false; in modo che non sto reindirizzato.

Ora ho l'intestazione della risposta al fine di individuare il nuovo URL.

utilizzando loWebResponse.GetResponseHeader("Location");

Il problema è che dal momento che questo URL contiene i caratteri greci stringa restituita è tutti mescolati fino (a causa di codifica).

Il quadro completo codewise:

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"];
È stato utile?

Soluzione

Se si lascia che il comportamento di default (loHttp.AllowAutoRedirect = true) e il tuo codice non funziona (non vieni reindirizzato alla nuova risorsa), ciò significa che il server non è la codifica l'intestazione Location correttamente. È il reindirizzamento opera nel browser?

Per esempio, se l'URL di reindirizzamento è http://site/Μία_Σελίδα l'intestazione Location deve assomigliare http://site/%CE%95%CE%BD%CE%B9%CE%B1%CE%AF%CE%BF_%CE%94%CE%B5%CE%.


UPDATE:

Dopo aver esaminato ulteriormente la questione comincio a sospettare che ci sia qualcosa di strano con HttpWebRequest. Quando la richiesta viene inviata al server invia la seguente risposta:

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">

Come si può vedere l'intestazione Location contiene caratteri greci che non sono URL codificato. Non sono del tutto sicuro se questo è valido in base al HTTP specifica . Quello che possiamo dire per certo è che un web browser interpreta correttamente.

Qui viene la parte interessante. Sembra che HttpWebRequest non fa uso di codifica UTF-8 per analizzare le intestazioni di risposta, perché quando si analizza l'intestazione Location dà: http://www.site.com/buy/κινηÏή-ÏÏαθεÏή-ÏηλεÏÏνία/c/cn69569/, che ovviamente è sbagliato e quando si tenta di reindirizzare in questa posizione il server risponde con un nuovo reindirizzamento e così via fino al raggiungimento del numero massimo di reindirizzamenti e viene generata un'eccezione.

non riuscivo a trovare un modo per specificare la codifica utilizzata da HttpWebRequest durante l'analisi delle intestazioni di risposta. Se usiamo TCPClient manualmente funziona perfettamente bene :

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/
    }
}

Sono davvero perplesso da questo comportamento. C'è un modo per specificare la codifica corretta usata da HttpWebRequest? Forse qualche intestazione di richiesta deve essere impostato?

Per aggirare il problema si potrebbe provare a modificare la pagina di asp che esegue il reindirizzamento e UrlEncode l'intestazione Location. Per esempio, quando in un'applicazione ASP.NET si esegue un Response.Redirect(location), la posizione sarà automaticamente html codificati e tutti i caratteri non standard saranno convertiti nei loro entità corrispondenti.

Ad esempio se: Response.Redirect("http://www.site.com/buy/κινητή-σταθερή-τηλεφωνία/c/cn69569/"); in un'applicazione ASP.NET l'intestazione Location verrà impostato su:

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

Sembra che questo non è il caso con ASP classico.

Altri suggerimenti

Non mi aspetto la stringa restituita da malformato ... come stai determinando che è deforme? La stringa dovrebbe essere in un formato Unicode come UTF-8 che sarebbe in grado di rappresentare la stringa greco facilmente.

Potrebbe essere che semplicemente non hanno i caratteri greci per rappresentare la stringa?

Come spiega Darin Dimitrov, credo che la codifica intestazione è causato da un bug nella classe HttpWebResponse. Abbiamo avuto lo stesso problema per cui abbiamo voluto aggiungere un cookie al intestazione (Set-Cookie) e questo cookie potrebbe contenere caratteri non ASCII. Nel nostro caso spesific questo sarebbe le lettere norvegesi Æ ', 'O' e 'A'(in alto e in basso a caso). Non siamo riusciti a capire come ottenere il HeaderEncoding di lavorare, ma abbiamo trovato un work-around con Base64-encoding del cookie. Si noti che questo funziona solo se si è in controllo sia del client e lato server (o si può convincere la gente responsabile del codice lato server per aggiungere la codifica Base64 per voi ... )

Sul lato server:

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

Sul lato client:

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

Si noti che cookieDataAsUtf8Base64Encoded sul lato client è la parte dei dati del cookie (cioè 'MyCookie = [i dati]', dove 'MyCookie =' viene strappato via).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top