2009-07-03 40 views
5

Tengo un problema muy extraño ... Realmente espero que alguien tenga una respuesta porque no sabría a quién más preguntarle.Internet Explorer 8 + Deflate

Estoy escribiendo una aplicación cgi en C++ que es ejecutada por Apache y emite código HTML. Estoy comprimiendo el resultado HTML yo mismo, desde mi aplicación C++, ya que mi servidor web no admite mod_deflate por algún motivo.

He probado esto con Firefox 2, Firefox 3, Opera 9, Opera 10, Google Chrome, Safari, Internet Explorer 6, Internet Explorer 7, IE8, incluso wget .. Funciona con NADA excepto IE8.

IE8 solo dice "Internet Explorer no puede mostrar la página web", sin ninguna información. Sé que es debido a la compresión solo porque funciona si lo desactivo.

¿Sabes lo que estoy haciendo mal?

utilizo zlib para comprimir, y el código exacto es:

/* 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; 
} 
+0

bien, esto es raro. Si envío "gzip" como codificación de contenido, funciona en IE8, pero en cualquier otro navegador ...: Error de codificación de contenido La página que intenta ver no se puede mostrar porque utiliza una forma no válida o no compatible compresión. –

+1

Después de más intentos ... Si envío la codificación de contenido como gzip (¡no lo es!), Funciona en el explorador de Internet solo en cualquier versión, incluido ie8, mientras que no funciona en ningún otro navegador. Si envío desinflar, el correcto, funciona en cualquier navegador incluyendo ie6 y ie7 pero no en ie8 <. < –

+0

Parece que es hora de realizar la detección de agente de usuario.Sí, es un hack feo, pero en mi limitada experiencia, el desarrollo web está lleno de ellos. –

Respuesta

5

El gzip y desinflar métodos no son lo mismo ... que están muy cerca, pero hay algunas diferencias sutiles con el encabezado, entonces, si cambia su codificación de contenido, también debe cambiar sus parámetros al método de codificación (específicamente, el tamaño de la ventana).

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

Es probable que los otros navegadores están ignorando su especificación Content-Encoding y haciendo algo de reconocimiento automático, pero IE8 no es ...

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

Trate de usar:

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

Y el uso de "gzip" como el contenido de codificación de

+2

guau, gracias! Te amo: D Una pequeña corrección, sin embargo. Hay 3 (!) Formatos de compresión: zlib, el que estaba usando, que pensé que era "desinflar", desinflar y gzip. Como si no fuera lo suficientemente confuso, aparentemente los 3 se crearon utilizando la biblioteca zlib. Al no especificar los Bits de ventana (como estaba haciendo), se emite el formato zlib, usando un valor negativo (como sugirió) se emite un formato ** DEFLATED ** (¡no gzip!). Todavía no estoy seguro de cómo generar el formato gzip (y no me importa, ahora funciona con deflate en todos los navegadores). ¡¡GRACIAS DE NUEVO!! :) –

+0

+1, buen descubrimiento! Eso es un error en mod_gzip. –

5

Yo quería aclarar lo que he descubierto en esto, como he escrito mi propio algoritmo deflate, mi propio servidor HTTP, y para mi consternación IE8 también se abstuvo de reconocer el contenido de mi desinflado:

RFC HTTP es http://www.faqs.org/ftp/rfc/rfc2616.pdf. Página 17 estados tanto RFC 1950 como RFC 1951 se utilizan cuando se realiza un desinflado en los encabezados HTTP. RFC 1950 simplemente está definiendo los bytes del encabezado y del remolque; el algoritmo de desinflado se define en RFC 1951. Cuando programé esto a la especificación, IE8 falló.

Cuando ignoré RFC 1950 y solo RFC 1951, pasó.

Supongo, entonces, que IE8 no está siguiendo correctamente RFC 2616 página 17, y todos los otros navegadores son lo suficientemente agradables para aceptar cualquier formato.

+0

Acabo de encontrar un proxy de caché web de un cliente que se está forzando a desinflar, y ¿adivinen qué implementación han elegido? El equivocado, probablemente para soportar IE8. Desafortunadamente, nuestro cliente de Java, que utiliza bibliotecas HTTP estándar, espera la implementación correcta de desinflado. Tendré que desactivar el soporte desinflado en nuestro cliente y forzarlos a usar gzip o nada. –

Cuestiones relacionadas