HttpWebResponse.Characterset Vrs. Html Header Charset

Demanda: Ler uma url e utilizar o html obtido para enviar um e-mail.

Tudo “às pampas”, até ver que os “ç” e outros caracteres ‘especiais’ do nosso idioma acabam apresentados de forma erronia.

Mas qual set de caracteres devo utilizar afinal?
Não há resposta para esta pergunta, pois devo ler corretamente qualquer url. De qualquer idioma.

Logo, vou utilizar o set de caracteres exposto pelo servidor web como integrante do cabeçalho do response.

string responsePlainText = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("thiagotimm.wordpress.com");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string charSetServer = response.CharacterSet;
using (Stream responseStream = response.GetResponseStream())
	using (StreamReader responseStreamHeader = new StreamReader(responseStream, System.Text.Encoding.GetEncoding(charSetServer)))
		responsePlainText = responseStreamHeader.ReadToEnd();

Perfeito!
Agora algumas paginas html são lidas corretamente.
Entretanto outras insistem em não utilizar o correto set de caracteres.
Porem, o browser exibe-as corretamente. Mas eu ainda não consigo ler.

Claro.
Ao hospedar o html em um servidor web, muitos não tem disponibilizado a configuração do web server para nele informar qual o set de caracteres.
Logo, ao escrever o html, é inserido no mesmo, dentro da tag head, o correto set de caracteres para apresentação. Como exemplificado abaixo.

<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
...
</head>

Com esta abordagem, indifere qual o set de caracteres configurado no web-server. Devo considerar o set de caracteres especificado no html, ignorando o recebido do web-server inicialmente.

string responsePlainText = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("thiagotimm.wordpress.com");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string charSetServer = response.CharacterSet;
using (Stream responseStream = response.GetResponseStream())
	using (StreamReader responseStreamHeader = new StreamReader(responseStream, System.Text.Encoding.GetEncoding(charSetServer)))
		responsePlainText = responseStreamHeader.ReadToEnd();

if (!string.IsNullOrEmpty(responsePlainText))
{
    int charSetPageIdxStart = responsePlainText.IndexOf("charset=");
    if (charSetPageIdxStart > 0)
    {
        charSetPageIdxStart += 8;
        int charSetPageIdxEnd = responsePlainText.IndexOfAny(new char[] { ' ', '\"', ';' }, charSetPageIdxStart);
        string charSetPage = responsePlainText.Substring(charSetPageIdxStart, charSetPageIdxEnd - charSetPageIdxStart);
        if (!string.Compare(charSetPage, charSetServer, true).Equals(0))
        {
            request = (HttpWebRequest)WebRequest.Create("thiagotimm.wordpress.com");
            response = (HttpWebResponse)request.GetResponse();
            using (Stream responseStream = response.GetResponseStream())
                using (StreamReader responseStreamHeader = new StreamReader(responseStream, System.Text.Encoding.GetEncoding(charSetPage)))
                    responsePlainText = responseStreamHeader.ReadToEnd();
        }
    }
}

Notem no snippet acima que, se o set de caracteres primeiramente obtido do web-server for diferente do obtido ao ler o header do html, não consigo evitar o segundo request. Isto porque meu response inical já foi lido com o set errado.

Nasce aí a necessidade, de acordo com a demanda, da utilização de um cache. O que vocês me dizem?

Mas isto já é tema para um próximo post!

T+

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s