8. Expressing HTTP Semantics in HTTP/2 (Ausdruck von HTTP-Semantik in HTTP/2)
HTTP/2 ist darauf ausgelegt, so kompatibel wie möglich mit der aktuellen Verwendung von HTTP zu sein. Dies 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] beibehalten, 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 beschränken sich auf diejenigen, die für eine erfolgreiche Implementierung von HTTP/2 erforderlich sind, die sich auf das HTTP-Wire-Format beziehen oder die ohne zusätzliche Definition in HTTP/2 zu Mehrdeutigkeiten führen würden.
8.1. HTTP Message Framing (HTTP-Nachrichten-Framing)
Eine HTTP-Nachricht (Anfrage oder Antwort) besteht aus:
-
nur für eine Antwort, null oder mehr HEADERS-Frames (jeweils gefolgt von null oder mehr CONTINUATION-Frames), die die Nachrichtenheader informativer (1xx) HTTP-Antworten enthalten (siehe Abschnitt 15 von [HTTP]), und/oder
-
einem HEADERS-Frame (gefolgt von null oder mehr CONTINUATION-Frames), der die Nachrichtenheader enthält (siehe Abschnitt 6.3 von [HTTP]), und
-
null oder mehr DATA-Frames, die den Nachrichteninhalt enthalten (siehe Abschnitt 6.4 von [HTTP]), und
-
optional einem HEADERS-Frame (gefolgt von null oder mehr CONTINUATION-Frames), der den Trailer-Teil-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 einem HEADERS-Frame mit END_STREAM-Flag CONTINUATION-Frames folgen können, die einen verbleibenden Teil des Header-Blocks tragen. Andere Frames (von einem beliebigen Stream) DÜRFEN NICHT zwischen dem HEADERS-Frame und allen möglicherweise folgenden CONTINUATION-Frames auftreten.
HTTP/2 verwendet DATA-Frames zum Transport von Nachrichteninhalten. Die [CHUNKED]-Transfercodierung (definiert in Abschnitt 7.1 von [HTTP]) DARF NICHT mit HTTP/2 verwendet werden.
Trailer-Felder werden in einem Feldabschnitt getragen; siehe Abschnitt 8.2. Es gibt keinen definierten Feldabschnittsnamen für Trailer-Felder, da alle Trailer-Felder in HTTP/2 in denselben Feldabschnitt codiert 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 mit einem ungültigen Feldblock führt zu einem Stream-Fehler (siehe Abschnitt 5.4.2).
8.1.1. Malformed Messages (Fehlerhafte Nachrichten)
Eine fehlerhafte Nachricht ist eine Nachricht, die eine ansonsten gültige Frame-Sequenz 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 darauf abzielen, vor mehreren Arten gängiger Angriffe zu schützen; sie sind bewusst streng, da Nachsicht in fehlerhaften Nachrichtensituationen Implementierungen diesen Schwachstellen aussetzen kann.
8.2. HTTP Fields (HTTP-Felder)
HTTP-Feldnamen und -werte sind Oktettsequenzen und werden mit derselben Kodierung wie in HTTP/1.x verwendet (siehe Abschnitt 5.1 von [HTTP]). Feldnamen MÜSSEN jedoch vor ihrer Kodierung in HTTP/2 in Kleinbuchstaben konvertiert werden. Eine Anfrage oder Antwort, die Großbuchstaben im Feldnamen enthält, MUSS als fehlerhaft behandelt werden (Abschnitt 8.1.1).
HTTP/2 verwendet nicht das Connection-Header-Feld (siehe Abschnitt 7.6.1 von [HTTP]), 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 vom Connection-Feld genannten Felder sowie das Connection-Feld selbst entfernen muss. Solche Vermittler SOLLTEN auch andere verbindungsspezifische Felder wie Keep-Alive, Proxy-Connection, Transfer-Encoding und Upgrade entfernen, auch wenn sie nicht vom Connection-Feld genannt werden.
| Hinweis: HTTP/2 unterstützt absichtlich kein Upgrade auf ein anderes Protokoll. | Die in Abschnitt 3 beschriebenen Handshake-Methoden werden | als ausreichend angesehen, um die Verwendung alternativer Protokolle auszuhandeln.
8.2.1. Field Validity (Feldgültigkeit)
Feldnamen werden gemäß den Regeln in Abschnitt 5.1 von [HTTP] validiert, aber vor der Darstellung in HTTP/2 in Kleinbuchstaben konvertiert.
Ein mit [COMPRESSION] komprimierter Feldabschnitt kann Leerzeichen enthalten, wie durch die Produktion "optional whitespace" (OWS) definiert; Leerzeichen sind nicht Teil des Feldes; sie MÜSSEN während der Dekompression 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 sind in Abschnitt 8.3 angegeben.
8.2.2. Connection-Specific Header Fields (Verbindungsspezifische Header-Felder)
HTTP/2 verwendet nicht das Connection-Header-Feld, 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.
8.2.3. Compressing the Cookie Header Field (Komprimierung des Cookie-Header-Feldes)
Das Cookie-Header-Feld [COOKIES] verwendet ein Semikolon (";"), um Cookie-Paare (oder "Krümel") zu trennen. 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, die jeweils ein oder mehrere Cookie-Paare enthalten. Wenn es nach der Dekompression mehrere Cookie-Header-Felder gibt, MÜSSEN diese vor der Übergabe an einen Nicht-HTTP/2-Kontext, wie eine HTTP/1.1-Verbindung oder eine generische HTTP-Serveranwendung, unter Verwendung des Zwei-Oktett-Trennzeichens 0x3B, 0x20 (die ASCII-Zeichenfolge "; ") zu einer einzelnen Oktettzeichenfolge verkettet 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 Control Data (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 Nachrichtenstartzeile getragen wurden. Pseudo-Header-Felder sind keine HTTP-Felder. Endpunkte DÜRFEN KEINE anderen Pseudo-Header-Felder als die in diesem Dokument definierten generieren.
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-Teil-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-Sets, das 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. Request Pseudo-Header Fields (Anfrage-Pseudo-Header-Felder)
Die folgenden Pseudo-Header-Felder sind für HTTP/2-Anfragen definiert:
-
Das Pseudo-Header-Feld
:methodenthält die HTTP-Methode (Abschnitt 9 von [HTTP]). -
Das Pseudo-Header-Feld
:schemeenthält den Schema-Teil des Ziel-URI (Abschnitt 3.1 von [URI]).Das
:schemeist nicht auf "http"- und "https"-schematisierte URIs beschränkt. Ein Proxy oder Gateway kann Anfragen für Nicht-HTTP-Schemas übersetzen und so die Verwendung von HTTP für die Interaktion mit Nicht-HTTP-Diensten ermöglichen.Siehe Abschnitt 8.5 für die CONNECT-Methode, die das Pseudo-Header-Feld
:schemeauslässt. -
Das Pseudo-Header-Feld
:authorityenthält den Autoritätsteil des Ziel-URI (Abschnitt 3.2 von [URI]). Die Autorität DARF NICHT die veraltete userinfo-Subkomponente für "http"- oder "https"-schematisierte URIs enthalten.Um sicherzustellen, dass die HTTP/1.1-Anforderungszeile genau reproduziert werden kann, MUSS dieses Pseudo-Header-Feld weggelassen werden, wenn von einer HTTP/1.1-Anfrage übersetzt wird, die ein Anfrageziel in Ursprungs- oder Sternform hat (siehe Abschnitt 3.2 von [HTTP]). Clients, die HTTP/2-Anfragen direkt generieren, MÜSSEN das Pseudo-Header-Feld
:authorityanstelle des Host-Feldes verwenden. Ein Vermittler, der eine HTTP/2-Anfrage in HTTP/1.1 konvertiert, MUSS ein Host-Feld erstellen, wenn in einer Anfrage keines vorhanden ist, indem er den Wert des Pseudo-Header-Feldes:authoritykopiert.Ein Server SOLLTE eine Anfrage als fehlerhaft behandeln, wenn sie sowohl das Pseudo-Header-Feld
:authorityals auch das Host-Feld enthält, wenn die Feldwerte nicht identisch sind. -
Das Pseudo-Header-Feld
:pathenthält die Pfad- und Abfrageteile des 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 Sternform enthält den Wert '*' für das Pseudo-Header-Feld:path.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 Sternform gestellt, in diesem Fall MUSS sie einen Wert von '*' enthalten.
Siehe Abschnitt 8.5 für die CONNECT-Methode, die das Pseudo-Header-Feld
:pathauslässt.
Alle HTTP/2-Anfragen MÜSSEN genau einen gültigen Wert für die Pseudo-Header-Felder :method und :scheme enthalten, es sei denn, es handelt sich um eine CONNECT-Anfrage (Abschnitt 8.5).
Wenn das Pseudo-Header-Feld :scheme ein Schema identifiziert, das eine Autorität verwendet (siehe Abschnitt 3.2 von [URI]), dann MUSS eine HTTP/2-Anfrage, die das Anfrageziel nicht enthält, entweder das Feld :authority 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 tragen, die in der HTTP/1.1-Anforderungszeile enthalten ist.
8.3.2. Response Pseudo-Header Fields (Antwort-Pseudo-Header-Felder)
Für HTTP/2-Antworten ist ein einzelnes Pseudo-Header-Feld :status definiert, das das HTTP-Statuscode-Feld 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 den Begründungstext zu tragen, der in einer HTTP/1.1-Statuszeile enthalten ist.
8.4. Server Push (Server-Push)
HTTP/2 ermöglicht es einem Server, Antworten präemptiv (oder "push") an einen Client in Verbindung mit einer vorherigen vom Client initiierten 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 mit einem vollständigen Satz von Anfragefeldern, 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 Einstellung SETTINGS_MAX_CONCURRENT_STREAMS ändert. Das Setzen dieses Wertes auf Null deaktiviert Server-Push, indem verhindert wird, dass der Server die erforderlichen Streams erstellt. Dies hindert einen Server nicht daran, PUSH_PROMISE-Frames zu senden; Clients müssen alle unerwünschten versprochenen Streams zurücksetzen.
8.4.1. Push Requests (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 mit einem vollständigen Satz von Anfragefeldern, 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, in dem die HTTP/2-Verbindung über TLS initiiert wurde (siehe [TLS13]).
Gepushte Anfragen MÜSSEN cachebar 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 cachebar, 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 Pseudo-Header-Feld :authority angeben, 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 erhalten möchte, indem er einen RST_STREAM an den Server sendet, der auf die versprochene Stream-Kennung verweist.
Ein Server SOLLTE nur Antworten pushen, von denen er glaubt, dass der Client sie verwenden wird oder anderweitig davon profitiert. Der Server SOLLTE möglichen Anfrageinhalt, alle Cache-Felder in der Anfrage, die Methode der Anfrage und alle bekannten Inhalte, die vom Client verwaltet werden (basierend beispielsweise auf in früheren Anfragen empfangenen Cookies), bei der Entscheidung, was gepusht werden soll, berücksichtigen.
8.4.2. Push Responses (Push-Antworten)
Nach dem Senden eines PUSH_PROMISE-Frames, der auf den versprochenen Stream verweist, kann der Server mit der Bereitstellung der gepushten Antwort auf einem Stream unter Verwendung der versprochenen Stream-Kennung beginnen. Der Server übermittelt initiale Antwortfelder mit einem HEADERS-Frame unter Verwendung der versprochenen Stream-Kennung. Dieser Stream geht in den Zustand "half-closed (remote)" über (Abschnitt 5.1). Der Server SOLLTE die Antwort senden, die den Push initiiert, bevor er den PUSH_PROMISE-Frame sendet, um eine Wettlaufsituation 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 ausgeben, 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 mit dem Senden der versprochenen Antwort zu beginnen, kann der Client einen RST_STREAM-Frame senden, der entweder den Code CANCEL oder REFUSED_STREAM verwendet und auf die gepushte Stream-Kennung verweist.
Ein Client kann die Einstellung SETTINGS_MAX_CONCURRENT_STREAMS 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-Wertes 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 unerwünschten versprochenen Streams zurücksetzen.
8.5. The CONNECT Method (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-Proxies verwendet, um eine TLS-Sitzung mit einem Ursprungsserver zum Zweck der Interaktion mit "https"-Ressourcen herzustellen.
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 Pseudo-Header-Feld
:methodist auf "CONNECT" gesetzt. - Das Pseudo-Header-Feld
:authorityenthält den Host und Port, zu dem eine Verbindung hergestellt werden soll (entspricht der Autoritätsform des Anfrageziels einer CONNECT-Anfrage; siehe Abschnitt 3.2 von [HTTP]).
Die Pseudo-Header-Felder :scheme und :path 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 zur Übermittlung von HTTP-Anfragen oder -Antworten verwendet. Jede erfolgreiche CONNECT-Antwort wird verwendet, um dem Client mitzuteilen, 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-Anfrage-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 lässt dann die verbleibenden Anfrage-Header-Felder unverändert auf der Verbindung zum Server passieren.
Jede 2xx (Successful)-Antwort, die nach einer CONNECT-Anfrage empfangen wird, zeigt an, dass der Proxy eine Verbindung zum angeforderten Host und Port hergestellt hat und zum Tunneling des entsprechenden Streams gewechselt ist.
Bei jeder anderen erfolgreichen 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 beiden Endpunkten nach dem Schließen des Tunnels halbschließen und dann seinen Stream nach Erhalt des END_STREAM-Flags vom Peer schließen.
Ein TCP-Verbindungsfehler wird von einem der Endpunkte unter Verwendung eines RST_STREAM-Frames mit einem Fehlercode signalisiert. Ein Proxy behandelt jeden empfangenen Fehlercode 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-Anfrage-Stream darstellt, ein Signal an den Client auf dieselbe Weise.
8.6. The Upgrade Header Field (Das Upgrade-Header-Feld)
HTTP/2 unterstützt nicht den informativen Statuscode 101 (Switching Protocols) (Abschnitt 15.2.2 von [HTTP]).
Die Semantik des Upgrade-Header-Feldes ist spezifisch für das Protokoll, auf das aktualisiert wird. Das Upgrade-Feld in einer direkten Verbindung (Abschnitt 9.1.1) gilt nur für den nächsten Hop. Daher ist das Upgrade-Feld nicht auf HTTP/2 anwendbar.
Eine Implementierung, die auf ein anderes Protokoll über eine HTTP/2-Verbindung aktualisieren möchte, SOLLTE [ALT-SVC] verwenden.
8.7. Request Reliability (Anfragezuverlässigkeit)
Im Allgemeinen kann ein HTTP-Client eine nicht-idempotente Anfrage nicht wiederholen, wenn ein Fehler auftritt, da es keine Möglichkeit gibt, die Art 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 wiederholt würde.
Wenn ein Server einen Anfrage-Stream ablehnt, ohne eine Anwendungsverarbeitung durchzuführen, kann die Anfrage als sicher für einen erneuten Versuch auf einer anderen Verbindung angesehen werden. Ein Server kann dies anzeigen, indem er den Fehlercode REFUSED_STREAM (Abschnitt 7) auf einem RST_STREAM-Frame verwendet.
Ein Server DARF NICHT den Fehlercode REFUSED_STREAM verwenden, nachdem er eine Anwendungsverarbeitung durchgeführt hat. Dies liegt daran, dass die Verwendung von REFUSED_STREAM anzeigt, dass der Server keine Verarbeitung für die Anfrage durchgeführt hat, wodurch ein erneuter Versuch sicher ist. Ein anderer Fehlercode MUSS für Anfragen verwendet werden, die vom Server in irgendeiner Weise verarbeitet wurden.
Clients können Anfragen wiederholen, die mit REFUSED_STREAM abgelehnt wurden, auch wenn die Anfrage nicht idempotent ist. Wenn der Client jedoch eine solche Anfrage wiederholt, MUSS er davon ausgehen, 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-cachebare Inhalte enthält, ist nicht wiederholbar. Gepushte Anfragen, die nicht cachebar oder nicht sicher sind, sind nicht zulässig, wie in Abschnitt 8.4.1 beschrieben.
8.8. Examples (Beispiele)
Dieser Abschnitt zeigt HTTP/1.1-Anfragen und -Antworten mit Illustrationen äquivalenter HTTP/2-Anfragen und -Antworten. Eine HTTP/2-Anfrage und -Antwort verwendet den komprimierten Header-Abschnitt, der nicht über der HTTP/2-Frame-Schicht angezeigt wird.
8.8.1. Simple Request (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 mit 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. Simple Response (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 mit einem Pseudo-Header-Feld dargestellt:
:status = 200
content-type = image/jpeg
content-length = 123
{binary data}
8.8.3. Complex Request (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. Response with Body (Antwort mit Körper)
Eine HTTP/1.1-Antwort, einschließlich Felder und einem 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. Informational Responses (Informative Antworten)
HTTP/2 unterstützt informative (1xx) Antworten, die mit HEADERS-Frames gesendet werden, wie in Abschnitt 15 von [HTTP] definiert.
Beispielsweise kann eine 100 (Continue)-Antwort vor einer finalen 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