c Encoding # HttpWebResponse
-
19-09-2019 - |
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"];
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).