2010-03-10 4 views
27

Ich versuche, die Vor- und Nachteile der HTTP-Header Content-Length gegen die Verwendung von Chunked-Codierung, um [möglicherweise] große Dateien von meinem Server zurückgeben. Der eine oder der andere muss den HTTP 1.1-Spezifikationen entsprechen, die persistente Verbindungen verwenden. Ich sehe den Vorteil des Content-Length Kopf Wesen:Content-Length-Header im Vergleich zu Chunked-Codierung

  • Download-Dialoge genaue Fortschrittsbalken zeigen
  • Kunde im Voraus weiß, ob die Datei möglicherweise/nicht zu groß sein kann für sie

Die aufnehmen Nachteil ist, dass Sie die Größe berechnen müssen, bevor Sie das Objekt zurückgeben, was nicht immer praktisch ist und die Server-/Datenbanknutzung verbessern könnte. Der Nachteil der Chunked-Codierung ist der kleine Overhead beim Hinzufügen der Chunk-Größe vor jedem Chunk und der Download-Fortschrittsleiste. Irgendwelche Gedanken? Irgendwelche anderen HTTP-Betrachtungen für beide Methoden, an die ich nicht gedacht habe?

+1

Ist es selbstverständlich, dass Ihr Inhalt ist statisch und seine Länge a priori bekannt ist? Wenn nicht, wäre Chunked viel schneller für große Dateien. –

Antwort

27

Verwenden Sie Content-Length, definitiv. Die Server-Nutzung von dieser wird fast nicht vorhanden sein und der Nutzen für Ihre Benutzer wird groß sein.

Für dynamischen Inhalt ist es auch ganz einfach, komprimierte Antwortunterstützung hinzuzufügen (gzip). Das erfordert eine Ausgabepufferung, die wiederum die Länge des Inhalts angibt. (Nicht praktisch bei Dateidownloads oder bereits komprimiertem Inhalt (Ton, Bilder)).

Erwägen Sie auch das Hinzufügen von Unterstützung für partiellen Inhalt/Byte-Bereich dient - dh, die Fähigkeit, Downloads neu zu starten. See here for a byte-range example (das Beispiel ist in PHP, ist aber in jeder Sprache anwendbar). Sie benötigen Content-Length, wenn Sie teilweise Inhalte bereitstellen.

Natürlich sind solche, die nicht silberne Kugeln: für Streaming-Medien, es sinnlos ist Ausgabepufferung oder Antwortgröße zu verwenden; Für große Dateien ist die Pufferung von Ausgaben nicht sinnvoll, aber Content-Length und Byte-Serving sind sehr sinnvoll (ein fehlgeschlagener Download ist möglich).

Persönlich serviere ich Content-Length, wann immer ich es weiß; Beim Dateidownload ist die Überprüfung der Dateigröße in Bezug auf Ressourcen unbedeutend. Ergebnis: Der Benutzer hat einen bestimmten Fortschrittsbalken (und dynamische Seiten können dank gzip schneller heruntergeladen werden).

+1

Ich sehe nicht, wie Byte-Range-Serving (im Grunde: "Fortsetzen Downloads") in diesem speziellen Fall vorteilhaft ist. Dies erfordert nämlich, dass die Inhaltslänge vorher bekannt ist. Sie können dann genauso gut die Inhaltslänge einstellen. – BalusC

+0

@BalusC: Content-Length ist eine ** Voraussetzung ** für das Byte-Serving. Typischer Anwendungsfall: Benutzer lädt eine 10MB-Datei über ihre WiFi-Verbindung herunter, das Signal fällt 7MB in den Download. Ohne Lebenslauf muss sie die ganzen 10 MB wieder herunterladen, was für sie ziemlich nervig ist; Mit Lebenslauf sind nur noch 3 MB übrig. Die meisten modernen Browser unterstützen dies. – Piskvor

+0

Ja, ich weiß. Vielleicht hast du mich nicht verstanden? Ich sage nur, dass ich nicht sehe, wie das mit der "Inhaltslänge" vs. zusammenhängt. "Transfer-Encoding: Chunked" -Frage. Übrigens sagt mir die Post-Historie des OP, dass seine Hauptsprache Java ist. In diesem Fall könnte dieses 'FileServlet'-Beispiel nützlicher sein: http://balusc.blogspot.com/2009/02/fileservlet-support-resume- and.html – BalusC

10

Wenn die Länge des Inhalts im Voraus bekannt ist, würde ich es sicherlich vor dem Senden in Stücke bevorzugen. Wenn statische Datendateien auf dem lokalen Dateisystem oder in einer Datenbank vorhanden sind, bietet jede selbst respektierte Programmiersprache und RDBMS Möglichkeiten, die Länge des Inhalts vorher zu ermitteln. Du solltest es benutzen.

Wenn die Länge des Inhalts jedoch vorher unvorhersehbar ist (zB wenn mehrere Dateien zusammen gepackt und als eins gesendet werden sollen), ist das Senden in Blöcken möglicherweise schneller als das Puffern im Serverspeicher oder zuerst auf lokales Dateisystem schreiben. Dies wirkt sich jedoch negativ auf die Benutzerfreundlichkeit aus, da der Download-Fortschritt unbekannt ist. Der Ungeduldige kann dann den Download abbrechen und sich fortbewegen.

Ein weiterer Vorteil zu wissen, die Länge des Inhalts ist vorher die Möglichkeit, Downloads wieder aufnehmen. Ich sehe in Ihrer Postgeschichte, dass Ihre Hauptprogrammiersprache Java ist; Sie finden here einen Artikel mit mehr technischen Hintergrundinformationen und ein Java-Servlet-Beispiel, das das tut.

0

Content-Length

Der Content-Length Header bestimmt die Byte-Länge des Request/Response-Körper. Wenn Sie den Header Content-Length nicht angeben, fügen HTTP-Server implizit einen Header Transfer-Encoding: chunked hinzu. Die Header Content-Length und Transfer-Encoding sollten nicht zusammen verwendet werden. Der Empfänger wird keine Ahnung haben, wie lang der Körper ist und kann die Download-Zeit nicht abschätzen. Wenn Sie einen Header Content-Length hinzufügen, stellen Sie sicher, dass es den gesamten Körper in Bytes entspricht, wenn es falsch ist, ist das Verhalten von Empfängern nicht definiert.

Der Header Content-Length erlaubt kein Streaming, ist aber für große Binärdateien nützlich, in denen Sie die teilweise Bereitstellung von Inhalten unterstützen möchten. Dies bedeutet im Wesentlichen wiederaufnehmbare Downloads, pausierte Downloads, partielle Downloads und multi-homed Downloads. Dies erfordert die Verwendung eines zusätzlichen Headers mit der Bezeichnung Range. Diese Technik wird Byte serving genannt.

Transfer-Encoding

Die Verwendung von Transfer-Encoding: chunked ist, was in einer einzigen Anfrage oder Antwort ermöglicht Streaming. Dies bedeutet, dass die Daten chunked übertragen werden und keinen Einfluss auf die Darstellung des Inhalts haben.

Offiziell soll ein HTTP-Client eine Anfrage mit einem Header-Feld TE senden, das angibt, welche Arten von Transfercodierungen der Client zu akzeptieren bereit ist. Dies wird nicht immer gesendet, jedoch gehen die meisten Server davon aus, dass Clients chunked Kodierungen verarbeiten können.

Die chunked Übertragungscodierung verwendet besser persistente TCP-Verbindungen, von denen HTTP 1.1 standardmäßig als true angenommen wird.

Content-Encoding

Es ist auch möglich, Chunked oder nicht Chunked Daten zu komprimieren. Dies geschieht praktisch über den Header .

Beachten Sie, dass die Content-Length gleich der Länge des Körpers nach der ist. Das heißt, wenn Sie Ihre Antwort gezippt haben, erfolgt die Längenberechnung nach der Komprimierung. Sie müssen in der Lage sein, den gesamten Körper in den Speicher zu laden, wenn Sie die Länge berechnen möchten (es sei denn, Sie haben diese Informationen an anderer Stelle).

Beim Streaming mit Chunked-Encoding muss der Komprimierungsalgorithmus auch die Online-Verarbeitung unterstützen. Glücklicherweise unterstützt gzip die Stream-Komprimierung. Ich glaube, dass der Inhalt zuerst komprimiert und dann in Stücke geschnitten wird. Auf diese Weise werden die Chunks empfangen und dann dekomprimiert, um den echten Inhalt zu erhalten. Wenn es umgekehrt wäre, würden Sie den komprimierten Stream bekommen, und dann würde uns das Dekomprimieren in Stücke verwandeln. Was keinen Sinn ergibt.

Eine typische komprimierte Strom Antwort kann diesen Header hat:

Content-Type: text/html 
Content-Encoding: gzip 
Transfer-Encoding: chunked 

semantisch Verwendung von Content-Encoding zeigt einen Codierschema „Ende an Ende“, das die dekodieren nur den letzten Client oder endgültige Servermittel sollte Inhalt. Proxies in der Mitte sollen den Inhalt nicht dekodieren.

Wenn Sie Proxies in der Mitte zulassen möchten, um den Inhalt zu dekodieren, ist der korrekte Header tatsächlich der Transfer-Encoding Header. Wenn die HTTP-Anfrage einen TE: gzip chunked Header besitzt, ist es zulässig, mit Transfer-Encoding: gzip chunked zu antworten.

Dies wird jedoch sehr selten unterstützt. Sie sollten also nur für Ihre Komprimierung verwenden.

Chunked vs Store & Forward

Verwandte Themen