Zum Hauptinhalt springen

8. HTTP-Semantik in HTTP/2 ausdrücken

HTTP/2 ist so konzipiert, dass es so kompatibel wie möglich mit der aktuellen Verwendung von HTTP ist. Das bedeutet, dass aus Anwendungssicht die Funktionen des Protokolls weitgehend unverändert bleiben. Um dies zu erreichen, werden alle Anfrage- und Antwortsemantics durch die Mechanismen in HTTP/1.1 [HTTP] erhalten, obwohl sich die Syntax zur Übermittlung dieser Semantik geändert hat.

Somit gelten die Spezifikation und Anforderungen von HTTP [HTTP], Semantik und Syntax sowie Erweiterungen wie [COOKIES] für HTTP/2. Die in diesem Abschnitt beschriebenen Einschränkungen und zusätzlichen Anforderungen sind auf diejenigen beschränkt, die für eine erfolgreiche Implementierung von HTTP/2 erforderlich sind, die sich auf das Wire-Format von HTTP beziehen oder die ohne zusätzliche Definition in HTTP/2 zu Mehrdeutigkeit führen würden.

8.1. HTTP-Nachrichten-Framing

Eine HTTP-Nachricht (Anfrage oder Antwort) besteht aus:

  1. nur für eine Antwort, null oder mehr HEADERS-Frames (jeweils gefolgt von null oder mehr CONTINUATION-Frames), die die Nachrichtenheader von informativen (1xx) HTTP-Antworten enthalten (siehe Abschnitt 15 von [HTTP]), und/oder

  2. einem HEADERS-Frame (gefolgt von null oder mehr CONTINUATION-Frames), der die Nachrichtenheader enthält (siehe Abschnitt 6.3 von [HTTP]), und

  3. null oder mehr DATA-Frames, die den Nachrichteninhalt enthalten (siehe Abschnitt 6.4 von [HTTP]), und

  4. optional einem HEADERS-Frame (gefolgt von null oder mehr CONTINUATION-Frames), der den Trailer-Part-Feldabschnitt enthält (siehe Abschnitt 6.5 von [HTTP]).

Der letzte Frame in der Sequenz trägt ein END_STREAM-Flag, wobei zu beachten ist, dass ein HEADERS-Frame mit END_STREAM-Flag von CONTINUATION-Frames gefolgt werden kann, die den verbleibenden Teil des Header-Blocks tragen. Andere Frames (von jedem Stream) DÜRFEN NICHT zwischen dem HEADERS-Frame und eventuell folgenden CONTINUATION-Frames auftreten.

HTTP/2 verwendet DATA-Frames, um Nachrichteninhalte zu übertragen. Die [CHUNKED] Transfer-Codierung (definiert in Abschnitt 7.1 von [HTTP]) DARF NICHT mit HTTP/2 verwendet werden.

Trailer-Felder werden in einem Feldabschnitt übertragen; siehe Abschnitt 8.2. Es gibt keinen definierten Feldabschnittsnamen für Trailer-Felder, da alle Trailer-Felder in denselben Feldabschnitt in HTTP/2 kodiert werden. Es gibt keine definierte Reihenfolge zwischen Feldzeilen; siehe Abschnitt 8.2.1. Schließlich enthalten Trailer-Felder keine Pseudo-Header-Felder (siehe Abschnitt 8.3).

Eine HTTP-Anfrage oder -Antwort ist fehlerhaft, wenn sie eines der folgenden ist:

  • Sie enthält eine Feldzeile mit einem ungültigen Feldnamen (siehe Abschnitt 5.1 von [HTTP]), eine Feldzeile mit einem ungültigen Feldzeilenwert (siehe Abschnitt 5.5 von [HTTP]) oder ein Pseudo-Header-Feld, das in diesem Kontext nicht erscheinen darf (siehe Abschnitt 8.3),

  • Sie lässt ein Pseudo-Header-Feld aus, das für diesen Nachrichtentyp erforderlich ist (siehe Abschnitt 8.3),

  • Sie enthält Großbuchstaben in Feldzeilennamen, oder

  • Sie enthält einen ungültigen Content-Length-Feldwert.

Die Fehlerbehandlung für Streams wird in Abschnitt 8.1.1 beschrieben.

Zusätzlich zu den obligatorischen Teilen einer Nachricht können PRIORITY-Informationen in HEADERS-Frames vorhanden sein. Weitere Informationen finden Sie in Abschnitt 5.3.

Der Empfang eines HEADERS-Frames, der einen ungültigen Feldblock enthält, führt zu einem Stream-Fehler (siehe Abschnitt 5.4.2).

8.1.1. Fehlerhafte Nachrichten

Eine fehlerhafte Nachricht ist eine, die ansonsten eine gültige Folge von Frames ist, aber aufgrund des Vorhandenseins verbotener Felder, des Fehlens erforderlicher Felder oder ungültiger Feldwerte ungültig ist. Ein Peer, der eine fehlerhafte Anfrage oder Antwort erkennt, MUSS mit einem Stream-Fehler antworten (siehe Abschnitt 5.4.2). Bei fehlerhaften Anfragen KANN ein Server eine HTTP-Antwort senden, bevor er den Stream schließt oder zurücksetzt. Clients DÜRFEN KEINE fehlerhafte Antwort akzeptieren. Beachten Sie, dass diese Anforderungen zum Schutz vor mehreren Arten von gängigen Angriffen gedacht sind; sie sind absichtlich streng, da Nachsicht Implementierungen diesen Schwachstellen aussetzen kann.

8.2. HTTP-Felder

HTTP-Feldnamen und -werte sind Oktetfolgen und werden mit derselben Codierung wie in HTTP/1.x verwendet (siehe Abschnitt 5.1 von [HTTP]). Feldnamen MÜSSEN jedoch vor ihrer Codierung in HTTP/2 in Kleinbuchstaben umgewandelt werden. Eine Anfrage oder Antwort, die Großbuchstaben in Feldnamen enthält, MUSS als fehlerhaft behandelt werden (Abschnitt 8.1.1).

HTTP/2 verwendet das Connection-Header-Feld (siehe Abschnitt 7.6.1 von [HTTP]) nicht, um verbindungsspezifische Felder anzuzeigen; in diesem Protokoll werden verbindungsspezifische Metadaten auf andere Weise übermittelt. Ein Endpunkt DARF KEINE HTTP/2-Nachricht generieren, die verbindungsspezifische Felder enthält; jede Nachricht, die verbindungsspezifische Felder enthält, MUSS als fehlerhaft behandelt werden (Abschnitt 8.1.1).

Die einzige Ausnahme hiervon ist das TE-Header-Feld, das in einer HTTP/2-Anfrage vorhanden sein KANN; wenn es vorhanden ist, DARF es KEINEN anderen Wert als "trailers" enthalten.

Dies bedeutet, dass ein Vermittler, der eine HTTP/1.x-Nachricht in HTTP/2 umwandelt, alle Felder entfernen muss, die vom Connection-Feld nominiert werden, zusammen mit dem Connection-Feld selbst. Solche Vermittler SOLLTEN auch andere verbindungsspezifische Felder wie Keep-Alive, Proxy-Connection, Transfer-Encoding und Upgrade entfernen, auch wenn sie nicht vom Connection-Feld nominiert werden.

|  Hinweis: HTTP/2 unterstützt absichtlich kein Upgrade auf ein anderes Protokoll. Die
| in [Abschnitt 3](#3-starting-http2) beschriebenen Handshake-Methoden werden als ausreichend
| für die Aushandlung der Verwendung alternativer Protokolle angesehen.

8.2.1. Feldgültigkeit

Feldnamen werden gemäß den Regeln in Abschnitt 5.1 von [HTTP] validiert, aber vor der Darstellung in HTTP/2 in Kleinbuchstaben umgewandelt.

Ein mit [COMPRESSION] komprimierter Feldabschnitt kann Leerzeichen enthalten, wie durch die "optional whitespace" (OWS) Produktion definiert; Leerzeichen sind nicht Teil des Feldes; sie MÜSSEN während der Dekomprimierung oder vor der Übergabe der Nachricht an einen Nicht-HTTP/2-Kontext, wie eine HTTP/1.1-Verbindung oder eine generische HTTP-Serveranwendung, entfernt werden.

Die Werte von Pseudo-Header-Feldern werden in Abschnitt 8.3 spezifiziert.

8.2.2. Verbindungsspezifische Header-Felder

HTTP/2 verwendet das Connection-Header-Feld nicht, um verbindungsspezifische Felder anzuzeigen; in diesem Protokoll werden verbindungsspezifische Metadaten auf andere Weise übermittelt. Ein Endpunkt DARF KEINE Nachricht generieren, die verbindungsspezifische Felder enthält; jede Nachricht, die verbindungsspezifische Felder enthält, MUSS als fehlerhaft behandelt werden (Abschnitt 8.1.1).

Die einzige Ausnahme hiervon ist das TE-Header-Feld, das in einer HTTP/2-Anfrage vorhanden sein KANN, aber wenn es vorhanden ist, DARF es KEINEN anderen Wert als "trailers" enthalten.

Das Cookie-Header-Feld [COOKIES] verwendet ein Semikolon (";"), um Cookie-Paare (oder "Krümel") zu begrenzen. Dieses Header-Feld folgt nicht den Listenregeln (siehe Abschnitt 5.3 von [HTTP]) der Kommatrennung, was verhindern kann, dass Cookie-Paare effizient komprimiert werden. Da das Cookie-Header-Feld oft eine relativ große Datenmenge enthalten kann, kann dies die Komprimierungseffizienz erheblich beeinträchtigen.

Um eine bessere Komprimierung zu ermöglichen, KANN das Cookie-Header-Feld in separate Header-Felder aufgeteilt werden, jeweils mit einem oder mehreren Cookie-Paaren. Wenn nach der Dekomprimierung mehrere Cookie-Header-Felder vorhanden sind, MÜSSEN diese zu einer einzigen Oktetzeichenkette unter Verwendung des Zwei-Oktett-Trennzeichens 0x3B, 0x20 (die ASCII-Zeichenkette "; ") zusammengefügt werden, bevor sie an einen Nicht-HTTP/2-Kontext wie eine HTTP/1.1-Verbindung oder eine generische HTTP-Serveranwendung übergeben werden.

Daher sind die folgenden zwei Listen von Cookie-Header-Feldern semantisch äquivalent.

cookie: a=b; c=d; e=f

cookie: a=b
cookie: c=d
cookie: e=f

8.3. HTTP-Kontrolldaten

HTTP/2 verwendet spezielle Pseudo-Header-Felder, die mit dem ':'-Zeichen (ASCII 0x3a) beginnen, um Informationen über die Anfrage oder Antwort zu übermitteln, die in HTTP/1.x in der Nachrichtenstart-Zeile enthalten waren. Pseudo-Header-Felder sind keine HTTP-Felder. Endpunkte DÜRFEN KEINE anderen Pseudo-Header-Felder generieren als die in diesem Dokument definierten.

Pseudo-Header-Felder sind nur im Feldabschnitt eines HEADERS- und PUSH_PROMISE-Frames gültig. Ein Feldabschnitt, der Trailer-Felder trägt, DARF jedoch KEINE Pseudo-Header-Felder enthalten; ein Trailer-Part-Feldabschnitt, der Pseudo-Header-Felder enthält, MUSS als fehlerhaft behandelt werden (Abschnitt 8.1.1).

Pseudo-Header-Felder beginnen mit einem ':'-Zeichen (ASCII 0x3a). Ihre Namen sind Feldnamen, die nur aus diesem Präfix bestehen; der Doppelpunkt ist nicht Teil des Feldnamens. Der Doppelpunkt ist nicht Teil des Token-Satzes, der für Feldnamen verwendet wird (siehe Abschnitt 5.1 von [HTTP]).

Alle Pseudo-Header-Felder MÜSSEN vor allen regulären Feldern erscheinen. Jede Anfrage oder Antwort, die ein Pseudo-Header-Feld enthält, das nach einem regulären Feld erscheint, MUSS als fehlerhaft behandelt werden (Abschnitt 8.1.1).

Die folgenden Pseudo-Header-Felder sind definiert:

8.3.1. Anfrage-Pseudo-Header-Felder

Die folgenden Pseudo-Header-Felder sind für HTTP/2-Anfragen definiert:

  • Das :method-Pseudo-Header-Feld enthält die HTTP-Methode (Abschnitt 9 von [HTTP]).

  • Das :scheme-Pseudo-Header-Feld enthält den Schema-Teil der Ziel-URI (Abschnitt 3.1 von [URI]).

    Das :scheme ist nicht auf "http" und "https" Schema-URIs beschränkt. Ein Proxy oder Gateway kann Anfragen für Nicht-HTTP-Schemas übersetzen, wodurch die Verwendung von HTTP zur Interaktion mit Nicht-HTTP-Diensten ermöglicht wird.

    Siehe Abschnitt 8.5 für die CONNECT-Methode, die das :scheme-Pseudo-Header-Feld auslässt.

  • Das :authority-Pseudo-Header-Feld enthält den Autoritätsteil der Ziel-URI (Abschnitt 3.2 von [URI]). Die Autorität DARF NICHT die veraltete userinfo-Subkomponente für "http"- oder "https"-Schema-URIs enthalten.

    Um sicherzustellen, dass die HTTP/1.1-Anforderungszeile genau reproduziert werden kann, MUSS dieses Pseudo-Header-Feld weggelassen werden, wenn eine HTTP/1.1-Anfrage übersetzt wird, die ein Anforderungsziel in Origin- oder Asterisk-Form hat (siehe Abschnitt 3.2 von [HTTP]). Clients, die HTTP/2-Anfragen direkt generieren, MÜSSEN das :authority-Pseudo-Header-Feld anstelle des Host-Felds verwenden. Ein Vermittler, der eine HTTP/2-Anfrage in HTTP/1.1 umwandelt, MUSS ein Host-Feld erstellen, wenn keines in einer Anfrage vorhanden ist, indem er den Wert des :authority-Pseudo-Header-Felds kopiert.

    Ein Server SOLLTE eine Anfrage als fehlerhaft behandeln, wenn sie eine Anfrage enthält, die sowohl das :authority-Pseudo-Header-Feld als auch das Host-Feld hat, wenn die Feldwerte nicht identisch sind.

  • Das :path-Pseudo-Header-Feld enthält die Pfad- und Abfrageteile der Ziel-URI (die absolute-path-Produktion und optional ein '?'-Zeichen gefolgt von der query-Produktion (siehe Abschnitte 3.3 und 3.4 von [URI])). Eine Anfrage in Asterisk-Form enthält den Wert '*' für das :path-Pseudo-Header-Feld.

    Dieses Pseudo-Header-Feld DARF NICHT leer sein für "http"- oder "https"-URIs; "http"- oder "https"-URIs, die keine Pfadkomponente enthalten, MÜSSEN einen Wert von '/' enthalten, es sei denn, die Anfrage wird in Asterisk-Form gestellt, in welchem Fall sie einen Wert von '*' enthalten MUSS.

    Siehe Abschnitt 8.5 für die CONNECT-Methode, die das :path-Pseudo-Header-Feld auslässt.

Alle HTTP/2-Anfragen MÜSSEN genau einen gültigen Wert für die :method- und :scheme-Pseudo-Header-Felder enthalten, es sei denn, es handelt sich um eine CONNECT-Anfrage (Abschnitt 8.5).

Wenn das :scheme-Pseudo-Header-Feld ein Schema identifiziert, das eine Autorität verwendet (siehe Abschnitt 3.2 von [URI]), dann MUSS eine HTTP/2-Anfrage, die das Anforderungsziel nicht enthält, entweder das :authority-Feld oder das Host-Feld enthalten. Wenn diese Felder fehlen, SOLLTE der Server, der die Anfrage empfängt, mit einem 400 (Bad Request) Statuscode antworten (siehe Abschnitt 15.5.1 von [HTTP]).

HTTP/2 definiert keine Möglichkeit, die Versionskennung zu übertragen, die in der HTTP/1.1-Anforderungszeile enthalten ist.

8.3.2. Antwort-Pseudo-Header-Felder

Für HTTP/2-Antworten ist ein einzelnes :status-Pseudo-Header-Feld definiert, das das HTTP-Statuscodefeld trägt (siehe Abschnitt 15 von [HTTP]). Dieses Pseudo-Header-Feld MUSS in allen Antworten enthalten sein; andernfalls ist die Antwort fehlerhaft (Abschnitt 8.1.1).

HTTP/2 definiert keine Möglichkeit, die Version oder Begründungsphrase zu übertragen, die in einer HTTP/1.1-Statuszeile enthalten ist.

8.4. Server Push

HTTP/2 ermöglicht es einem Server, Antworten präventiv (oder "push") an einen Client in Verbindung mit einer vorherigen clientinitierten Anfrage zu senden. Dies kann nützlich sein, wenn der Server weiß, dass der Client diese Antworten benötigt, um die Antwort auf die ursprüngliche Anfrage vollständig zu verarbeiten.

Eine gepushte Antwort ist immer mit einer expliziten Anfrage vom Client verbunden. Der Server sendet einen PUSH_PROMISE-Frame auf dem Stream dieser Anfrage. Der PUSH_PROMISE-Frame enthält einen Feldabschnitt, der einen vollständigen Satz von Anfragefeldern enthält, die der Server der Anfrage zuordnet.

Es gibt keine Begrenzung für die Anzahl der Antworten, die von einem Server gepusht werden können, abgesehen von den verfügbaren Stream-Identifikatoren auf einer einzelnen Verbindung. Ein Client kann jedoch die Anzahl gleichzeitig gepushter Streams begrenzen, indem er die SETTINGS_MAX_CONCURRENT_STREAMS-Einstellung ändert. Das Setzen dieses Werts auf Null deaktiviert Server-Push, indem verhindert wird, dass der Server die erforderlichen Streams erstellt. Dies verhindert nicht, dass ein Server PUSH_PROMISE-Frames sendet; Clients müssen alle unerwünschten versprochenen Streams zurücksetzen.

8.4.1. Push-Anfragen

Server-Push ist semantisch äquivalent zu einem Server, der auf eine Anfrage antwortet; in diesem Fall wird diese Anfrage jedoch auch vom Server als PUSH_PROMISE-Frame gesendet.

Der PUSH_PROMISE-Frame enthält einen Feldabschnitt, der einen vollständigen Satz von Anfragefeldern enthält, die der Server der Anfrage zuordnet. Es ist nicht möglich, eine Antwort auf eine Anfrage zu pushen, die einen Anfragekörper enthält, außer in dem Fall, dass die HTTP/2-Verbindung über TLS initiiert wurde (siehe [TLS13]).

Gepushte Anfragen MÜSSEN cachefähig sein (siehe Abschnitt 9.2.3 von [HTTP]), MÜSSEN sicher sein (siehe Abschnitt 9.2.1 von [HTTP]) und DÜRFEN KEINEN Anfrageinhalt enthalten. Clients, die eine gepushte Anfrage erhalten, die nicht cachefähig ist, nicht sicher ist oder Anfrageinhalt enthält, MÜSSEN den versprochenen Stream mit einem Stream-Fehler (Abschnitt 5.4.2) vom Typ PROTOCOL_ERROR zurücksetzen.

Gepushte Anfragefelder und Anfrage-Pseudo-Header-Felder MÜSSEN autoritativ sein (siehe Abschnitt 10.1). Der Server MUSS einen Wert im :authority-Pseudo-Header-Feld einfügen, für den der Server autoritativ ist (siehe Abschnitt 10.1). Ein Client MUSS eine gepushte Anfrage, die nicht autoritativ ist, als Stream-Fehler (Abschnitt 5.4.2) vom Typ PROTOCOL_ERROR behandeln.

Ein Client kann signalisieren, dass er eine gepushte Antwort nicht empfangen möchte, indem er einen RST_STREAM an den Server sendet, der die versprochene Stream-Kennung referenziert.

Ein Server SOLLTE nur Antworten pushen, von denen er glaubt, dass der Client sie verwenden oder anderweitig davon profitieren wird. Der Server SOLLTE möglichen Anfrageinhalt, alle Cache-Felder in der Anfrage, die Methode der Anfrage und alle Inhalte, die bekanntermaßen vom Client verwaltet werden (basierend beispielsweise auf Cookies, die bei früheren Anfragen empfangen wurden), berücksichtigen, wenn er entscheidet, was gepusht werden soll.

8.4.2. Push-Antworten

Nach dem Senden eines PUSH_PROMISE-Frames, der den versprochenen Stream referenziert, kann der Server beginnen, die gepushte Antwort auf einem Stream unter Verwendung der versprochenen Stream-Kennung zu liefern. Der Server übermittelt anfängliche Antwortfelder unter Verwendung eines HEADERS-Frames unter Verwendung der versprochenen Stream-Kennung. Dieser Stream tritt in den Zustand "half-closed (remote)" ein (Abschnitt 5.1). Der Server SOLLTE die Antwort senden, die den Push initiiert, bevor er den PUSH_PROMISE-Frame sendet, um eine Race-Bedingung zu vermeiden.

Sobald ein Client einen PUSH_PROMISE-Frame empfängt und sich entscheidet, die gepushte Antwort zu akzeptieren, SOLLTE der Client KEINE Anfragen für die versprochene Antwort stellen, bis der versprochene Stream geschlossen wurde.

Wenn der Client aus irgendeinem Grund feststellt, dass er die gepushte Antwort vom Server nicht erhalten möchte, oder wenn der Server zu lange braucht, um die versprochene Antwort zu senden, kann der Client einen RST_STREAM-Frame senden, entweder mit dem Code CANCEL oder REFUSED_STREAM und unter Referenzierung der gepushten Stream-Kennung.

Ein Client kann die SETTINGS_MAX_CONCURRENT_STREAMS-Einstellung verwenden, um die Anzahl der Antworten zu begrenzen, die gleichzeitig von einem Server gepusht werden können. Das Ankündigen eines SETTINGS_MAX_CONCURRENT_STREAMS-Werts von Null deaktiviert Server-Push, indem verhindert wird, dass der Server die erforderlichen Streams erstellt. Dies verbietet einem Server nicht, PUSH_PROMISE-Frames zu senden; Clients müssen alle versprochenen Streams zurücksetzen, die nicht gewünscht werden.

8.5. Die CONNECT-Methode

In HTTP/1.x wird die Pseudo-Methode CONNECT (Abschnitt 9.3.6 von [HTTP]) verwendet, um eine HTTP-Verbindung in einen Tunnel zu einem entfernten Host umzuwandeln. CONNECT wird hauptsächlich mit HTTP-Proxys verwendet, um eine TLS-Sitzung mit einem Origin-Server herzustellen, um mit "https"-Ressourcen zu interagieren.

In HTTP/2 wird die CONNECT-Methode verwendet, um einen Tunnel über einen entfernten Host für ähnliche Zwecke herzustellen.

Eine CONNECT-Anfrage MUSS die folgenden Pseudo-Header-Felder verwenden:

  • Das :method-Pseudo-Header-Feld wird auf "CONNECT" gesetzt.
  • Das :authority-Pseudo-Header-Feld enthält den Host und Port, zu dem eine Verbindung hergestellt werden soll (entspricht der authority-form des request-target einer CONNECT-Anfrage; siehe Abschnitt 3.2 von [HTTP]).

Die :scheme- und :path-Pseudo-Header-Felder MÜSSEN weggelassen werden.

Eine CONNECT-Anfrage DARF KEIN Content-Length- oder Transfer-Encoding-Header-Feld enthalten. Jede CONNECT-Anfrage, die diese Felder enthält, ist fehlerhaft (Abschnitt 8.1.1).

Ein Stream, der eine CONNECT-Anfrage trägt, wird nicht zum Übertragen von HTTP-Anfragen oder -Antworten verwendet. Jede erfolgreiche CONNECT-Antwort wird verwendet, um den Client zu benachrichtigen, dass der Stream zu einem Tunnel geworden ist. Dieser Stream wird nicht durch den Empfang eines DATA-Frames mit dem END_STREAM-Flag geschlossen. Der CONNECT-Anforderungs-Stream wird nicht durch den Empfang eines DATA-Frames mit dem END_STREAM-Flag geschlossen.

Ein Proxy entfernt alle Header-Felder, die als verbindungsspezifisch bekannt sind (wie die in Abschnitt 7.6.1 von [HTTP] definierten), und erlaubt dann, dass die verbleibenden Anforderungs-Header-Felder unverändert auf der Verbindung zum Server durchlaufen.

Jede 2xx (Erfolgreiche) Antwort, die nach einer CONNECT-Anfrage empfangen wird, zeigt an, dass der Proxy eine Verbindung zum angeforderten Host und Port hergestellt hat und zum Tunneln des entsprechenden Streams gewechselt ist.

Für jede andere erfolgreiche Antwort wird kein Tunnel erstellt.

Nachdem ein erfolgreicher Tunnel hergestellt wurde, MUSS der Server einen einzelnen DATA-Frame (mit gesetztem END_STREAM-Flag) auf dem Tunnel-Stream senden, um den Tunnel sofort zu schließen. Der Client SOLLTE seinen Stream an jedem Endpunkt nach dem Schließen des Tunnels halb schließen und dann seinen Stream schließen, nachdem er das END_STREAM-Flag vom Peer empfangen hat.

Ein TCP-Verbindungsfehler wird von jedem Endpunkt unter Verwendung eines RST_STREAM-Frames mit einem Fehlercode signalisiert. Ein Proxy behandelt jeden Fehlercode, den er empfängt, als Hinweis auf einen Stream-Fehler (Abschnitt 5.4.2), dass er die CONNECT-Anfrage nicht erfolgreich abschließen konnte. Entsprechend sendet ein Proxy, wenn er einen Fehler mit der TCP-Verbindung erkennt, die er für einen CONNECT-Anforderungs-Stream darstellt, ein Signal an den Client auf die gleiche Weise.

8.6. Das Upgrade-Header-Feld

HTTP/2 unterstützt den 101 (Switching Protocols) Informationsstatuscode nicht (Abschnitt 15.2.2 von [HTTP]).

Die Semantik des Upgrade-Header-Felds ist spezifisch für das Protokoll, auf das aktualisiert werden soll. Das Upgrade-Feld in einer direkten Verbindung (Abschnitt 9.1.1) gilt nur für den nächsten Hop. Daher ist das Upgrade-Feld auf HTTP/2 nicht anwendbar.

Eine Implementierung, die auf ein anderes Protokoll auf einer HTTP/2-Verbindung aktualisieren möchte, SOLLTE [ALT-SVC] verwenden.

8.7. Anforderungszuverlässigkeit

Im Allgemeinen kann ein HTTP-Client eine nicht-idempotente Anfrage nicht wiederholen, wenn ein Fehler auftritt, da es keine Möglichkeit gibt, die Natur des Fehlers zu bestimmen. Es ist möglich, dass vor dem Fehler eine Serververarbeitung stattgefunden hat, was zu unerwünschten Effekten führen könnte, wenn die Anfrage erneut versucht würde.

Wenn ein Server einen Anforderungs-Stream ablehnt, ohne eine Anwendungsverarbeitung durchzuführen, kann die Anfrage als sicher anzusehen sein, sie auf einer anderen Verbindung erneut zu versuchen. Ein Server kann dies mit dem Fehlercode REFUSED_STREAM (Abschnitt 7) auf einem RST_STREAM-Frame anzeigen.

Ein Server DARF den Fehlercode REFUSED_STREAM NICHT verwenden, nachdem er eine Anwendungsverarbeitung durchgeführt hat. Dies liegt daran, dass die Verwendung von REFUSED_STREAM anzeigt, dass der Server keine Verarbeitung der Anfrage durchgeführt hat, wodurch es sicher ist, sie erneut zu versuchen. Ein anderer Fehlercode MUSS für Anfragen verwendet werden, die vom Server in irgendeiner Weise verarbeitet wurden.

Clients können Anfragen, die mit REFUSED_STREAM abgelehnt wurden, wiederholen, auch wenn die Anfrage nicht idempotent ist. Wenn der Client sich jedoch entscheidet, eine solche Anfrage erneut zu versuchen, MUSS er annehmen, dass der Server die Anfrage möglicherweise verarbeitet hat, bevor er sie abgelehnt hat. Wenn der Client eine Anfrage wiederholt hat, die nicht idempotent war, SOLLTE er einen Indikator in nachfolgenden Anfragen einfügen, damit der Server eine wiederholte Anfrage erkennen kann.

Eine PUSH_PROMISE-Anfrage, die nicht-cachefähigen Inhalt enthält, ist nicht wiederholbar. Gepushte Anfragen, die nicht cachefähig oder nicht sicher sind, sind nicht erlaubt, wie in Abschnitt 8.4.1 beschrieben.

8.8. Beispiele

Dieser Abschnitt zeigt HTTP/1.1-Anfragen und -Antworten mit Illustrationen äquivalenter HTTP/2-Anfragen und -Antworten. Eine HTTP/2-Anfrage und -Antwort verwenden den komprimierten Header-Abschnitt, der nicht oberhalb der HTTP/2-Frame-Schicht gezeigt wird.

8.8.1. Einfache Anfrage

Eine HTTP/1.1 GET-Anfrage enthält Anfragefelder, eine Methode und ein Anfrageziel.

GET /resource HTTP/1.1
Host: example.org
Accept: image/jpeg

Dieselbe Anfrage wird unter Verwendung von Pseudo-Header-Feldern dargestellt und als Feldabschnitt in HEADERS-Frames in HTTP/2 gesendet:

:method = GET
:scheme = https
:path = /resource
:authority = example.org
accept = image/jpeg

8.8.2. Einfache Antwort

Eine einfache HTTP/1.1-Antwort enthält einen Statuscode, Antwortfelder und Antwortinhalt:

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 123

{binary data}

In HTTP/2 wird der Statuscode unter Verwendung eines Pseudo-Header-Felds dargestellt:

:status = 200
content-type = image/jpeg
content-length = 123

{binary data}

8.8.3. Komplexe Anfrage

Eine HTTP/1.1 POST-Anfrage mit optionalen Feldern:

POST /resource HTTP/1.1
Host: example.org
Content-Type: image/jpeg
Content-Length: 123

{binary data}

Dieselbe HTTP/2-Anfrage:

:method = POST
:scheme = https
:path = /resource
:authority = example.org
content-type = image/jpeg
content-length = 123

{binary data}

8.8.4. Antwort mit Körper

Eine HTTP/1.1-Antwort, einschließlich Felder und Antwortkörper:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 552

<html>
<head>
<title>An Example Page</title>
</head>
<body>
<h1>Example</h1>
<p>This is an example page.</p>
</body>
</html>

In HTTP/2 unter Verwendung eines Feldabschnitts und DATA-Frames:

:status = 200
content-type = text/html; charset=utf-8
content-length = 552

<html>
<head>
<title>An Example Page</title>
</head>
<body>
<h1>Example</h1>
<p>This is an example page.</p>
</body>
</html>

8.8.5. Informative Antworten

HTTP/2 unterstützt informative (1xx) Antworten, die unter Verwendung von HEADERS-Frames gesendet werden, wie in Abschnitt 15 von [HTTP] definiert.

Beispielsweise kann eine 100 (Continue) Antwort vor einer endgültigen Antwort gesendet werden:

:status = 100

:status = 200
content-type = image/jpeg
content-length = 123

{binary data}

Kapitel 8 abgeschlossen!

References

  • [HTTP] RFC 9110
  • [COOKIES] RFC 6265
  • [COMPRESSION] RFC 7541
  • [URI] RFC 3986
  • [TLS13] RFC 8446
  • [ALT-SVC] RFC 7838