Zum Hauptinhalt springen

3. Nachrichtenformat

Alle HTTP/1.1-Nachrichten bestehen aus einer Startzeile, gefolgt von einer Oktettsequenz in einem Format, das dem Internet Message Format [RFC5322] ähnelt: null oder mehr Header-Felder (zusammenfassend als die "Header" oder der "Header-Abschnitt" bezeichnet), eine Leerzeile, die das Ende des Header-Abschnitts anzeigt, und ein optionaler Nachrichtenkörper.

HTTP-message   = start-line
*( header-field CRLF )
CRLF
[ message-body ]

Das normale Verfahren zum Parsen einer HTTP-Nachricht besteht darin, die Startzeile in eine Struktur einzulesen, jedes Header-Feld nach Feldname bis zur Leerzeile in eine Hashtabelle einzulesen und anschließend anhand der geparsten Daten zu bestimmen, ob ein Nachrichtenkörper erwartet wird. Wurde ein Nachrichtenkörper angezeigt, wird er als Stream gelesen, bis eine Anzahl von Oktetten gleich der Nachrichtenkörperlänge gelesen wurde oder die Verbindung geschlossen wird.

Ein Empfänger muss eine HTTP-Nachricht als Oktettsequenz in einer Kodierung parsen, die eine Obermenge von US-ASCII [USASCII] ist. Das Parsen einer HTTP-Nachricht als Stream von Unicode-Zeichen ohne Rücksicht auf die spezifische Kodierung erzeugt Sicherheitslücken, weil String-Verarbeitungsbibliotheken ungültige Mehrbyte-Zeichensequenzen, die das Oktett LF (%x0A) enthalten, unterschiedlich behandeln. String-basierte Parser können innerhalb von Protokollelementen erst dann sicher verwendet werden, nachdem das Element aus der Nachricht extrahiert wurde, etwa innerhalb eines Header-Feldwerts, nachdem das Parsen der Nachricht die einzelnen Felder abgegrenzt hat.

Eine HTTP-Nachricht kann als Stream für inkrementelle Verarbeitung oder Weiterleitung stromabwärts geparst werden. Empfänger können sich jedoch nicht auf die inkrementelle Auslieferung von Teilmeldungen verlassen, da einige Implementierungen die Nachrichtenweiterleitung zugunsten von Netzwerkeffizienz, Sicherheitsprüfungen oder Payload-Transformationen puffern oder verzögern.

Ein Absender darf KEIN Whitespace zwischen der Startzeile und dem ersten Header-Feld senden. Ein Empfänger, der Whitespace zwischen der Startzeile und dem ersten Header-Feld empfängt, muss entweder die Nachricht als ungültig zurückweisen oder jede durch Whitespace eingeleitete Zeile konsumieren, ohne sie weiter zu verarbeiten (d. h. die gesamte Zeile zusammen mit allen nachfolgenden, durch Whitespace eingeleiteten Zeilen ignorieren, bis ein korrekt gebildetes Header-Feld empfangen wird oder der Header-Abschnitt beendet ist).

Das Vorhandensein solchen Whitespace in einer Anfrage kann der Versuch sein, einen Server dazu zu bringen, dieses Feld zu ignorieren oder die darauffolgende Zeile als neue Anfrage zu verarbeiten, was beides zu einer Sicherheitslücke führen kann, wenn andere Implementierungen innerhalb der Anfragekette dieselbe Nachricht anders interpretieren. Ebenso kann das Vorhandensein solchen Whitespace in einer Antwort von einigen Clients ignoriert werden oder andere dazu bringen, das Parsen einzustellen.

3.1. Startzeile​

Eine HTTP-Nachricht kann entweder eine Anfrage von Client an Server oder eine Antwort von Server an Client sein. Syntaktisch unterscheiden sich die beiden Nachrichtentypen nur in der Startzeile, die entweder eine Anfragezeile (request-line, für Anfragen) oder eine Statuszeile (status-line, für Antworten) ist, und im Algorithmus zur Bestimmung der Länge des Nachrichtenkörpers (Abschnitt 3.3).

Theoretisch könnte ein Client Anfragen empfangen und ein Server Antworten, wobei sie durch ihre unterschiedlichen Startzeilenformate unterschieden werden; in der Praxis sind Server jedoch so implementiert, dass sie nur eine Anfrage erwarten (eine Antwort wird als unbekannte oder ungültige Anforderungsmethode interpretiert), und Clients sind so implementiert, dass sie nur eine Antwort erwarten.

start-line     = request-line / status-line

3.1.1. Anfragezeile​

Eine Anfragezeile beginnt mit einem Methoden-Token, gefolgt von einem einzelnen Leerzeichen (SP), dem Anfrageziel (request-target), einem weiteren einzelnen Leerzeichen (SP), der Protokollversion, und endet mit CRLF.

request-line   = method SP request-target SP HTTP-version CRLF

Das Methoden-Token zeigt die Anforderungsmethode an, die auf die Zielressource angewendet werden soll. Die Anforderungsmethode ist case-sensitiv.

method         = token

Die von dieser Spezifikation definierten Anforderungsmethoden finden sich in Abschnitt 4 von [RFC7231], zusammen mit Informationen zum HTTP-Methodenregister und Überlegungen zur Definition neuer Methoden.

Das Anfrageziel identifiziert die Zielressource, auf die die Anfrage angewendet werden soll, wie in Abschnitt 5.3 definiert.

Empfänger parsen die Anfragezeile üblicherweise in ihre Bestandteile, indem sie an Whitespace aufteilen (siehe Abschnitt 3.5), da in den drei Komponenten kein Whitespace erlaubt ist. Leider schaffen es einige User Agents nicht, in Hypertext-Referenzen gefundenen Whitespace ordnungsgemäß zu kodieren oder auszuschließen, sodass diese unzulässigen Zeichen in einem Anfrageziel gesendet werden.

Empfänger einer ungültigen Anfragezeile SOLLTEN entweder mit einem Fehler 400 (Bad Request) oder mit einer Weiterleitung 301 (Moved Permanently) antworten, wobei das Anfrageziel ordnungsgemäß kodiert ist. Ein Empfänger SOLLTE NICHT versuchen, die Anfrage automatisch zu korrigieren und dann ohne Weiterleitung zu verarbeiten, da die ungültige Anfragezeile absichtlich so gestaltet sein könnte, dass sie Sicherheitsfilter entlang der Anfragekette umgeht.

HTTP setzt, wie in Abschnitt 2.5 beschrieben, keine vordefinierte Grenze für die Länge einer Anfragezeile. Ein Server, der eine Methode empfängt, die länger ist als jede, die er implementiert, SOLLTE mit dem Statuscode 501 (Not Implemented) antworten. Ein Server, der ein Anfrageziel empfängt, das länger ist als jeder URI, den er parsen möchte, MUSS mit dem Statuscode 414 (URI Too Long) antworten (siehe Abschnitt 6.5.12 von [RFC7231]).

In der Praxis gibt es verschiedene Ad-hoc-Beschränkungen der Anfragezeilenlänge. Es wird EMPFOHLEN, dass alle HTTP-Absender und -Empfänger mindestens Anfragezeilenlängen von 8000 Oktetten unterstützen.

3.1.2. Statuszeile​

Die erste Zeile einer Antwortnachricht ist die Statuszeile; sie besteht aus der Protokollversion, einem Leerzeichen (SP), dem Statuscode, einem weiteren Leerzeichen, einer möglicherweise leeren Textphrase, die den Statuscode beschreibt, und endet mit CRLF.

status-line = HTTP-version SP status-code SP reason-phrase CRLF

Das Element status-code ist ein dreistelliger ganzzahliger Code, der das Ergebnis des Versuchs des Servers beschreibt, die entsprechende Anfrage des Clients zu verstehen und zu erfüllen. Der Rest der Antwortnachricht ist im Lichte der für diesen Statuscode definierten Semantik zu interpretieren. Informationen zur Semantik von Statuscodes, einschließlich der Statuscode-Klassen (angezeigt durch die erste Ziffer), der von dieser Spezifikation definierten Statuscodes, Überlegungen zur Definition neuer Statuscodes und des IANA-Registers, finden Sie in Abschnitt 6 von [RFC7231].

status-code    = 3DIGIT

Das Element reason-phrase existiert einzig zu dem Zweck, eine textuelle Beschreibung bereitzustellen, die dem numerischen Statuscode zugeordnet ist, vor allem aus Rücksicht auf frühere Internet-Anwendungsprotokolle, die häufiger mit interaktiven Textclients verwendet wurden. Ein Client SOLLTE den Inhalt der reason-phrase ignorieren.

reason-phrase  = *( HTAB / SP / VCHAR / obs-text )

3.2. Header-Felder​

Jedes Header-Feld besteht aus einem case-insensitiven Feldnamen, gefolgt von einem Doppelpunkt (":"), optionalem führendem Whitespace, dem Feldwert und optionalem nachfolgendem Whitespace.

header-field   = field-name ":" OWS field-value OWS

field-name = token
field-value = *( field-content / obs-fold )
field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
field-vchar = VCHAR / obs-text

obs-fold = CRLF 1*( SP / HTAB )
; obsolete line folding
; see Section 3.2.4

Das Token field-name kennzeichnet den entsprechenden field-value als die durch dieses Header-Feld definierte Semantik besitzend. Beispielsweise ist das Header-Feld Date in Abschnitt 7.1.1.2 von [RFC7231] so definiert, dass es den Erzeugungszeitstempel für die Nachricht enthält, in der es erscheint.

3.2.1. Felderweiterbarkeit​

Header-Felder sind vollständig erweiterbar: Es gibt keine Begrenzung für die Einführung neuer Feldnamen, von denen jeder vermutlich neue Semantik definiert, noch für die Anzahl der in einer bestimmten Nachricht verwendeten Header-Felder. Bestehende Felder sind in jedem Teil dieser Spezifikation und in vielen anderen Spezifikationen außerhalb dieses Dokumentensatzes definiert.

Neue Header-Felder können so definiert werden, dass sie, wenn sie von einem Empfänger verstanden werden, die Interpretation zuvor definierter Header-Felder überschreiben oder erweitern, Vorbedingungen für die Auswertung von Anfragen definieren oder die Bedeutung von Antworten verfeinern können.

Ein Proxy MUSS nicht erkannte Header-Felder weiterleiten, es sei denn, der Feldname ist im Header-Feld Connection aufgeführt (Abschnitt 6.1) oder der Proxy ist speziell darauf konfiguriert, solche Felder zu blockieren oder anderweitig zu transformieren. Andere Empfänger SOLLTEN nicht erkannte Header-Felder ignorieren. Diese Anforderungen erlauben es, die Funktionalität von HTTP zu erweitern, ohne eine vorherige Aktualisierung der eingesetzten Vermittler zu erfordern.

Alle definierten Header-Felder sollten bei IANA im Register "Message Headers" registriert werden, wie in Abschnitt 8.3 von [RFC7231] beschrieben.

3.2.2. Feldreihenfolge​

Die Reihenfolge, in der Header-Felder mit unterschiedlichen Feldnamen empfangen werden, ist nicht signifikant. Es ist jedoch gute Praxis, Header-Felder, die Steuerdaten enthalten, zuerst zu senden, etwa Host bei Anfragen und Date bei Antworten, damit Implementierungen so früh wie möglich entscheiden können, wann sie eine Nachricht nicht verarbeiten. Ein Server darf eine Anfrage erst dann auf die Zielressource anwenden, wenn der gesamte Anforderungs-Header-Abschnitt empfangen wurde, da spätere Header-Felder Bedingungen, Authentifizierungsnachweise oder absichtlich irreführende doppelte Header-Felder enthalten könnten, die die Verarbeitung der Anfrage beeinflussen würden.

Ein Absender darf KEINE mehreren Header-Felder mit demselben Feldnamen in einer Nachricht erzeugen, es sei denn, entweder der gesamte Feldwert für dieses Header-Feld ist als durch Kommas getrennte Liste definiert [d. h. #(values)] oder das Header-Feld ist eine wohlbekannte Ausnahme (wie unten erwähnt).

Ein Empfänger KANN mehrere Header-Felder mit demselben Feldnamen zu einem einzigen Paar "field-name: field-value" zusammenfassen, ohne die Semantik der Nachricht zu ändern, indem er jeden nachfolgenden Feldwert in der Reihenfolge an den zusammengefassten Feldwert anhängt, getrennt durch ein Komma. Die Reihenfolge, in der Header-Felder mit demselben Feldnamen empfangen werden, ist daher für die Interpretation des zusammengefassten Feldwerts signifikant; ein Proxy darf die Reihenfolge dieser Feldwerte beim Weiterleiten einer Nachricht NICHT ändern.

Hinweis: In der Praxis erscheint das Header-Feld "Set-Cookie" ([RFC6265]) häufig mehrfach in einer Antwortnachricht und verwendet nicht die Listensyntax, was die obigen Anforderungen an mehrere Header-Felder mit demselben Namen verletzt. Da es nicht zu einem einzigen Feldwert zusammengefasst werden kann, sollten Empfänger "Set-Cookie" bei der Verarbeitung von Header-Feldern als Sonderfall behandeln. (Siehe Anhang A.2.3 von [Kri2001] für Details.)

3.2.3. Whitespace​

Diese Spezifikation verwendet drei Regeln, um die Verwendung von linearem Whitespace zu bezeichnen: OWS (optionaler Whitespace), RWS (erforderlicher Whitespace) und BWS ("schlechter" Whitespace).

Die Regel OWS wird verwendet, wo null oder mehr Oktette linearen Whitespace erscheinen können. Für Protokollelemente, bei denen optionaler Whitespace zur Verbesserung der Lesbarkeit bevorzugt wird, SOLLTE ein Absender den optionalen Whitespace als einzelnes SP erzeugen; andernfalls SOLLTE ein Absender keinen optionalen Whitespace erzeugen, außer soweit nötig, um ungültige oder unerwünschte Protokollelemente während der In-Place-Nachrichtenfilterung auszublenden.

Die Regel RWS wird verwendet, wenn mindestens ein Oktett linearen Whitespace erforderlich ist, um Feld-Token zu trennen. Ein Absender SOLLTE RWS als einzelnes SP erzeugen.

Die Regel BWS wird verwendet, wo die Grammatik optionalen Whitespace nur aus historischen Gründen zulässt. Ein Absender darf BWS NICHT in Nachrichten erzeugen. Ein Empfänger muss auf solchen schlechten Whitespace prüfen und ihn entfernen, bevor er das Protokollelement interpretiert.

OWS            = *( SP / HTAB )
; optional whitespace
RWS = 1*( SP / HTAB )
; required whitespace
BWS = OWS
; "bad" whitespace

3.2.4. Feld-Parsing​

Nachrichten werden mit einem generischen Algorithmus geparst, unabhängig von den einzelnen Header-Feldnamen. Die Inhalte innerhalb eines bestimmten Feldwerts werden erst in einer späteren Stufe der Nachrichteninterpretation geparst (üblicherweise nachdem der gesamte Header-Abschnitt der Nachricht verarbeitet wurde). Folglich verwendet diese Spezifikation keine ABNF-Regeln, um jedes Paar "Field-Name: Field Value" zu definieren, wie es in früheren Ausgaben getan wurde. Stattdessen verwendet diese Spezifikation ABNF-Regeln, die entsprechend jedem registrierten Feldnamen benannt sind, wobei die Regel die gültige Grammatik für die entsprechenden Feldwerte dieses Felds definiert (d. h. nachdem der Feldwert durch einen generischen Feldparser aus dem Header-Abschnitt extrahiert wurde).

Zwischen dem Header-Feldnamen und dem Doppelpunkt ist kein Whitespace erlaubt. In der Vergangenheit haben Unterschiede in der Behandlung solchen Whitespace zu Sicherheitslücken beim Anfrage-Routing und bei der Antwortbehandlung geführt. Ein Server muss jede empfangene Anforderungsnachricht, die Whitespace zwischen einem Header-Feldnamen und dem Doppelpunkt enthält, mit dem Antwortcode 400 (Bad Request) zurückweisen. Ein Proxy muss jeden solchen Whitespace aus einer Antwortnachricht entfernen, bevor er die Nachricht stromabwärts weiterleitet.

Einem Feldwert kann optionaler Whitespace (OWS) vorangehen und/oder folgen; ein einzelnes SP vor dem Feldwert wird für eine konsistente Lesbarkeit durch Menschen bevorzugt. Der Feldwert enthält keinen führenden oder nachfolgenden Whitespace: OWS, das vor dem ersten Nicht-Whitespace-Oktett des Feldwerts oder nach dem letzten Nicht-Whitespace-Oktett des Feldwerts auftritt, sollte von Parsern beim Extrahieren des Feldwerts aus einem Header-Feld ausgeschlossen werden.

Historisch konnten HTTP-Header-Feldwerte über mehrere Zeilen erstreckt werden, indem jeder zusätzlichen Zeile mindestens ein Leerzeichen oder horizontaler Tabulator vorangestellt wurde (obs-fold). Diese Spezifikation verwirft solche Zeilenfaltung, außer innerhalb des Medientyps message/http (Abschnitt 8.3.1). Ein Absender darf KEINE Nachricht erzeugen, die Zeilenfaltung enthält (d. h., deren field-value einen Treffer für die Regel obs-fold enthält), es sei denn, die Nachricht ist für die Verpackung innerhalb des Medientyps message/http vorgesehen.

Ein Server, der ein obs-fold in einer Anforderungsnachricht empfängt, das nicht innerhalb eines message/http-Containers liegt, muss entweder die Nachricht zurückweisen, indem er einen 400 (Bad Request) sendet, vorzugsweise mit einer Repräsentation, die erklärt, dass veraltete Zeilenfaltung nicht akzeptabel ist, oder jedes empfangene obs-fold durch ein oder mehrere SP-Oktette ersetzen, bevor er den Feldwert interpretiert oder die Nachricht stromabwärts weiterleitet.

Ein Proxy oder Gateway, der ein obs-fold in einer Antwortnachricht empfängt, das nicht innerhalb eines message/http-Containers liegt, muss entweder die Nachricht verwerfen und sie durch eine Antwort 502 (Bad Gateway) ersetzen, vorzugsweise mit einer Repräsentation, die erklärt, dass nicht akzeptable Zeilenfaltung empfangen wurde, oder jedes empfangene obs-fold durch ein oder mehrere SP-Oktette ersetzen, bevor er den Feldwert interpretiert oder die Nachricht stromabwärts weiterleitet.

Ein User Agent, der ein obs-fold in einer Antwortnachricht empfängt, das nicht innerhalb eines message/http-Containers liegt, muss jedes empfangene obs-fold durch ein oder mehrere SP-Oktette ersetzen, bevor er den Feldwert interpretiert.

Historisch hat HTTP Feldinhalte mit Text im Zeichensatz ISO-8859-1 [ISO-8859-1] zugelassen und andere Zeichensätze nur durch Verwendung der Kodierung nach [RFC2047] unterstützt. In der Praxis verwenden die meisten HTTP-Header-Feldwerte nur eine Teilmenge des Zeichensatzes US-ASCII [USASCII]. Neu definierte Header-Felder SOLLTEN ihre Feldwerte auf US-ASCII-Oktette beschränken. Ein Empfänger SOLLTE andere Oktette im Feldinhalt (obs-text) als undurchsichtige Daten behandeln.

3.2.5. Feldgrenzen​

HTTP setzt, wie in Abschnitt 2.5 beschrieben, keine vordefinierte Grenze für die Länge jedes Header-Felds oder für die Länge des Header-Abschnitts als Ganzes. In der Praxis gibt es verschiedene Ad-hoc-Beschränkungen der Länge einzelner Header-Felder, die oft von der spezifischen Feld-Semantik abhängen.

Ein Server, der ein Anforderungs-Header-Feld oder eine Gruppe von Feldern empfängt, die größer ist als er verarbeiten möchte, MUSS mit einem geeigneten Statuscode 4xx (Client Error) antworten. Das Ignorieren solcher Header-Felder würde die Anfälligkeit des Servers für Request-Smuggling-Angriffe (Abschnitt 9.5) erhöhen.

Ein Client KANN empfangene Header-Felder, die größer sind als der Client verarbeiten möchte, verwerfen oder kürzen, wenn die Feld-Semantik so beschaffen ist, dass die verworfenen Werte sicher ignoriert werden können, ohne das Nachrichten-Framing oder die Antwort-Semantik zu ändern.

3.2.6. Feldwertkomponenten​

Die meisten HTTP-Header-Feldwerte werden mithilfe gemeinsamer Syntaxkomponenten (token, quoted-string und comment) definiert, die durch Whitespace oder bestimmte Begrenzungszeichen getrennt sind. Begrenzungszeichen werden aus der Menge der sichtbaren US-ASCII-Zeichen gewählt, die in einem Token nicht erlaubt sind (DQUOTE und "(),/:;<=>?@[]{}").

token          = 1*tchar

tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; any VCHAR, except delimiters

Eine Textzeichenkette wird als einzelner Wert geparst, wenn sie mit doppelten Anführungszeichen in Anführungszeichen gesetzt ist.

quoted-string  = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text
obs-text = %x80-FF

Kommentare können in einigen HTTP-Header-Feldern eingefügt werden, indem der Kommentartext in Klammern gesetzt wird. Kommentare sind nur in Feldern erlaubt, die "comment" als Teil ihrer Feldwertdefinition enthalten.

comment        = "(" *( ctext / quoted-pair / comment ) ")"
ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text

Das Backslash-Oktett ("") kann als Ein-Oktett-Quoting-Mechanismus innerhalb von quoted-string- und comment-Konstrukten verwendet werden. Empfänger, die den Wert eines quoted-string verarbeiten, MÜSSEN ein quoted-pair so behandeln, als wäre es durch das auf den Backslash folgende Oktett ersetzt worden.

quoted-pair    = "\" ( HTAB / SP / VCHAR / obs-text )

Ein Absender SOLLTE NICHT ein quoted-pair in einem quoted-string erzeugen, außer wo es notwendig ist, um in dieser Zeichenkette vorkommende DQUOTE- und Backslash-Oktette zu quoten. Ein Absender SOLLTE NICHT ein quoted-pair in einem Kommentar erzeugen, außer wo es notwendig ist, um in diesem Kommentar vorkommende Klammern ["(" und ")"] und Backslash-Oktette zu quoten.

3.3. Nachrichtenkörper​

Der Nachrichtenkörper (falls vorhanden) einer HTTP-Nachricht wird verwendet, um den Payload-Body dieser Anfrage oder Antwort zu transportieren. Der Nachrichtenkörper ist mit dem Payload-Body identisch, es sei denn, es wurde eine Transferkodierung angewendet, wie in Abschnitt 3.3.1 beschrieben.

message-body = *OCTET

Die Regeln dafür, wann ein Nachrichtenkörper in einer Nachricht erlaubt ist, unterscheiden sich für Anfragen und Antworten.

Das Vorhandensein eines Nachrichtenkörpers in einer Anfrage wird durch ein Header-Feld Content-Length oder Transfer-Encoding angezeigt. Das Framing von Anforderungsnachrichten ist unabhängig von der Methodensemantik, selbst wenn die Methode keine Verwendung für einen Nachrichtenkörper definiert.

Das Vorhandensein eines Nachrichtenkörpers in einer Antwort hängt sowohl von der Anforderungsmethode, auf die geantwortet wird, als auch vom Antwortstatuscode ab (Abschnitt 3.1.2). Antworten auf die Anforderungsmethode HEAD (Abschnitt 4.3.2 von [RFC7231]) enthalten niemals einen Nachrichtenkörper, weil die zugehörigen Antwort-Header-Felder (z. B. Transfer-Encoding, Content-Length usw.), sofern vorhanden, nur anzeigen, wie ihre Werte gewesen wären, wenn die Anforderungsmethode GET gewesen wäre (Abschnitt 4.3.1 von [RFC7231]). 2xx-Antworten (Successful) auf eine CONNECT-Anforderungsmethode (Abschnitt 4.3.6 von [RFC7231]) wechseln in den Tunnelmodus, statt einen Nachrichtenkörper zu haben. Alle 1xx-Antworten (Informational), 204 (No Content) und 304 (Not Modified) enthalten keinen Nachrichtenkörper. Alle anderen Antworten enthalten einen Nachrichtenkörper, obwohl der Körper eine Länge von null haben kann.

3.3.1. Transfer-Encoding​

Das Header-Feld Transfer-Encoding listet die Namen der Transferkodierungen auf, die der Abfolge von Transferkodierungen entsprechen, die auf den Payload-Body angewendet wurden (oder werden), um den Nachrichtenkörper zu bilden. Transferkodierungen sind in Abschnitt 4 definiert.

Transfer-Encoding = 1#transfer-coding

Transfer-Encoding ist analog zum Feld Content-Transfer-Encoding von MIME, das entwickelt wurde, um den sicheren Transport von Binärdaten über einen 7-Bit-Transportdienst zu ermöglichen ([RFC2045], Abschnitt 6). Für ein 8bit-clean-Übertragungsprotokoll liegt der Fokus des sicheren Transports jedoch anders. Im Falle von HTTP ist Transfer-Encoding in erster Linie dazu gedacht, einen dynamisch erzeugten Payload exakt abzugrenzen und Payload-Kodierungen, die nur aus Gründen der Transporteffizienz oder Sicherheit angewendet werden, von solchen zu unterscheiden, die Merkmale der ausgewählten Ressource sind.

Ein Empfänger muss in der Lage sein, die chunked-Transferkodierung (Abschnitt 4.1) zu parsen, weil sie eine entscheidende Rolle beim Framing von Nachrichten spielt, wenn die Größe des Payload-Bodys im Voraus nicht bekannt ist. Ein Absender darf chunked NICHT mehr als einmal auf einen Nachrichtenkörper anwenden (d. h., das Chunking einer bereits gechunkten Nachricht ist nicht erlaubt). Wird eine andere Transferkodierung als chunked auf einen Anforderungs-Payload-Body angewendet, muss der Absender chunked als abschließende Transferkodierung anwenden, um sicherzustellen, dass die Nachricht ordnungsgemäß geframt wird. Wird eine andere Transferkodierung als chunked auf einen Antwort-Payload-Body angewendet, muss der Absender entweder chunked als abschließende Transferkodierung anwenden oder die Nachricht durch Schließen der Verbindung beenden.

Zum Beispiel

Transfer-Encoding: gzip, chunked

zeigt an, dass der Payload-Body mit der gzip-Kodierung komprimiert und dann bei der Bildung des Nachrichtenkörpers mit der chunked-Kodierung gechunkt wurde.

Anders als Content-Encoding (Abschnitt 3.1.2.1 von [RFC7231]) ist Transfer-Encoding eine Eigenschaft der Nachricht, nicht der Repräsentation, und jeder Empfänger entlang der Anfrage/Antwort-Kette KANN die empfangene(n) Transferkodierung(en) dekodieren oder zusätzliche Transferkodierung(en) auf den Nachrichtenkörper anwenden, sofern entsprechende Änderungen am Feldwert von Transfer-Encoding vorgenommen werden. Zusätzliche Informationen über die Kodierungsparameter können durch andere Header-Felder bereitgestellt werden, die nicht durch diese Spezifikation definiert sind.

Transfer-Encoding KANN in einer Antwort auf eine HEAD-Anfrage oder in einer 304-Antwort (Not Modified) (Abschnitt 4.1 von [RFC7232]) auf eine GET-Anfrage gesendet werden -- keines von beiden enthält einen Nachrichtenkörper --, um anzuzeigen, dass der Ursprungsserver eine Transferkodierung auf den Nachrichtenkörper angewendet hätte, wenn die Anfrage eine unbedingte GET gewesen wäre. Diese Angabe ist jedoch nicht erforderlich, weil jeder Empfänger in der Antwortkette (einschließlich des Ursprungsservers) Transferkodierungen entfernen kann, wenn sie nicht benötigt werden.

Ein Server darf KEIN Header-Feld Transfer-Encoding in einer Antwort mit einem Statuscode 1xx (Informational) oder 204 (No Content) senden. Ein Server darf KEIN Header-Feld Transfer-Encoding in einer 2xx-Antwort (Successful) auf eine CONNECT-Anfrage senden (Abschnitt 4.3.6 von [RFC7231]).

Transfer-Encoding wurde in HTTP/1.1 eingeführt. Es wird allgemein angenommen, dass Implementierungen, die nur HTTP/1.0-Unterstützung angeben, nicht verstehen werden, wie ein transferkodierter Payload zu verarbeiten ist. Ein Client darf KEINE Anfrage senden, die Transfer-Encoding enthält, es sei denn, er weiß, dass der Server HTTP/1.1-Anfragen (oder später) verarbeiten wird; solches Wissen kann in Form einer spezifischen Benutzerkonfiguration oder durch Erinnern der Version einer zuvor empfangenen Antwort vorliegen. Ein Server darf KEINE Antwort senden, die Transfer-Encoding enthält, es sei denn, die entsprechende Anfrage zeigt HTTP/1.1 (oder später) an.

Ein Server, der eine Anforderungsnachricht mit einer Transferkodierung empfängt, die er nicht versteht, SOLLTE mit 501 (Not Implemented) antworten.

3.3.2. Content-Length​

Wenn eine Nachricht kein Header-Feld Transfer-Encoding hat, kann ein Header-Feld Content-Length die erwartete Größe als Dezimalzahl von Oktetten für einen möglichen Payload-Body angeben. Bei Nachrichten, die einen Payload-Body enthalten, liefert der Feldwert von Content-Length die Framing-Informationen, die notwendig sind, um zu bestimmen, wo der Body (und die Nachricht) endet. Bei Nachrichten, die keinen Payload-Body enthalten, gibt Content-Length die Größe der ausgewählten Repräsentation an (Abschnitt 3 von [RFC7231]).

Content-Length = 1*DIGIT

Ein Beispiel ist

Content-Length: 3495

Ein Absender darf KEIN Header-Feld Content-Length in einer Nachricht senden, die ein Header-Feld Transfer-Encoding enthält.

Ein User Agent SOLLTE einen Content-Length in einer Anforderungsnachricht senden, wenn kein Transfer-Encoding gesendet wird und die Anforderungsmethode eine Bedeutung für einen eingeschlossenen Payload-Body definiert. Beispielsweise wird normalerweise ein Header-Feld Content-Length in einer POST-Anfrage gesendet, selbst wenn der Wert 0 ist (was einen leeren Payload-Body anzeigt). Ein User Agent SOLLTE NICHT ein Header-Feld Content-Length senden, wenn die Anforderungsnachricht keinen Payload-Body enthält und die Methodensemantik keinen solchen Body vorsieht.

Ein Server KANN ein Header-Feld Content-Length in einer Antwort auf eine HEAD-Anfrage senden (Abschnitt 4.3.2 von [RFC7231]); ein Server darf in einer solchen Antwort KEINEN Content-Length senden, es sei denn, sein Feldwert ist gleich der Dezimalzahl von Oktetten, die im Payload-Body einer Antwort gesendet worden wären, wenn dieselbe Anfrage die Methode GET verwendet hätte.

Ein Server KANN ein Header-Feld Content-Length in einer 304-Antwort (Not Modified) auf eine bedingte GET-Anfrage senden (Abschnitt 4.1 von [RFC7232]); ein Server darf in einer solchen Antwort KEINEN Content-Length senden, es sei denn, sein Feldwert ist gleich der Dezimalzahl von Oktetten, die im Payload-Body einer 200-Antwort (OK) auf dieselbe Anfrage gesendet worden wären.

Ein Server darf KEIN Header-Feld Content-Length in einer Antwort mit einem Statuscode 1xx (Informational) oder 204 (No Content) senden. Ein Server darf KEIN Header-Feld Content-Length in einer 2xx-Antwort (Successful) auf eine CONNECT-Anfrage senden (Abschnitt 4.3.6 von [RFC7231]).

Abgesehen von den oben definierten Fällen SOLLTE ein Ursprungsserver in Abwesenheit von Transfer-Encoding ein Header-Feld Content-Length senden, wenn die Größe des Payload-Bodys vor dem Senden des vollständigen Header-Abschnitts bekannt ist. Dies ermöglicht es downstream-Empfängern, den Übertragungsfortschritt zu messen, zu wissen, wann eine empfangene Nachricht vollständig ist, und die Verbindung möglicherweise für weitere Anfragen wiederzuverwenden.

Jeder Content-Length-Feldwert größer oder gleich null ist gültig. Da es keine vordefinierte Grenze für die Länge eines Payloads gibt, muss ein Empfänger potenziell große Dezimalzahlen erwarten und Parsing-Fehler aufgrund von Ganzzahlkonvertierungs-Überläufen verhindern (Abschnitt 9.3).

Wird eine Nachricht empfangen, die mehrere Header-Felder Content-Length mit Feldwerten aus demselben Dezimalwert aufweist, oder ein einzelnes Header-Feld Content-Length mit einem Feldwert, der eine Liste identischer Dezimalwerte enthält (z. B. "Content-Length: 42, 42"), was anzeigt, dass doppelte Content-Length-Header-Felder von einem vorgelagerten Nachrichtenprozessor erzeugt oder zusammengefasst wurden, dann muss der Empfänger entweder die Nachricht als ungültig zurückweisen oder die duplizierten Feldwerte durch ein einzelnes gültiges Content-Length-Feld mit diesem Dezimalwert ersetzen, bevor er die Nachrichtenkörperlänge bestimmt oder die Nachricht weiterleitet.

Hinweis: Die Verwendung von Content-Length durch HTTP für das Nachrichten-Framing unterscheidet sich erheblich von der Verwendung desselben Felds in MIME, wo es ein optionales Feld ist, das nur innerhalb des Medientyps "message/external-body" verwendet wird.

3.3.3. Nachrichtenkörperlänge​

Die Länge eines Nachrichtenkörpers wird durch eines der folgenden Elemente bestimmt (in der Reihenfolge der Priorität):

  1. Jede Antwort auf eine HEAD-Anfrage und jede Antwort mit einem Statuscode 1xx (Informational), 204 (No Content) oder 304 (Not Modified) wird immer durch die erste Leerzeile nach den Header-Feldern beendet, unabhängig von den in der Nachricht vorhandenen Header-Feldern, und kann daher keinen Nachrichtenkörper enthalten.

  2. Jede 2xx-Antwort (Successful) auf eine CONNECT-Anfrage impliziert, dass die Verbindung unmittelbar nach der Leerzeile, die die Header-Felder abschließt, zu einem Tunnel wird. Ein Client muss alle in einer solchen Nachricht empfangenen Header-Felder Content-Length oder Transfer-Encoding ignorieren.

  3. Wenn ein Header-Feld Transfer-Encoding vorhanden ist und die chunked-Transferkodierung (Abschnitt 4.1) die letzte Kodierung ist, wird die Nachrichtenkörperlänge bestimmt, indem die gechunkten Daten gelesen und dekodiert werden, bis die Transferkodierung anzeigt, dass die Daten vollständig sind.

Wenn ein Header-Feld Transfer-Encoding in einer Antwort vorhanden ist und die chunked-Transferkodierung nicht die letzte Kodierung ist, wird die Nachrichtenkörperlänge bestimmt, indem die Verbindung gelesen wird, bis sie vom Server geschlossen wird. Wenn ein Header-Feld Transfer-Encoding in einer Anfrage vorhanden ist und die chunked-Transferkodierung nicht die letzte Kodierung ist, kann die Nachrichtenkörperlänge nicht zuverlässig bestimmt werden; der Server MUSS mit dem Statuscode 400 (Bad Request) antworten und dann die Verbindung schließen.

Wird eine Nachricht mit sowohl einem Header-Feld Transfer-Encoding als auch einem Header-Feld Content-Length empfangen, so übersteuert Transfer-Encoding den Content-Length. Eine solche Nachricht kann den Versuch anzeigen, Request-Smuggling (Abschnitt 9.5) oder Response-Splitting (Abschnitt 9.4) durchzuführen, und sollte als Fehler behandelt werden. Ein Absender muss das empfangene Feld Content-Length entfernen, bevor er eine solche Nachricht stromabwärts weiterleitet.

  1. Wird eine Nachricht ohne Transfer-Encoding und entweder mit mehreren Header-Feldern Content-Length mit unterschiedlichen Feldwerten oder mit einem einzelnen Header-Feld Content-Length mit einem ungültigen Wert empfangen, dann ist das Nachrichten-Framing ungültig und der Empfänger muss dies als nicht behebbaren Fehler behandeln. Handelt es sich um eine Anforderungsnachricht, muss der Server mit dem Statuscode 400 (Bad Request) antworten und dann die Verbindung schließen. Handelt es sich um eine von einem Proxy empfangene Antwortnachricht, muss der Proxy die Verbindung zum Server schließen, die empfangene Antwort verwerfen und eine Antwort 502 (Bad Gateway) an den Client senden. Handelt es sich um eine von einem User Agent empfangene Antwortnachricht, muss der User Agent die Verbindung zum Server schließen und die empfangene Antwort verwerfen.

  2. Wenn ein gültiges Header-Feld Content-Length ohne Transfer-Encoding vorhanden ist, definiert sein Dezimalwert die erwartete Nachrichtenkörperlänge in Oktetten. Schließt der Absender die Verbindung oder läuft beim Empfänger eine Zeitüberschreitung ab, bevor die angegebene Anzahl von Oktetten empfangen wurde, muss der Empfänger die Nachricht als unvollständig betrachten und die Verbindung schließen.

  3. Handelt es sich um eine Anforderungsnachricht und trifft nichts der oben Genannten zu, dann ist die Nachrichtenkörperlänge null (es ist kein Nachrichtenkörper vorhanden).

  4. Andernfalls handelt es sich um eine Antwortnachricht ohne deklarierte Nachrichtenkörperlänge, sodass die Nachrichtenkörperlänge durch die Anzahl der vor dem Schließen der Verbindung durch den Server empfangenen Oktette bestimmt wird.

Da es keine Möglichkeit gibt, eine erfolgreich abgeschlossene, durch Schließen abgegrenzte Nachricht von einer teilweise empfangenen, durch Netzwerkfehler unterbrochenen Nachricht zu unterscheiden, SOLLTE ein Server nach Möglichkeit kodierungs- oder längenabgegrenzte Nachrichten erzeugen. Die Funktion der Abgrenzung durch Schließen existiert in erster Linie für die Abwärtskompatibilität mit HTTP/1.0.

Ein Server KANN eine Anfrage, die einen Nachrichtenkörper, aber keinen Content-Length enthält, ablehnen, indem er mit 411 (Length Required) antwortet.

Sofern keine andere Transferkodierung als chunked angewendet wurde, SOLLTE ein Client, der eine Anfrage mit einem Nachrichtenkörper sendet, ein gültiges Header-Feld Content-Length verwenden, wenn die Nachrichtenkörperlänge im Voraus bekannt ist, statt der chunked-Transferkodierung, da einige bestehende Dienste auf chunked mit dem Statuscode 411 (Length Required) antworten, selbst wenn sie die chunked-Transferkodierung verstehen. Dies liegt typischerweise daran, dass solche Dienste über ein Gateway implementiert sind, das vor dem Aufruf einen Content-Length erfordert, und der Server nicht in der Lage oder nicht willens ist, die gesamte Anfrage vor der Verarbeitung zu puffern.

Ein User Agent, der eine Anfrage mit einem Nachrichtenkörper sendet, MUSS ein gültiges Header-Feld Content-Length senden, wenn er nicht weiß, dass der Server HTTP/1.1-Anfragen (oder später) verarbeiten wird; solches Wissen kann in Form einer spezifischen Benutzerkonfiguration oder durch Erinnern der Version einer zuvor empfangenen Antwort vorliegen.

Wenn die endgültige Antwort auf die letzte Anfrage einer Verbindung vollständig empfangen wurde und noch zusätzliche Daten zu lesen sind, KANN ein User Agent die verbleibenden Daten verwerfen oder versuchen zu bestimmen, ob diese Daten als Teil des vorherigen Antwortkörpers dazugehören, was der Fall sein könnte, wenn der Content-Length-Wert der vorherigen Nachricht falsch ist. Ein Client darf solche zusätzlichen Daten NICHT als separate Antwort verarbeiten, zwischenspeichern oder weiterleiten, da ein solches Verhalten anfällig für Cache-Poisoning wäre.

3.4. Behandlung unvollständiger Nachrichten​

Ein Server, der eine unvollständige Anforderungsnachricht empfängt, üblicherweise aufgrund einer abgebrochenen Anfrage oder einer ausgelösten Zeitüberschreitungs-Ausnahme, KANN vor dem Schließen der Verbindung eine Fehlerantwort senden.

Ein Client, der eine unvollständige Antwortnachricht empfängt, was auftreten kann, wenn eine Verbindung vorzeitig geschlossen wird oder wenn das Dekodieren einer vermeintlich gechunkten Transferkodierung fehlschlägt, muss die Nachricht als unvollständig vermerken. Cache-Anforderungen für unvollständige Antworten sind in Abschnitt 3 von [RFC7234] definiert.

Wenn eine Antwort mitten im Header-Abschnitt endet (bevor die Leerzeile empfangen wird) und der Statuscode möglicherweise auf Header-Felder angewiesen ist, um die vollständige Bedeutung der Antwort zu vermitteln, kann der Client nicht annehmen, dass diese Bedeutung vermittelt wurde; der Client muss die Anfrage möglicherweise wiederholen, um zu bestimmen, welche Aktion als Nächstes zu ergreifen ist.

Ein Nachrichtenkörper, der die chunked-Transferkodierung verwendet, ist unvollständig, wenn der den Kodierungsvorgang abschließende Chunk der Größe null nicht empfangen wurde. Eine Nachricht, die einen gültigen Content-Length verwendet, ist unvollständig, wenn die Größe des empfangenen Nachrichtenkörpers (in Oktetten) kleiner ist als der durch Content-Length angegebene Wert. Eine Antwort, die weder chunked-Transferkodierung noch Content-Length hat, wird durch Schließen der Verbindung beendet und gilt daher unabhängig von der Anzahl der empfangenen Nachrichtenkörper-Oktette als vollständig, vorausgesetzt, der Header-Abschnitt wurde unversehrt empfangen.

3.5. Robustheit des Nachrichten-Parsings​

Ältere HTTP/1.0-User-Agent-Implementierungen senden möglicherweise eine zusätzliche CRLF nach einer POST-Anfrage als Workaround für einige frühe Serveranwendungen, die Nachrichtenkörperinhalte, die nicht durch ein Zeilenende abgeschlossen waren, nicht lesen konnten. Ein HTTP/1.1-User-Agent darf eine Anfrage NICHT mit einer zusätzlichen CRLF einleiten oder abschließen. Wenn das Beenden des Anforderungsnachrichtenkörpers mit einem Zeilenende gewünscht wird, muss der User Agent die abschließenden CRLF-Oktette als Teil der Nachrichtenkörperlänge zählen.

Im Interesse der Robustheit SOLLTE ein Server, der erwartet, eine Anfragezeile zu empfangen und zu parsen, mindestens eine leere Zeile (CRLF) ignorieren, die vor der Anfragezeile empfangen wird.

Obwohl das Zeilenendezeichen für die Startzeile und die Header-Felder die Sequenz CRLF ist, KANN ein Empfänger ein einzelnes LF als Zeilenendezeichen erkennen und jedes vorausgehende CR ignorieren.

Obwohl die Grammatikregeln für request-line und status-line verlangen, dass jedes der Komponentenelemente durch ein einzelnes SP-Oktett getrennt ist, KÖNNEN Empfänger stattdessen an durch Whitespace begrenzten Wortgrenzen parsen und, abgesehen vom CRLF-Abschluss, jede Form von Whitespace als SP-Trenner behandeln, während sie vorausgehenden oder nachfolgenden Whitespace ignorieren; solcher Whitespace umfasst eines oder mehrere der folgenden Oktette: SP, HTAB, VT (%x0B), FF (%x0C) oder ein einzelnes CR. Nachsichtiges Parsen kann jedoch zu Sicherheitslücken führen, wenn es mehrere Empfänger der Nachricht gibt und jeder seine eigene, einzigartige Interpretation von Robustheit hat (siehe Abschnitt 9.5).

Wenn ein Server, der nur auf HTTP-Anforderungsnachrichten wartet oder verarbeitet, was von der Startzeile her als HTTP-Anforderungsnachricht erscheint, eine Sequenz von Oktetten empfängt, die abgesehen von den oben aufgeführten Robustheitsausnahmen nicht zur Grammatik HTTP-message passt, SOLLTE der Server mit einer Antwort 400 (Bad Request) antworten.