Pergunta sobre cgi, apache, c++, internet-explorer-8, compression – Internet Explorer 8 + Deflate

5

Eu tenho um problema muito estranho .. Eu realmente espero que alguém tenha uma resposta, porque eu não sei onde mais perguntar.

Estou escrevendo um aplicativo cgi em C ++ que é executado pelo Apache e gera o código HTML. Eu estou compactando a saída HTML sozinho - de dentro do meu aplicativo C ++ - desde o meu host não suporta mod_deflate por algum motivo.

Eu testei isso com o Firefox 2, Firefox 3, Opera 9, Opera 10, Google Chrome, Safari, IE6, IE7, IE8, mesmo wget .. Ele trabalha comQUALQUER COISA exceto IE8.

O IE8 apenas diz "O Internet Explorer não pode exibir a página da Web", sem nenhuma informação. Eu sei que é por causa da compressão só porque funciona se eu desabilitá-lo.

Você sabe o que estou fazendo errado?

Eu uso o zlib para compactá-lo e o código exato é:

    /* Compress it */
int compressed_output_size = content.length() + (content.length() * 0.2) + 16;
char *compressed_output = (char *)Alloc(compressed_output_size);
int compressed_output_length;
Compress(compressed_output, compressed_output_size, (void *)content.c_str(), content.length(), &compressed_output_length);

/* Send the compressed header */
cout << "Content-Encoding: deflate\r\n";
cout << boost::format("Content-Length: %d\r\n") % compressed_output_length;
cgiHeaderContentType("text/html");
cout.write(compressed_output, compressed_output_length);


static void Compress(void *to, size_t to_size, void *from, size_t from_size, int *final_size)
{
int ret;
z_stream stream;

stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;

if ((ret = deflateInit(&stream, CompressionSpeed)) != Z_OK)
    COMPRESSION_ERROR("deflateInit() failed: %d", ret);

stream.next_out = (Bytef *)to;
stream.avail_out = (uInt)to_size;
stream.next_in = (Bytef *)from;
stream.avail_in = (uInt)from_size;

if ((ret = deflate(&stream, Z_NO_FLUSH)) != Z_OK)
    COMPRESSION_ERROR("deflate() failed: %d", ret);

if (stream.avail_in != 0)
    COMPRESSION_ERROR("stream.avail_in is not 0 (it's %d)", stream.avail_in);

if ((ret = deflate(&stream, Z_FINISH)) != Z_STREAM_END)
    COMPRESSION_ERROR("deflate() failed: %d", ret);

if ((ret = deflateEnd(&stream)) != Z_OK)
    COMPRESSION_ERROR("deflateEnd() failed: %d", ret);

if (final_size)
    *final_size = stream.total_out;
return;
}
Ele envia ambos deflate e gzip como Accept-Encoding. Eu verifico se contém "deflacionar" antes de enviar qualquer saída deflacionada. Thomas Bonini
Além disso, certifique-se de ler essa perguntastackoverflow.com/questions/388595/…. Melhor ficar com o gzip. Eye
cout << boost :: format ("Content-Encoding:% s \ r \ n")% ((UserAgent.GetBrowser () == INTERNET_EXPLORER && UserAgent.GetVersion ()> = 8)? "gzip": "esvaziar" ); // Bem, isso corrige isso. Ainda procurando uma resposta real, se alguém puder inventar um. Thomas Bonini
Parece que é hora de realizar a detecção do agente do usuário. Sim, é um hack feio, mas na minha experiência limitada o desenvolvimento web está cheio deles. j_random_hacker

Sua resposta

2   a resposta
5

s, mas existem algumas diferenças sutis com o cabeçalho, então, se você alterar sua codificação de conteúdo, você também deve alterar seus parâmetros para o método de codificação (especificamente , o tamanho da janela)!

Vejo:http://apcmag.com/improve_your_site_with_http_compression.htm

Provavelmente, os outros navegadores estão ignorando sua especificação de codificação de conteúdo e fazendo algum reconhecimento automático, mas o IE8 não é ...

Vejo:http://www.zlib.net/manual.html#deflateInit2

Tente usar:

method=Z_DEFLATED
windowBits=-15  (negative so that the header is suppressed)

E use "gzip" como codificação de conteúdo

+1, bom encontrar! Goste disso, um bug no mod_gzip. j_random_hacker
nossa, obrigada! Eu te amo: D Uma pequena correção, no entanto. Existem 3 (!) Formatos de compactação: zlib - o que eu estava usando, que eu achava que era "deflate" -, deflate e gzip. Como se não fosse confuso o suficiente, todos os 3 deles são aparentemente criados usando a biblioteca zlib. Não especificando o windowBits (como eu estava fazendo) produz o formato zlib, usando um valor negativo (como você sugeriu) gera umDEFLATED formato (não gzip!). Eu não tenho certeza ainda como produzir o formato gzip (e eu não me importo, agora ele funciona com deflate em todos os navegadores). OBRIGADO NOVAMENTE!! :) Thomas Bonini
5

como eu escrevi meu próprio algoritmo deflate, meu próprio servidor HTTP, e para meu espanto IE8 também não conseguiu reconhecer o meu conteúdo deflacionado:

HTTP RFC éhttp://www.faqs.org/ftp/rfc/rfc2616.pdf. Página 17 afirma tanto RFC 1950 e RFC 1951 é usado ao executar um deflate nos cabeçalhos HTTP. A RFC 1950 está simplesmente definindo os bytes do cabeçalho e do trailer; o deflate algoritmo é definido no RFC 1951. Quando eu programado isso para especificação, o IE8 falhou.

Quando eu ignorei o RFC 1950 e só fiz o RFC 1951, ele passou.

Suponho, então, que o IE8 não está seguindo corretamente a RFC 2616 página 17, e todos os outros navegadores são bons o suficiente para aceitar qualquer formato.

Acabei de encontrar o proxy de cache da web de um cliente que está forçando a esvaziar e adivinhar qual implementação eles escolheram? O errado, provavelmente para suportar o IE8. Infelizmente, nosso cliente Java, usando bibliotecas HTTP padrão, espera a implementação de esvaziamento correta. Eu terei que desativar o deflate support em nosso cliente, e forçá-los a usar o gzip ou nada. Marcus Adams

Perguntas relacionadas