Pytanie w sprawie compression, cgi, internet-explorer-8, c++, apache – Internet Explorer 8 + Deflate

5

Mam bardzo dziwny problem ... Naprawdę mam nadzieję, że ktoś ma odpowiedź, ponieważ nie wiedziałbym, gdzie jeszcze zapytać.

Piszę aplikację cgi w C ++, która jest wykonywana przez Apache i wyświetla kod HTML. Sam kompresuję wyjście HTML - z poziomu mojej aplikacji C ++ - ponieważ mój host WWW z jakiegoś powodu nie obsługuje mod_deflate.

Przetestowałem to z Firefox 2, Firefox 3, Opera 9, Opera 10, Google Chrome, Safari, IE6, IE7, IE8, a nawet wget .. Działa zBYLE CO z wyjątkiem IE8.

IE8 mówi po prostu: „Internet Explorer nie może wyświetlić strony internetowej”, bez żadnych informacji. Wiem, że to tylko z powodu kompresji, ponieważ działa, gdy ją wyłączę.

Czy wiesz, co robię źle?

Używam zlib do kompresji, a dokładny kod to:

    /* 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;
}
Upewnij się także, że przeczytałeś to pytanie SOstackoverflow.com/questions/388595/…. Lepiej trzymać się gzipa. Eye
ok, to dziwne. Jeśli wysyłam „gzip” jako kodowanie treści, działa na IE8, ale na dowolnej innej przeglądarce.: Błąd kodowania treści Strona, którą próbujesz wyświetlić, nie może zostać wyświetlona, ​​ponieważ używa nieprawidłowej lub nieobsługiwanej formy kompresji. Thomas Bonini
Jakieś wskazówki w nagłówku IE8 Accept-Encoding? John Kugelman
cout << boost :: format ("Content-Encoding:% s r n")% ((UserAgent.GetBrowser () == INTERNET_EXPLORER && UserAgent.GetVersion ()> = 8)? "gzip": "deflate" ); // Cóż, to naprawia to. Wciąż szukam prawdziwej odpowiedzi, jeśli ktoś może coś wymyślić. Thomas Bonini

Twoja odpowiedź

2   odpowiedź
5

co odkryłem na ten temat, ponieważ napisałem własny algorytm deflacji, mój własny serwer HTTP, i ku mojemu przerażeniu IE8 również nie rozpoznał mojej deflowanej treści:

HTTP RFC tohttp://www.faqs.org/ftp/rfc/rfc2616.pdf. Strona 17 oznacza, że ​​zarówno RFC 1950, jak i RFC 1951 są używane podczas przeprowadzania deflacji w nagłówkach HTTP. RFC 1950 po prostu definiuje nagłówek i bajty zwiastunów; algorytm deflate jest zdefiniowany w RFC 1951. Kiedy zaprogramowałem to do specyfikacji, IE8 nie powiodło się.

Kiedy zignorowałem RFC 1950 i zrobiłem tylko RFC 1951, minęło.

Zakładałbym zatem, że IE8 nie działa poprawnie na stronie 17 RFC 2616, a wszystkie inne przeglądarki są wystarczająco miłe, aby zaakceptować dowolny format.

Właśnie natknąłem się na proxy buforowania stron internetowych klienta, które wymusza deflację i zgadnij, którą implementację wybrali? Zły, prawdopodobnie do obsługi IE8. Niestety, nasz klient Java, używający standardowych bibliotek HTTP, oczekuje poprawnej implementacji deflatu. Będę musiał wyłączyć obsługę deflate u naszego klienta i zmusić ich do używania gzip lub niczego. Marcus Adams
5

ale istnieją pewne subtelne różnice w nagłówku, więc jeśli zmienisz kodowanie treści, powinieneś także zmienić parametry na metodę kodowania (w szczególności , rozmiar okna)!

Widzieć:http://apcmag.com/improve_your_site_with_http_compression.htm

Prawdopodobnie inne przeglądarki ignorują specyfikację kodowania treści i wykonują automatyczne rozpoznawanie, ale IE8 nie jest ...

Widzieć:http://www.zlib.net/manual.html#deflateInit2

Spróbuj użyć:

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

I użyj „gzip” jako kodowania treści

wow, dzięki! Kocham cię: D Mała korekta. Istnieją 3 (!) Formaty kompresji: zlib - ten, którego używałem, który uważałem za „deflate” -, deflate i gzip. Jakby nie było wystarczająco mylące, wszystkie 3 z nich są najwyraźniej tworzone przy użyciu biblioteki zlib. Nie określając bitów okien (jak robiłem) wypisuje format zlib, używając wartości ujemnej (tak jak zasugerowałeś) wyprowadzaDEFLATED format (nie gzip!). Nie jestem jeszcze pewien, jak wypisać format gzip (i mnie to nie obchodzi, teraz działa z opróżnieniem we wszystkich przeglądarkach). DZIĘKI JESZCZE RAZ!! :) Thomas Bonini
+1, fajne znalezisko! Masz ochotę na błąd w mod_gzip. j_random_hacker

Powiązane pytania