it-swarm.com.de

Transfer-Encoding: gzip vs. Content-Encoding: gzip

Was ist der aktuelle Stand der Dinge, wenn es darum geht, ob zu tun

Transfer-Encoding: gzip

oder ein

Content-Encoding: gzip

wenn ich Clients mit z. Begrenzte Bandbreite, um ihre Bereitschaft zu signalisieren, eine komprimierte Antwort zu akzeptieren und der Server hat das letzte Wort, ob er komprimieren möchte oder nicht .

Letzteres ist, was z.B. Apache's mod_deflate und IIS tun, wenn Sie es für die Komprimierung sorgen lassen. Abhängig von der Größe des zu komprimierenden Inhalts wird zusätzlich Transfer-Encoding: chunked Ausgeführt.

Es wird auch einen Vary: Accept-Encoding Enthalten, der bereits auf das Problem hinweist. Content-Encoding Scheint Teil der Entität zu sein, so dass das Ändern des Betrags Content-Encoding Zu einer Änderung der Entität führt, d. H. Ein anderer Accept-Encoding - Header bedeutet z. Ein Cache kann seine zwischengespeicherte Version der ansonsten identischen Entität nicht verwenden.

Gibt es eine eindeutige Antwort darauf, die ich verpasst habe (und die nicht in einer Nachricht in einem langen Thread in einer Apache-Newsgroup vergraben ist)?

Mein aktueller Eindruck ist:

  • Transfer-Encoding wäre in der Tat der richtige Weg, um das zu tun, was meistens mit Content-Encoding durch vorhandene Server- und Client-Implementierungen gemacht wird
  • Die Inhaltskodierung birgt aufgrund ihrer semantischen Implikationen einige Probleme (Was sollte der Server mit dem ETag tun, wenn er eine Antwort transparent komprimiert?)
  • Der Grund ist chicken'n'Egg: Browser unterstützen es nicht, weil Server es nicht tun, weil Browser es nicht tun

Ich gehe also davon aus, dass der richtige Weg ein Transfer-Encoding: gzip Wäre (oder, wenn ich den Körper zusätzlich zerlege, es würde werdenTransfer-Encoding: gzip, chunked). Und kein Grund, Vary oder ETag oder einen anderen Header in diesem Fall zu berühren, da es sich um eine Sache auf Transportebene handelt.

Im Moment ist mir die 'Hop-by-Hop'-Fähigkeit von Transfer-Encoding Nicht so wichtig, was andere anscheinend zuallererst zu befürchten scheinen, da Proxys möglicherweise dekomprimiert und unkomprimiert an den Client weitergeleitet werden . Proxies können es jedoch genauso gut weiterleiten wie es ist (komprimiert), wenn die ursprüngliche Anforderung den richtigen Accept-Encoding - Header hat, der für alle mir bekannten Browser eine Selbstverständlichkeit ist.

Übrigens ist dieses Problem mindestens ein Jahrzehnt alt, siehe z. https://bugzilla.mozilla.org/show_bug.cgi?id=68517 .

Jede Klarstellung hierzu wird gebeten. Sowohl in Bezug auf das, was als normenkonform angesehen wird, als auch auf das, was als praktisch angesehen wird. Beispielsweise wären HTTP-Client-Bibliotheken, die nur transparentes "Content-Encoding" unterstützen, ein Argument gegen die Praktikabilität.

88

Zitat Roy T. Fielding , einer der Autoren von RFC 2616:

eine inkonsistente Änderung der Inhaltskodierung im laufenden Betrieb (weder "nie" noch "immer") macht es unmöglich, dass spätere Anforderungen in Bezug auf diesen Inhalt (z. B. PUT oder bedingtes GET) korrekt behandelt werden. Dies ist natürlich der Grund für die Ausführung Die spontane Codierung von Inhalten ist eine blöde Idee, und deshalb habe ich "Transfer-Encoding" zu HTTP hinzugefügt, um die Codierung im laufenden Betrieb ohne Änderung der Ressource zu ermöglichen.

Quelle: https://issues.Apache.org/bugzilla/show_bug.cgi?id=39727#c31

Mit anderen Worten: Machen Sie nicht on-the-fly Content-Encoding, sondern verwenden Sie stattdessen Transfer-Encoding!

Bearbeiten: Das heißt, es sei denn, Sie möchten gzippte Inhalte nur Clients bereitstellen, die die Inhaltscodierung verstehen . Welches scheint leider die meisten von ihnen zu sein. Beachten Sie jedoch, dass Sie den Bereich der Spezifikation verlassen und möglicherweise auf Probleme stoßen, wie das von Fielding erwähnte und andere, z. wenn Caching-Proxys beteiligt sind.

33

Die korrekte -Verwendung, wie in RFC 2616 definiert und tatsächlich in freier Wildbahn implementiert, dient dazu, dass der Client einen Accept-Encoding -Anforderungsheader sendet (der Client kann mehrere Codierungen angeben). Der Server kann dann und nur dann die Antwort gemäß den vom Client unterstützten Codierungen codieren (falls die Dateidaten nicht bereits in dieser Codierung gespeichert sind) und im Antwortheader Content-Encoding angeben, welche Codierung verwendet wird. Der Client kann dann Daten basierend auf dem Transfer-Encoding (dh chunked) vom Socket lesen und sie anschließend basierend auf dem Content-Encoding (dh gzip) dekodieren. .

In Ihrem Fall würde der Client also einen Anforderungsheader Accept-Encoding: gzip senden, und der Server könnte dann beschließen, (falls nicht bereits geschehen) einen Antwortheader Content-Encoding: gzip und optional Transfer-Encoding: chunked zu komprimieren.

Und ja, der Transfer-Encoding -Header kann in Anforderungen verwendet werden, jedoch nur für HTTP 1.1, was erfordert, dass sowohl Client- als auch Serverimplementierungen die chunked -Codierung in beide Richtungen unterstützen.

ETag identifiziert die Ressourcendaten auf dem Server eindeutig, nicht die tatsächlich übertragenen Daten. Wenn eine bestimmte URL-Ressource ihren Wert ETag ändert, bedeutet dies, dass sich die serverseitigen Daten für diese Ressource geändert haben.

26
Remy Lebeau