Frage an c++, compression, internet-explorer-8, apache, cgi – Internet Explorer 8 + Deflate

5

Ich habe ein sehr seltsames Problem. Ich hoffe wirklich, dass jemand eine Antwort hat, weil ich nicht wüsste, wo ich sonst fragen soll.

Ich schreibe eine CGI-Anwendung in C ++, die von Apache ausgeführt wird und HTML-Code ausgibt. Ich komprimiere die HTML-Ausgabe selbst - aus meiner C ++ - Anwendung heraus - da mein Webhost mod_deflate aus irgendeinem Grund nicht unterstützt.

Ich habe dies mit Firefox 2, Firefox 3, Opera 9, Opera 10, Google Chrome, Safari, IE6, IE7, IE8 getestet. Es funktioniert mitETWAS außer IE8.

IE8 sagt nur "Internet Explorer kann die Webseite nicht anzeigen", ohne jegliche Information. Ich weiß, es liegt an der Komprimierung, nur weil es funktioniert, wenn ich es deaktiviere.

Weißt du was ich falsch mache?

Ich benutze Zlib, um es zu komprimieren, und der genaue Code ist:

    /* 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;
}
Es sendet sowohl deflate als auch gzip als Accept-Encoding. Ich überprüfe, ob es "deflate" enthält, bevor ich eine deflated Ausgabe sende. Thomas Bonini
Stellen Sie außerdem sicher, dass Sie diese SO-Frage gelesen habenstackoverflow.com/questions/388595/…. Bleib lieber bei gzip. Eye
Nach weiteren Versuchen. Wenn ich die Inhaltskodierung als gzip sende (es ist nicht! Es ist deflate), funktioniert es im Internet Explorer nur in einer beliebigen Version, einschließlich ie8, während es in keinem anderen Browser funktioniert. Wenn ich deflate sende, das richtige, funktioniert es auf jedem Browser, einschließlich ie6 und ie7, aber nicht auf ie8 <. < Thomas Bonini
cout << boost :: format ("Inhaltskodierung:% s \ r \ n")% ((UserAgent.GetBrowser () == INTERNET_EXPLORER && UserAgent.GetVersion ()> = 8)? "gzip": "deflate" ); // Nun, das behebt es. Immer noch auf der Suche nach einer richtigen Antwort, falls jemand eine finden kann. Thomas Bonini

Deine Antwort

2   die antwort
5

Ich wollte klären, was ich dabei herausgefunden habe, da ich meinen eigenen Deflate-Algorithmus, meinen eigenen HTTP-Server und zu meinem Entsetzen auch den IE8 geschrieben habe, der meinen deflierten Inhalt nicht erkannt hat:

HTTP RFC isthttp://www.faqs.org/ftp/rfc/rfc2616.pdf. Page 17 besagt, dass sowohl RFC 1950 als auch RFC 1951 verwendet werden, wenn eine Deflation in den HTTP-Headern durchgeführt wird. RFC 1950 definiert einfach die Header- und Trailer-Bytes. Der Deflate-Algorithmus ist in RFC 1951 definiert. Als ich dies auf die Spezifikation programmierte, schlug IE8 fehl.

Als ich RFC 1950 ignorierte und nur RFC 1951 tat, ging es vorbei.

Ich würde dann annehmen, dass IE8 RFC 2616 Seite 17 nicht korrekt folgt, und alle anderen Browser sind nett genug, um beide Formate zu akzeptieren.

Ich bin gerade auf den Web-Caching-Proxy eines Kunden gestoßen, der eine Deflation erzwingt, und rate, welche Implementierung er gewählt hat. Die falsche, wahrscheinlich um IE8 zu unterstützen. Leider erwartet unser Java-Client, der Standard-HTTP-Bibliotheken verwendet, die korrekte Implementierung der Deflation. Ich muss den Deflate-Support in unserem Client deaktivieren und ihn zwingen, gzip oder nichts zu verwenden. Marcus Adams
5

Die Methoden gzip und deflate sind nicht identisch ... sie sind sehr ähnlich, es gibt jedoch einige geringfügige Unterschiede in der Kopfzeile. Wenn Sie also Ihre Inhaltskodierung ändern, sollten Sie auch Ihre Parameter in die Kodierungsmethode ändern (insbesondere , die Fenstergröße)!

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

Wahrscheinlich ignorieren die anderen Browser Ihre Inhaltscodierungsspezifikation und führen eine automatische Erkennung durch, aber IE8 ist nicht ...

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

Versuchen zu benutzen:

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

Und benutze "gzip" als Inhaltskodierung

Wow, danke! Ich liebe dich: D Eine kleine Korrektur. Es gibt 3 (!) Komprimierungsformate: zlib - das von mir verwendete, von dem ich dachte, es sei "deflate" -, deflate und gzip. Als ob es nicht verwirrend genug wäre, werden anscheinend alle drei mit der Bibliothek zlib erstellt. Wenn Sie die windowBits nicht angeben (wie ich es getan habe), wird das zlib-Format ausgegeben, wobei ein negativer Wert (wie von Ihnen vorgeschlagen) verwendet wirdDEFLATED Format (nicht gzip!). Ich bin mir noch nicht sicher, wie ich das gzip-Format ausgeben soll (und es ist mir egal, jetzt funktioniert es mit deflate in allen Browsern). DANKE NOCH EINMAL!! :) Thomas Bonini
+1, nette Entdeckung! Stellen Sie sich das vor, ein Fehler in mod_gzip. j_random_hacker

Verwandte Fragen