Zum Hauptinhalt springen

6. Frame Definitions (Frame-Definitionen)

Diese Spezifikation definiert eine Reihe von Frame-Typen, die jeweils durch einen eindeutigen 8-Bit-Typcode identifiziert werden. Jeder Frame-Typ dient einem bestimmten Zweck bei der Einrichtung und Verwaltung der Verbindung als Ganzes oder einzelner Streams.

Die Übertragung bestimmter Frame-Typen kann den Zustand einer Verbindung ändern. Wenn Endpunkte keine synchronisierte Sicht auf den Verbindungszustand aufrechterhalten, ist eine erfolgreiche Kommunikation innerhalb der Verbindung nicht mehr möglich. Daher ist es wichtig, dass Endpunkte ein gemeinsames Verständnis davon haben, wie der Zustand durch die Verwendung eines bestimmten Frames beeinflusst wird.

6.1. DATA

DATA-Frames (type=0x00) übertragen beliebige Oktetsequenzen variabler Länge, die einem Stream zugeordnet sind. Ein oder mehrere DATA-Frames werden beispielsweise verwendet, um HTTP-Anfrage- oder Antwortnachrichteninhalte zu übertragen.

DATA-Frames können auch Padding enthalten. Padding kann zu DATA-Frames hinzugefügt werden, um die Größe von Nachrichten zu verschleiern. Padding ist eine Sicherheitsfunktion; siehe Abschnitt 10.7.

DATA Frame {
Length (24),
Type (8) = 0x00,

Unused Flags (4),
PADDED Flag (1),
Unused Flags (2),
END_STREAM Flag (1),

Reserved (1),
Stream Identifier (31),

[Pad Length (8)],
Data (..),
Padding (..2040),
}

Abbildung 3: DATA-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Der DATA-Frame enthält die folgenden zusätzlichen Felder:

Pad Length (Padding-Länge): Ein 8-Bit-Feld, das die Länge des Frame-Paddings in Oktetteinheiten enthält. Dieses Feld ist bedingt und nur vorhanden, wenn das PADDED-Flag gesetzt ist.

Data (Daten): Anwendungsdaten. Die Datenmenge ist der Rest der Frame-Nutzlast nach Abzug der Länge der anderen vorhandenen Felder.

Padding (Padding): Padding-Oktette, die keinen semantischen Anwendungswert enthalten. Padding-Oktette MÜSSEN beim Senden auf Null gesetzt werden. Ein Empfänger ist nicht verpflichtet, Padding zu überprüfen, KANN jedoch Nicht-Null-Padding als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Der DATA-Frame definiert die folgenden Flags:

PADDED (0x08): Wenn gesetzt, zeigt das PADDED-Flag an, dass das Pad Length-Feld und jedes von ihm beschriebene Padding vorhanden sind.

END_STREAM (0x01): Wenn gesetzt, zeigt das END_STREAM-Flag an, dass dieser Frame der letzte ist, den der Endpunkt für den identifizierten Stream sendet. Das Setzen dieses Flags bewirkt, dass der Stream in einen der "half-closed"-Zustände oder den "closed"-Zustand eintritt (Abschnitt 5.1).

| Hinweis: Ein Endpunkt, der nach dem Senden aller Daten vom Stream-Abschluss erfährt, | kann einen Stream schließen, indem er einen STREAM-Frame mit einem Data-Feld der | Länge Null und gesetztem END_STREAM-Flag sendet. Dies ist nur möglich, wenn der | Endpunkt keine Trailer sendet, da das END_STREAM-Flag in diesem Fall auf einem | HEADERS-Frame erscheint; siehe Abschnitt 8.1.

DATA-Frames MÜSSEN einem Stream zugeordnet sein. Wenn ein DATA-Frame empfangen wird, dessen Stream Identifier-Feld 0x00 ist, MUSS der Empfänger mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

DATA-Frames unterliegen der Flusskontrolle und können nur gesendet werden, wenn sich ein Stream im Zustand "open" oder "half-closed (remote)" befindet. Die gesamte DATA-Frame-Nutzlast ist in der Flusskontrolle enthalten, einschließlich der Felder Pad Length und Padding, falls vorhanden. Wenn ein DATA-Frame empfangen wird, dessen Stream sich nicht im Zustand "open" oder "half-closed (local)" befindet, MUSS der Empfänger mit einem Stream-Fehler (Abschnitt 5.4.2) vom Typ STREAM_CLOSED antworten.

Die Gesamtzahl der Padding-Oktette wird durch den Wert des Pad Length-Feldes bestimmt. Wenn die Länge des Paddings gleich oder größer als die Länge der Frame-Nutzlast ist, MUSS der Empfänger dies als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

| Hinweis: Ein Frame kann um ein Oktett vergrößert werden, indem ein Pad Length-Feld | mit dem Wert Null eingefügt wird.

6.2. HEADERS

Der HEADERS-Frame (type=0x01) wird verwendet, um einen Stream zu öffnen (Abschnitt 5.1), und trägt zusätzlich ein Feldblockfragment. Trotz des Namens kann ein HEADERS-Frame einen Header-Abschnitt oder einen Trailer-Abschnitt tragen. HEADERS-Frames können auf einem Stream in den Zuständen "idle", "reserved (local)", "open" oder "half-closed (remote)" gesendet werden.

HEADERS Frame {
Length (24),
Type (8) = 0x01,

Unused Flags (2),
PRIORITY Flag (1),
Unused Flag (1),
PADDED Flag (1),
END_HEADERS Flag (1),
Unused Flag (1),
END_STREAM Flag (1),

Reserved (1),
Stream Identifier (31),

[Pad Length (8)],
[Exclusive (1)],
[Stream Dependency (31)],
[Weight (8)],
Field Block Fragment (..),
Padding (..2040),
}

Abbildung 4: HEADERS-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Die HEADERS-Frame-Nutzlast hat die folgenden zusätzlichen Felder:

Pad Length (Padding-Länge): Ein 8-Bit-Feld, das die Länge des Frame-Paddings in Oktetteinheiten enthält. Dieses Feld ist nur vorhanden, wenn das PADDED-Flag gesetzt ist.

Exclusive (Exklusiv): Ein Ein-Bit-Flag. Dieses Feld ist nur vorhanden, wenn das PRIORITY-Flag gesetzt ist. Prioritätssignale in HEADERS-Frames sind veraltet; siehe Abschnitt 5.3.2.

Stream Dependency (Stream-Abhängigkeit): Eine 31-Bit-Stream-Kennung. Dieses Feld ist nur vorhanden, wenn das PRIORITY-Flag gesetzt ist.

Weight (Gewicht): Eine vorzeichenlose 8-Bit-Ganzzahl. Dieses Feld ist nur vorhanden, wenn das PRIORITY-Flag gesetzt ist.

Field Block Fragment (Feldblockfragment): Ein Feldblockfragment (Abschnitt 4.3).

Padding (Padding): Padding-Oktette, die keinen semantischen Anwendungswert enthalten. Padding-Oktette MÜSSEN beim Senden auf Null gesetzt werden. Ein Empfänger ist nicht verpflichtet, Padding zu überprüfen, KANN jedoch Nicht-Null-Padding als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Der HEADERS-Frame definiert die folgenden Flags:

PRIORITY (0x20): Wenn gesetzt, zeigt das PRIORITY-Flag an, dass die Felder Exclusive, Stream Dependency und Weight vorhanden sind.

PADDED (0x08): Wenn gesetzt, zeigt das PADDED-Flag an, dass das Pad Length-Feld und jedes von ihm beschriebene Padding vorhanden sind.

END_HEADERS (0x04): Wenn gesetzt, zeigt das END_HEADERS-Flag an, dass dieser Frame einen vollständigen Feldblock (Abschnitt 4.3) enthält und keine CONTINUATION-Frames folgen.

Ein HEADERS-Frame ohne gesetztes END_HEADERS-Flag MUSS von einem CONTINUATION-Frame für denselben Stream gefolgt werden. Ein Empfänger MUSS den Empfang eines anderen Frame-Typs oder eines Frames auf einem anderen Stream als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

END_STREAM (0x01): Wenn gesetzt, zeigt das END_STREAM-Flag an, dass der Feldblock (Abschnitt 4.3) der letzte ist, den der Endpunkt für den identifizierten Stream sendet.

Ein HEADERS-Frame mit gesetztem END_STREAM-Flag signalisiert das Ende eines Streams. Einem HEADERS-Frame mit gesetztem END_STREAM-Flag können jedoch CONTINUATION-Frames auf demselben Stream folgen. Logisch sind die CONTINUATION-Frames Teil des HEADERS-Frames.

Die Frame-Nutzlast eines HEADERS-Frames enthält ein Feldblockfragment (Abschnitt 4.3). Ein Feldblock, der nicht in einen HEADERS-Frame passt, wird in einem CONTINUATION-Frame fortgesetzt (Abschnitt 6.10).

HEADERS-Frames MÜSSEN einem Stream zugeordnet sein. Wenn ein HEADERS-Frame empfangen wird, dessen Stream Identifier-Feld 0x00 ist, MUSS der Empfänger mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

Der HEADERS-Frame ändert den Verbindungszustand wie in Abschnitt 4.3 beschrieben.

Die Gesamtzahl der Padding-Oktette wird durch den Wert des Pad Length-Feldes bestimmt. Wenn die Länge des Paddings gleich oder größer als die Länge der Frame-Nutzlast ist, MUSS der Empfänger dies als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

| Hinweis: Ein Frame kann um ein Oktett vergrößert werden, indem ein Pad Length-Feld | mit dem Wert Null eingefügt wird.

6.3. PRIORITY

Der PRIORITY-Frame (type=0x02) ist veraltet; siehe Abschnitt 5.3.2. Ein PRIORITY-Frame kann in jedem Stream-Zustand gesendet werden, einschließlich idle oder closed Streams.

PRIORITY Frame {
Length (24) = 0x05,
Type (8) = 0x02,

Unused Flags (8),

Reserved (1),
Stream Identifier (31),

Exclusive (1),
Stream Dependency (31),
Weight (8),
}

Abbildung 5: PRIORITY-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Die Frame-Nutzlast eines PRIORITY-Frames enthält die folgenden zusätzlichen Felder:

Exclusive (Exklusiv): Ein Ein-Bit-Flag.

Stream Dependency (Stream-Abhängigkeit): Eine 31-Bit-Stream-Kennung.

Weight (Gewicht): Eine vorzeichenlose 8-Bit-Ganzzahl.

Der PRIORITY-Frame definiert keine Flags.

Der PRIORITY-Frame identifiziert immer einen Stream. Wenn ein PRIORITY-Frame mit einer Stream-Kennung von 0x00 empfangen wird, MUSS der Empfänger mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

Das Senden oder Empfangen eines PRIORITY-Frames beeinflusst nicht den Zustand eines Streams (Abschnitt 5.1). Der PRIORITY-Frame kann auf einem Stream in jedem Zustand gesendet werden, einschließlich "idle" oder "closed". Ein PRIORITY-Frame kann nicht zwischen aufeinanderfolgenden Frames gesendet werden, die einen einzelnen Feldblock bilden (Abschnitt 4.3).

Ein PRIORITY-Frame mit einer anderen Länge als 5 Oktetts MUSS als Stream-Fehler (Abschnitt 5.4.2) vom Typ FRAME_SIZE_ERROR behandelt werden.

6.4. RST_STREAM

Der RST_STREAM-Frame (type=0x03) ermöglicht die sofortige Beendigung eines Streams. RST_STREAM wird gesendet, um die Stornierung eines Streams anzufordern oder um anzuzeigen, dass eine Fehlerbedingung aufgetreten ist.

RST_STREAM Frame {
Length (24) = 0x04,
Type (8) = 0x03,

Unused Flags (8),

Reserved (1),
Stream Identifier (31),

Error Code (32),
}

Abbildung 6: RST_STREAM-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Zusätzlich enthält der RST_STREAM-Frame eine einzelne vorzeichenlose 32-Bit-Ganzzahl, die den Fehlercode identifiziert (Abschnitt 7). Der Fehlercode gibt an, warum der Stream beendet wird.

Der RST_STREAM-Frame definiert keine Flags.

Der RST_STREAM-Frame beendet den referenzierten Stream vollständig und lässt ihn in den "closed"-Zustand übergehen. Nach Erhalt eines RST_STREAM auf einem Stream DARF der Empfänger KEINE zusätzlichen Frames für diesen Stream senden, außer PRIORITY. Nach dem Senden des RST_STREAM MUSS der sendende Endpunkt jedoch darauf vorbereitet sein, zusätzliche auf dem Stream gesendete Frames zu empfangen und zu verarbeiten, die möglicherweise vom Peer vor dem Eintreffen des RST_STREAM gesendet wurden.

RST_STREAM-Frames MÜSSEN einem Stream zugeordnet sein. Wenn ein RST_STREAM-Frame mit einer Stream-Kennung von 0x00 empfangen wird, MUSS der Empfänger dies als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

RST_STREAM-Frames DÜRFEN NICHT für einen Stream im Zustand "idle" gesendet werden. Wenn ein RST_STREAM-Frame empfangen wird, der einen idle-Stream identifiziert, MUSS der Empfänger dies als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Ein RST_STREAM-Frame mit einer anderen Länge als 4 Oktetts MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FRAME_SIZE_ERROR behandelt werden.

6.5. SETTINGS

Der SETTINGS-Frame (type=0x04) übermittelt Konfigurationsparameter, die beeinflussen, wie Endpunkte kommunizieren, wie Präferenzen und Einschränkungen bezüglich des Peer-Verhaltens. Der SETTINGS-Frame wird auch verwendet, um den Empfang dieser Einstellungen zu bestätigen. Einzeln wird ein Konfigurationsparameter aus einem SETTINGS-Frame als "Einstellung" bezeichnet.

Einstellungen werden nicht ausgehandelt; sie beschreiben Eigenschaften des sendenden Peers, die vom empfangenden Peer verwendet werden. Verschiedene Werte für dieselbe Einstellung können von jedem Peer angekündigt werden. Beispielsweise kann ein Client ein hohes anfängliches Flusskontrollfenster festlegen, während ein Server möglicherweise einen niedrigeren Wert festlegt, um Ressourcen zu schonen.

Ein SETTINGS-Frame MUSS von beiden Endpunkten zu Beginn einer Verbindung gesendet werden und KANN jederzeit während der Lebensdauer der Verbindung von beiden Endpunkten gesendet werden. Implementierungen MÜSSEN alle in dieser Spezifikation definierten Einstellungen unterstützen.

Jeder Parameter in einem SETTINGS-Frame ersetzt jeden vorhandenen Wert für diesen Parameter. Einstellungen werden in der Reihenfolge verarbeitet, in der sie erscheinen, und ein Empfänger eines SETTINGS-Frames muss keinen anderen Zustand als den aktuellen Wert jeder Einstellung beibehalten. Daher ist der Wert eines SETTINGS-Parameters der zuletzt gesehene Wert eines Empfängers.

SETTINGS-Frames werden vom empfangenden Peer bestätigt. Um dies zu ermöglichen, definiert der SETTINGS-Frame das ACK-Flag:

ACK (0x01): Wenn gesetzt, zeigt das ACK-Flag an, dass dieser Frame den Empfang und die Anwendung des SETTINGS-Frames des Peers bestätigt. Wenn dieses Bit gesetzt ist, MUSS die Frame-Nutzlast des SETTINGS-Frames leer sein. Der Empfang eines SETTINGS-Frames mit gesetztem ACK-Flag und einem anderen Längenfeldwert als 0 MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FRAME_SIZE_ERROR behandelt werden. Weitere Informationen finden Sie in Abschnitt 6.5.3 ("Einstellungssynchronisation").

SETTINGS-Frames gelten immer für eine Verbindung, niemals für einen einzelnen Stream. Die Stream-Kennung für einen SETTINGS-Frame MUSS Null (0x00) sein. Wenn ein Endpunkt einen SETTINGS-Frame empfängt, dessen Stream Identifier-Feld nicht 0x00 ist, MUSS der Endpunkt mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

Der SETTINGS-Frame beeinflusst den Verbindungszustand. Ein fehlerhaft geformter oder unvollständiger SETTINGS-Frame MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandelt werden.

Ein SETTINGS-Frame mit einer Länge, die kein Vielfaches von 6 Oktetts ist, MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FRAME_SIZE_ERROR behandelt werden.

6.5.1. SETTINGS Format (SETTINGS-Format)

Die Frame-Nutzlast eines SETTINGS-Frames besteht aus null oder mehr Einstellungen, die jeweils aus einer vorzeichenlosen 16-Bit-Einstellungskennung und einem vorzeichenlosen 32-Bit-Wert bestehen.

SETTINGS Frame {
Length (24),
Type (8) = 0x04,

Unused Flags (7),
ACK Flag (1),

Reserved (1),
Stream Identifier (31) = 0,

Setting (48) ...,
}

Setting {
Identifier (16),
Value (32),
}

Abbildung 7: SETTINGS-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Die Frame-Nutzlast eines SETTINGS-Frames enthält eine beliebige Anzahl von Setting-Feldern, die jeweils aus Folgendem bestehen:

Identifier (Kennung): Eine 16-Bit-Einstellungskennung; siehe Abschnitt 6.5.2.

Value (Wert): Ein 32-Bit-Wert für die Einstellung.

6.5.2. Defined Settings (Definierte Einstellungen)

Die folgenden Einstellungen sind definiert:

SETTINGS_HEADER_TABLE_SIZE (0x01): Diese Einstellung ermöglicht es dem Sender, den entfernten Endpunkt über die maximale Größe der Komprimierungstabelle zu informieren, die zum Dekodieren von Feldblöcken verwendet wird, in Oktetteinheiten. Der Encoder kann jede Größe auswählen, die gleich oder kleiner als dieser Wert ist, indem er eine für das Komprimierungsformat spezifische Signalisierung innerhalb eines Feldblocks verwendet (siehe [COMPRESSION]). Der Anfangswert beträgt 4.096 Oktetts.

SETTINGS_ENABLE_PUSH (0x02): Diese Einstellung kann verwendet werden, um Server-Push zu aktivieren oder zu deaktivieren. Ein Server DARF KEINEN PUSH_PROMISE-Frame senden, wenn er diesen auf einen Wert von 0 gesetzten Parameter empfängt; siehe Abschnitt 8.4. Ein Client, der diesen Parameter auf 0 gesetzt und bestätigt hat, MUSS den Empfang eines PUSH_PROMISE-Frames als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Der Anfangswert von SETTINGS_ENABLE_PUSH ist 1. Für einen Client zeigt dieser Wert an, dass er bereit ist, PUSH_PROMISE-Frames zu empfangen. Für einen Server hat dieser Anfangswert keine Wirkung und entspricht dem Wert 0. Jeder andere Wert als 0 oder 1 MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandelt werden.

Ein Server DARF diesen Wert NICHT explizit auf 1 setzen. Ein Server KANN wählen, diese Einstellung beim Senden eines SETTINGS-Frames wegzulassen, aber wenn ein Server einen Wert einschließt, MUSS er 0 sein. Ein Client MUSS den Empfang eines SETTINGS-Frames mit auf 1 gesetztem SETTINGS_ENABLE_PUSH als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

SETTINGS_MAX_CONCURRENT_STREAMS (0x03): Diese Einstellung gibt die maximale Anzahl gleichzeitiger Streams an, die der Sender zulässt. Diese Grenze ist richtungsabhängig: Sie gilt für die Anzahl der Streams, die der Sender dem Empfänger zu erstellen erlaubt. Anfänglich gibt es keine Begrenzung für diesen Wert. Es wird empfohlen, dass dieser Wert nicht kleiner als 100 ist, um die Parallelität nicht unnötig einzuschränken.

Ein Wert von 0 für SETTINGS_MAX_CONCURRENT_STREAMS SOLLTE von Endpunkten NICHT als besonders behandelt werden. Ein Nullwert verhindert die Erstellung neuer Streams; dies kann jedoch auch bei jeder Grenze auftreten, die mit aktiven Streams erschöpft ist. Server SOLLTEN nur für kurze Zeiträume einen Nullwert festlegen; wenn ein Server keine Anfragen akzeptieren möchte, ist das Schließen der Verbindung angemessener.

SETTINGS_INITIAL_WINDOW_SIZE (0x04): Diese Einstellung gibt die anfängliche Fenstergröße des Senders (in Oktetteinheiten) für die Flusskontrolle auf Stream-Ebene an. Der Anfangswert beträgt 2^16-1 (65.535) Oktetts.

Diese Einstellung beeinflusst die Fenstergröße aller Streams (siehe Abschnitt 6.9.2).

Werte über der maximalen Flusskontrollfenstergröße von 2^31-1 MÜSSEN als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FLOW_CONTROL_ERROR behandelt werden.

SETTINGS_MAX_FRAME_SIZE (0x05): Diese Einstellung gibt die Größe der größten Frame-Nutzlast an, die der Sender zu empfangen bereit ist, in Oktetteinheiten.

Der Anfangswert beträgt 2^14 (16.384) Oktetts. Der von einem Endpunkt angekündigte Wert MUSS zwischen diesem Anfangswert und der maximal zulässigen Frame-Größe (2^24-1 oder 16.777.215 Oktetts) liegen, einschließlich. Werte außerhalb dieses Bereichs MÜSSEN als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandelt werden.

SETTINGS_MAX_HEADER_LIST_SIZE (0x06): Diese beratende Einstellung informiert einen Peer über die maximale Feldabschnittsgröße, die der Sender zu akzeptieren bereit ist, in Oktetteinheiten. Der Wert basiert auf der unkomprimierten Größe von Feldzeilen, einschließlich der Länge von Name und Wert in Oktetteinheiten plus einem Overhead von 32 Oktetts pro Feldzeile.

Für eine gegebene Anforderung KANN eine niedrigere Grenze als angekündigt durchgesetzt werden. Der Anfangswert dieser Einstellung ist unbegrenzt.

Ein Endpunkt, der einen SETTINGS-Frame mit einer unbekannten oder nicht unterstützten Kennung empfängt, MUSS diese Einstellung ignorieren.

6.5.3. Settings Synchronization (Einstellungssynchronisation)

Die meisten Werte in SETTINGS profitieren von oder erfordern ein Verständnis dafür, wann der Peer die geänderten Parameterwerte empfangen und angewendet hat. Um solche Synchronisationszeitpunkte bereitzustellen, MUSS der Empfänger eines SETTINGS-Frames, in dem das ACK-Flag nicht gesetzt ist, die aktualisierten Einstellungen so schnell wie möglich nach Empfang anwenden. SETTINGS-Frames werden in der Reihenfolge bestätigt, in der sie empfangen werden.

Die Werte im SETTINGS-Frame MÜSSEN in der Reihenfolge verarbeitet werden, in der sie erscheinen, ohne andere Frame-Verarbeitung zwischen den Werten. Nicht unterstützte Einstellungen MÜSSEN ignoriert werden. Sobald alle Werte verarbeitet wurden, MUSS der Empfänger sofort einen SETTINGS-Frame mit gesetztem ACK-Flag ausgeben. Nach Erhalt eines SETTINGS-Frames mit gesetztem ACK-Flag kann sich der Sender der geänderten Einstellungen darauf verlassen, dass die Werte aus dem ältesten unbestätigten SETTINGS-Frame angewendet wurden.

Wenn der Sender eines SETTINGS-Frames innerhalb einer angemessenen Zeit keine Bestätigung erhält, KANN er einen Verbindungsfehler (Abschnitt 5.4.1) vom Typ SETTINGS_TIMEOUT ausgeben. Beim Festlegen eines Timeouts muss ein gewisser Spielraum für Verarbeitungsverzögerungen beim Peer berücksichtigt werden; ein Timeout, das ausschließlich auf der Round-Trip-Zeit zwischen Endpunkten basiert, könnte zu Scheinfehlern führen.

6.6. PUSH_PROMISE

Der PUSH_PROMISE-Frame (type=0x05) wird verwendet, um den Peer-Endpunkt im Voraus über Streams zu informieren, die der Sender zu initiieren beabsichtigt. Der PUSH_PROMISE-Frame enthält die vorzeichenlose 31-Bit-Kennung des Streams, den der Endpunkt zu erstellen plant, zusammen mit einem Feldabschnitt, der zusätzlichen Kontext für den Stream bereitstellt. Abschnitt 8.4 enthält eine gründliche Beschreibung der Verwendung von PUSH_PROMISE-Frames.

PUSH_PROMISE Frame {
Length (24),
Type (8) = 0x05,

Unused Flags (4),
PADDED Flag (1),
END_HEADERS Flag (1),
Unused Flags (2),

Reserved (1),
Stream Identifier (31),

[Pad Length (8)],
Reserved (1),
Promised Stream ID (31),
Field Block Fragment (..),
Padding (..2040),
}

Abbildung 8: PUSH_PROMISE-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Die PUSH_PROMISE-Frame-Nutzlast hat die folgenden zusätzlichen Felder:

Pad Length (Padding-Länge): Ein 8-Bit-Feld, das die Länge des Frame-Paddings in Oktetteinheiten enthält. Dieses Feld ist nur vorhanden, wenn das PADDED-Flag gesetzt ist.

Promised Stream ID (Versprochene Stream-ID): Eine vorzeichenlose 31-Bit-Ganzzahl, die den durch PUSH_PROMISE reservierten Stream identifiziert. Die versprochene Stream-Kennung MUSS eine gültige Wahl für den nächsten vom Sender gesendeten Stream sein (siehe "neue Stream-Kennung" in Abschnitt 5.1.1).

Field Block Fragment (Feldblockfragment): Ein Feldblockfragment (Abschnitt 4.3), das die Anforderungskontrolldaten und einen Header-Abschnitt enthält.

Padding (Padding): Padding-Oktette, die keinen semantischen Anwendungswert enthalten. Padding-Oktette MÜSSEN beim Senden auf Null gesetzt werden. Ein Empfänger ist nicht verpflichtet, Padding zu überprüfen, KANN jedoch Nicht-Null-Padding als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Der PUSH_PROMISE-Frame definiert die folgenden Flags:

PADDED (0x08): Wenn gesetzt, zeigt das PADDED-Flag an, dass das Pad Length-Feld und jedes von ihm beschriebene Padding vorhanden sind.

END_HEADERS (0x04): Wenn gesetzt, zeigt das END_HEADERS-Flag an, dass dieser Frame einen vollständigen Feldblock (Abschnitt 4.3) enthält und keine CONTINUATION-Frames folgen.

Ein PUSH_PROMISE-Frame ohne gesetztes END_HEADERS-Flag MUSS von einem CONTINUATION-Frame für denselben Stream gefolgt werden. Ein Empfänger MUSS den Empfang eines anderen Frame-Typs oder eines Frames auf einem anderen Stream als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

PUSH_PROMISE-Frames DÜRFEN nur auf einem vom Peer initiierten Stream gesendet werden, der sich entweder im Zustand "open" oder "half-closed (remote)" befindet. Die Stream-Kennung eines PUSH_PROMISE-Frames gibt den Stream an, dem er zugeordnet ist. Wenn das Stream Identifier-Feld den Wert 0x00 angibt, MUSS ein Empfänger mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

Versprochene Streams müssen nicht in der Reihenfolge verwendet werden, in der sie versprochen wurden. PUSH_PROMISE reserviert nur Stream-Kennungen für eine spätere Verwendung.

PUSH_PROMISE DARF NICHT gesendet werden, wenn die SETTINGS_ENABLE_PUSH-Einstellung des Peer-Endpunkts auf 0 gesetzt ist. Ein Endpunkt, der diese Einstellung gesetzt und eine Bestätigung erhalten hat, MUSS den Empfang eines PUSH_PROMISE-Frames als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Empfänger von PUSH_PROMISE-Frames können versprochene Streams ablehnen, indem sie einen RST_STREAM zurücksenden, der die versprochene Stream-Kennung an den Sender des PUSH_PROMISE referenziert.

Ein PUSH_PROMISE-Frame ändert den Verbindungszustand auf zwei Arten. Erstens ändert die Aufnahme eines Feldblocks (Abschnitt 4.3) möglicherweise den für die Feldabschnittskomprimierung beibehaltenen Zustand. Zweitens reserviert PUSH_PROMISE auch einen Stream für eine spätere Verwendung, wodurch der versprochene Stream in den Zustand "reserved (local)" oder "reserved (remote)" übergeht. Ein Sender DARF KEINEN PUSH_PROMISE auf einem Stream senden, es sei denn, dieser Stream ist entweder "open" oder "half-closed (remote)"; der Sender MUSS sicherstellen, dass der versprochene Stream eine gültige Wahl für eine neue Stream-Kennung ist (Abschnitt 5.1.1) (d.h. der versprochene Stream MUSS sich im Zustand "idle" befinden).

Da PUSH_PROMISE einen Stream reserviert, führt das Ignorieren eines PUSH_PROMISE-Frames dazu, dass der Stream-Zustand unbestimmt wird. Ein Empfänger MUSS den Empfang eines PUSH_PROMISE auf einem Stream, der weder "open" noch "half-closed (local)" ist, als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln. Ein Endpunkt, das RST_STREAM auf dem zugehörigen Stream gesendet hat, MUSS jedoch PUSH_PROMISE-Frames verarbeiten, die möglicherweise erstellt wurden, bevor der RST_STREAM-Frame empfangen und verarbeitet wurde.

Ein Empfänger MUSS den Empfang eines PUSH_PROMISE, der eine illegale Stream-Kennung verspricht (Abschnitt 5.1.1), als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln. Beachten Sie, dass eine illegale Stream-Kennung eine Kennung für einen Stream ist, der sich derzeit nicht im Zustand "idle" befindet.

Die Gesamtzahl der Padding-Oktette wird durch den Wert des Pad Length-Feldes bestimmt. Wenn die Länge des Paddings gleich oder größer als die Länge der Frame-Nutzlast ist, MUSS der Empfänger dies als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

| Hinweis: Ein Frame kann um ein Oktett vergrößert werden, indem ein Pad Length-Feld | mit dem Wert Null eingefügt wird.

6.7. PING

Der PING-Frame (type=0x06) ist ein Mechanismus zum Messen einer minimalen Round-Trip-Zeit vom Sender sowie zum Bestimmen, ob eine inaktive Verbindung noch funktionsfähig ist. PING-Frames können von jedem Endpunkt gesendet werden.

PING Frame {
Length (24) = 0x08,
Type (8) = 0x06,

Unused Flags (7),
ACK Flag (1),

Reserved (1),
Stream Identifier (31) = 0,

Opaque Data (64),
}

Abbildung 9: PING-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben.

Zusätzlich zum Frame-Header MÜSSEN PING-Frames 8 Oktetts opake Daten in der Frame-Nutzlast enthalten. Ein Sender kann jeden beliebigen Wert einschließen und diese Oktetts auf beliebige Weise verwenden.

Empfänger eines PING-Frames, der kein ACK-Flag enthält, MÜSSEN als Antwort einen PING-Frame mit gesetztem ACK-Flag und identischer Frame-Nutzlast senden. PING-Antworten SOLLTEN eine höhere Priorität als jeder andere Frame erhalten.

Der PING-Frame definiert das folgende Flag:

ACK (0x01): Wenn gesetzt, zeigt das ACK-Flag an, dass dieser PING-Frame eine PING-Antwort ist. Ein Endpunkt MUSS dieses Flag in PING-Antworten setzen. Ein Endpunkt DARF NICHT auf PING-Frames antworten, die dieses Flag enthalten.

PING-Frames sind keinem einzelnen Stream zugeordnet. Wenn ein PING-Frame mit einem anderen Stream Identifier-Feldwert als 0x00 empfangen wird, MUSS der Empfänger mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

Der Empfang eines PING-Frames mit einem anderen Längenfeldwert als 8 MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FRAME_SIZE_ERROR behandelt werden.

6.8. GOAWAY

Der GOAWAY-Frame (type=0x07) wird verwendet, um das Herunterfahren einer Verbindung zu initiieren oder schwerwiegende Fehlerbedingungen zu signalisieren. GOAWAY ermöglicht es einem Endpunkt, das Akzeptieren neuer Streams ordnungsgemäß zu beenden, während die Verarbeitung zuvor etablierter Streams fortgesetzt wird. Dies ermöglicht administrative Aktionen wie Serverwartung.

Es gibt eine inhärente Race-Condition zwischen einem Endpunkt, der neue Streams startet, und dem entfernten Peer, der einen GOAWAY-Frame sendet. Um mit diesem Fall umzugehen, enthält der GOAWAY die Stream-Kennung des letzten vom Peer initiierten Streams, der auf dem sendenden Endpunkt in dieser Verbindung verarbeitet wurde oder möglicherweise verarbeitet wird. Wenn beispielsweise der Server einen GOAWAY-Frame sendet, ist der identifizierte Stream der Stream mit der höchsten Nummer, der vom Client initiiert wurde.

Sobald der GOAWAY gesendet wurde, ignoriert der Sender auf Streams gesendete Frames, die vom Empfänger initiiert wurden, wenn der Stream eine höhere Kennung als die enthaltene letzte Stream-Kennung hat. Empfänger eines GOAWAY-Frames DÜRFEN KEINE zusätzlichen Streams auf der Verbindung öffnen, obwohl eine neue Verbindung für neue Streams etabliert werden kann.

Wenn der Empfänger des GOAWAY Daten auf Streams mit einer höheren Stream-Kennung gesendet hat, als im GOAWAY-Frame angegeben ist, werden diese Streams nicht oder werden nicht verarbeitet. Der Empfänger des GOAWAY-Frames kann die Streams so behandeln, als wären sie nie erstellt worden, wodurch diese Streams später auf einer neuen Verbindung wiederholt werden können.

Endpunkte SOLLTEN immer einen GOAWAY-Frame senden, bevor sie eine Verbindung schließen, damit der entfernte Peer wissen kann, ob ein Stream teilweise verarbeitet wurde oder nicht. Wenn beispielsweise ein HTTP-Client ein POST sendet, während ein Server gleichzeitig eine Verbindung schließt, kann der Client nicht wissen, ob der Server mit der Verarbeitung dieser POST-Anfrage begonnen hat, wenn der Server keinen GOAWAY-Frame sendet, um anzugeben, auf welche Streams er möglicherweise eingewirkt hat.

Ein Endpunkt kann wählen, eine Verbindung ohne Senden eines GOAWAY für sich fehlverhaltende Peers zu schließen.

Ein GOAWAY-Frame muss möglicherweise nicht unmittelbar vor dem Schließen der Verbindung stehen; ein Empfänger eines GOAWAY, der keine weitere Verwendung für die Verbindung hat, SOLLTE dennoch einen GOAWAY-Frame senden, bevor er die Verbindung beendet.

GOAWAY Frame {
Length (24),
Type (8) = 0x07,

Unused Flags (8),

Reserved (1),
Stream Identifier (31) = 0,

Reserved (1),
Last-Stream-ID (31),
Error Code (32),
Additional Debug Data (..),
}

Abbildung 10: GOAWAY-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben.

Der GOAWAY-Frame definiert keine Flags.

Der GOAWAY-Frame gilt für die Verbindung, nicht für einen bestimmten Stream. Ein Endpunkt MUSS einen GOAWAY-Frame mit einer anderen Stream-Kennung als 0x00 als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Die letzte Stream-Kennung im GOAWAY-Frame enthält die Stream-Kennung mit der höchsten Nummer, für die der Sender des GOAWAY-Frames möglicherweise eine Aktion vorgenommen hat oder noch vornehmen könnte. Alle Streams bis einschließlich des identifizierten Streams könnten auf irgendeine Weise verarbeitet worden sein. Die letzte Stream-Kennung kann auf 0 gesetzt werden, wenn keine Streams verarbeitet wurden.

| Hinweis: In diesem Kontext bedeutet "verarbeitet", dass einige Daten aus dem Stream an | eine höhere Softwareschicht weitergegeben wurden, die möglicherweise als Ergebnis eine | Aktion ausgeführt hat.

Wenn eine Verbindung ohne GOAWAY-Frame beendet wird, ist die letzte Stream-Kennung effektiv die höchstmögliche Stream-Kennung.

Bei Streams mit niedrigeren oder gleichen nummerierten Kennungen, die vor dem Schließen der Verbindung nicht vollständig geschlossen wurden, ist ein erneuter Versuch von Anforderungen, Transaktionen oder jeglicher Protokollaktivität nicht möglich, außer für idempotente Aktionen wie HTTP GET, PUT oder DELETE. Jede Protokollaktivität, die höher nummerierte Streams verwendet, kann sicher mit einer neuen Verbindung wiederholt werden.

Die Aktivität auf Streams mit Nummern kleiner oder gleich der letzten Stream-Kennung kann noch erfolgreich abgeschlossen werden. Der Sender eines GOAWAY-Frames kann eine Verbindung ordnungsgemäß herunterfahren, indem er einen GOAWAY-Frame sendet und die Verbindung in einem "open"-Zustand beibehält, bis alle laufenden Streams abgeschlossen sind.

Ein Endpunkt KANN mehrere GOAWAY-Frames senden, wenn sich die Umstände ändern. Beispielsweise kann ein Endpunkt, das während eines ordnungsgemäßen Herunterfahrens GOAWAY mit NO_ERROR sendet, anschließend auf eine Bedingung stoßen, die eine sofortige Beendigung der Verbindung erfordert. Die letzte Stream-Kennung aus dem zuletzt empfangenen GOAWAY-Frame gibt an, auf welche Streams möglicherweise eingewirkt wurde. Endpunkte DÜRFEN den Wert, den sie in der letzten Stream-Kennung senden, NICHT erhöhen, da die Peers möglicherweise bereits nicht verarbeitete Anforderungen auf einer anderen Verbindung wiederholt haben.

Ein Client, der Anforderungen nicht wiederholen kann, verliert alle Anforderungen, die während des Schließens der Verbindung durch den Server übertragen werden. Dies gilt insbesondere für Vermittler, die Clients möglicherweise nicht mit HTTP/2 bedienen. Ein Server, der versucht, eine Verbindung ordnungsgemäß herunterzufahren, SOLLTE einen initialen GOAWAY-Frame mit der auf 2^31-1 gesetzten letzten Stream-Kennung und einem NO_ERROR-Code senden. Dies signalisiert dem Client, dass ein Herunterfahren bevorsteht und dass die Initiierung weiterer Anforderungen untersagt ist. Nach Zulassen der Zeit für jede laufende Stream-Erstellung (mindestens eine Round-Trip-Zeit) KANN der Server einen weiteren GOAWAY-Frame mit einer aktualisierten letzten Stream-Kennung senden. Dies stellt sicher, dass eine Verbindung ordnungsgemäß heruntergefahren werden kann, ohne Anforderungen zu verlieren.

Nach dem Senden eines GOAWAY-Frames kann der Sender Frames für Streams verwerfen, die vom Empfänger mit höheren Kennungen als dem identifizierten letzten Stream initiiert wurden. Alle Frames, die den Verbindungszustand ändern, können jedoch nicht vollständig ignoriert werden. Beispielsweise MÜSSEN HEADERS-, PUSH_PROMISE- und CONTINUATION-Frames minimal verarbeitet werden, um sicherzustellen, dass der für die Feldabschnittskomprimierung beibehaltene Zustand konsistent ist (siehe Abschnitt 4.3); ebenso MÜSSEN DATA-Frames auf das Verbindungs-Flusskontrollfenster angerechnet werden. Das Versäumnis, diese Frames zu verarbeiten, kann dazu führen, dass die Flusskontrolle oder der Feldabschnittskomprimierungszustand nicht synchronisiert wird.

Der GOAWAY-Frame enthält auch einen 32-Bit-Fehlercode (Abschnitt 7), der den Grund für das Schließen der Verbindung enthält.

Endpunkte KÖNNEN opake Daten an die Frame-Nutzlast jedes GOAWAY-Frames anhängen. Zusätzliche Debug-Daten sind nur für Diagnosezwecke bestimmt und tragen keinen semantischen Wert. Debug-Informationen könnten sicherheits- oder datenschutzsensible Daten enthalten. Protokollierte oder anderweitig dauerhaft gespeicherte Debug-Daten MÜSSEN angemessene Schutzmaßnahmen haben, um unbefugten Zugriff zu verhindern.

6.9. WINDOW_UPDATE

Der WINDOW_UPDATE-Frame (type=0x08) wird zur Implementierung der Flusskontrolle verwendet; siehe Abschnitt 5.2 für einen Überblick.

Die Flusskontrolle operiert auf zwei Ebenen: auf jedem einzelnen Stream und auf der gesamten Verbindung.

Beide Arten der Flusskontrolle sind Hop-by-Hop, d.h. nur zwischen den beiden Endpunkten. Vermittler leiten WINDOW_UPDATE-Frames nicht zwischen abhängigen Verbindungen weiter. Eine Drosselung der Datenübertragung durch einen Empfänger kann jedoch indirekt die Weitergabe von Flusskontrollinformationen zum ursprünglichen Sender verursachen.

Die Flusskontrolle gilt nur für Frames, die als der Flusskontrolle unterliegend identifiziert sind. Von den in diesem Dokument definierten Frame-Typen umfasst dies nur DATA-Frames. Frames, die von der Flusskontrolle ausgenommen sind, MÜSSEN akzeptiert und verarbeitet werden, es sei denn, der Empfänger ist nicht in der Lage, Ressourcen zur Verarbeitung des Frames zuzuweisen. Ein Empfänger KANN mit einem Stream-Fehler (Abschnitt 5.4.2) oder Verbindungsfehler (Abschnitt 5.4.1) vom Typ FLOW_CONTROL_ERROR antworten, wenn er nicht in der Lage ist, einen Frame zu akzeptieren.

WINDOW_UPDATE Frame {
Length (24) = 0x04,
Type (8) = 0x08,

Unused Flags (8),

Reserved (1),
Stream Identifier (31),

Reserved (1),
Window Size Increment (31),
}

Abbildung 11: WINDOW_UPDATE-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Die Frame-Nutzlast eines WINDOW_UPDATE-Frames ist ein reserviertes Bit plus eine vorzeichenlose 31-Bit-Ganzzahl, die die Anzahl der Oktetts angibt, die der Sender zusätzlich zum vorhandenen Flusskontrollfenster übertragen kann. Der zulässige Bereich für das Inkrement des Flusskontrollfensters beträgt 1 bis 2^31-1 (2.147.483.647) Oktetts.

Der WINDOW_UPDATE-Frame definiert keine Flags.

Der WINDOW_UPDATE-Frame kann spezifisch für einen Stream oder für die gesamte Verbindung sein. Im ersteren Fall gibt die Stream-Kennung des Frames den betroffenen Stream an; im letzteren Fall gibt der Wert "0" an, dass die gesamte Verbindung das Subjekt des Frames ist.

Ein Empfänger MUSS den Empfang eines WINDOW_UPDATE-Frames mit einem Flusskontrollfensterinkrement von 0 als Stream-Fehler (Abschnitt 5.4.2) vom Typ PROTOCOL_ERROR behandeln; Fehler im Verbindungs-Flusskontrollfenster MÜSSEN als Verbindungsfehler (Abschnitt 5.4.1) behandelt werden.

WINDOW_UPDATE kann von einem Peer gesendet werden, der einen Frame mit gesetztem END_STREAM-Flag gesendet hat. Dies bedeutet, dass ein Empfänger einen WINDOW_UPDATE-Frame auf einem Stream im Zustand "half-closed (remote)" oder "closed" empfangen könnte. Ein Empfänger DARF dies NICHT als Fehler behandeln (siehe Abschnitt 5.1).

Ein Empfänger, der einen flusskontrollierten Frame empfängt, MUSS immer seinen Beitrag zum Verbindungs-Flusskontrollfenster berücksichtigen, es sei denn, der Empfänger behandelt dies als Verbindungsfehler (Abschnitt 5.4.1). Dies ist auch dann erforderlich, wenn der Frame fehlerhaft ist. Der Sender zählt den Frame zum Flusskontrollfenster, aber wenn der Empfänger dies nicht tut, können das Flusskontrollfenster beim Sender und beim Empfänger unterschiedlich werden.

Ein WINDOW_UPDATE-Frame mit einer anderen Länge als 4 Oktetts MUSS als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FRAME_SIZE_ERROR behandelt werden.

6.9.1. The Flow-Control Window (Das Flusskontrollfenster)

Die Flusskontrolle in HTTP/2 wird mithilfe eines Fensters implementiert, das von jedem Sender auf jedem Stream beibehalten wird. Das Flusskontrollfenster ist ein einfacher ganzzahliger Wert, der angibt, wie viele Oktetts an Daten der Sender übertragen darf; als solches ist seine Größe ein Maß für die Pufferkapazität des Empfängers.

Zwei Flusskontrollfenster sind anwendbar: das Stream-Flusskontrollfenster und das Verbindungs-Flusskontrollfenster. Der Sender DARF KEINEN flusskontrollierten Frame mit einer Länge senden, die den verfügbaren Platz in einem der vom Empfänger angekündigten Flusskontrollfenster überschreitet. Frames mit Nulllänge und gesetztem END_STREAM-Flag (d.h. ein leerer DATA-Frame) KÖNNEN gesendet werden, wenn in keinem der Flusskontrollfenster verfügbarer Platz vorhanden ist.

Für Flusskontrollberechnungen wird der 9-Oktett-Frame-Header nicht gezählt.

Nach dem Senden eines flusskontrollierten Frames reduziert der Sender den verfügbaren Platz in beiden Fenstern um die Länge des übertragenen Frames.

Der Empfänger eines Frames sendet einen WINDOW_UPDATE-Frame, während er Daten konsumiert und Platz in Flusskontrollfenstern freigibt. Separate WINDOW_UPDATE-Frames werden für die Stream- und Verbindungsebenen-Flusskontrollfenster gesendet. Empfängern wird empfohlen, Mechanismen zu haben, um das Senden von WINDOW_UPDATE-Frames mit sehr kleinen Inkrementen zu vermeiden; siehe Abschnitt 4.2.3.3 von [RFC1122].

Ein Sender, der einen WINDOW_UPDATE-Frame empfängt, aktualisiert das entsprechende Fenster um den im Frame angegebenen Betrag.

Ein Sender DARF NICHT zulassen, dass ein Flusskontrollfenster 2^31-1 Oktetts überschreitet. Wenn ein Sender einen WINDOW_UPDATE empfängt, der ein Flusskontrollfenster veranlasst, dieses Maximum zu überschreiten, MUSS er entweder den Stream oder die Verbindung beenden, je nachdem, was angemessen ist. Für Streams sendet der Sender einen RST_STREAM mit einem Fehlercode von FLOW_CONTROL_ERROR; für die Verbindung wird ein GOAWAY-Frame mit einem Fehlercode von FLOW_CONTROL_ERROR gesendet.

Flusskontrollierte Frames vom Sender und WINDOW_UPDATE-Frames vom Empfänger sind in Bezug aufeinander vollständig asynchron. Diese Eigenschaft ermöglicht es einem Empfänger, die vom Sender beibehaltene Fenstergröße aggressiv zu aktualisieren, um zu verhindern, dass Streams ins Stocken geraten.

6.9.2. Initial Flow-Control Window Size (Anfängliche Flusskontrollfenstergröße)

Wenn eine HTTP/2-Verbindung zum ersten Mal hergestellt wird, werden neue Streams mit einer anfänglichen Flusskontrollfenstergröße von 65.535 Oktetts erstellt. Das Verbindungs-Flusskontrollfenster beträgt ebenfalls 65.535 Oktetts. Beide Endpunkte können die anfängliche Fenstergröße für neue Streams anpassen, indem sie einen Wert für SETTINGS_INITIAL_WINDOW_SIZE in den SETTINGS-Frame aufnehmen. Das Verbindungs-Flusskontrollfenster kann nur mithilfe von WINDOW_UPDATE-Frames geändert werden.

Vor dem Empfang eines SETTINGS-Frames, der einen Wert für SETTINGS_INITIAL_WINDOW_SIZE festlegt, kann ein Endpunkt nur die standardmäßige anfängliche Fenstergröße verwenden, wenn es flusskontrollierte Frames sendet. Ebenso wird das Verbindungs-Flusskontrollfenster basierend auf der standardmäßigen anfänglichen Fenstergröße festgelegt, bis ein WINDOW_UPDATE-Frame empfangen wird.

Zusätzlich zum Ändern des Flusskontrollfensters für Streams, die noch nicht aktiv sind, kann ein SETTINGS-Frame die anfängliche Flusskontrollfenstergröße für Streams mit aktiven Flusskontrollfenstern ändern (d.h. Streams im Zustand "open" oder "half-closed (remote)"). Wenn sich der Wert von SETTINGS_INITIAL_WINDOW_SIZE ändert, MUSS ein Empfänger die Größe aller Stream-Flusskontrollfenster, die er beibehält, um die Differenz zwischen dem neuen Wert und dem alten Wert anpassen.

Eine Änderung von SETTINGS_INITIAL_WINDOW_SIZE kann dazu führen, dass der verfügbare Platz in einem Flusskontrollfenster negativ wird. Ein Sender MUSS das negative Flusskontrollfenster verfolgen und DARF KEINE neuen flusskontrollierten Frames senden, bis er WINDOW_UPDATE-Frames empfängt, die das Flusskontrollfenster positiv machen.

Wenn beispielsweise der Client bei der Verbindungsherstellung sofort 60 KB sendet und der Server die anfängliche Fenstergröße auf 16 KB setzt, berechnet der Client beim Empfang des SETTINGS-Frames das verfügbare Flusskontrollfenster auf -44 KB neu. Der Client behält ein negatives Flusskontrollfenster bei, bis WINDOW_UPDATE-Frames das Fenster wieder positiv machen, woraufhin der Client das Senden fortsetzen kann.

Ein SETTINGS-Frame kann das Verbindungs-Flusskontrollfenster nicht ändern.

Ein Endpunkt MUSS eine Änderung von SETTINGS_INITIAL_WINDOW_SIZE, die ein Flusskontrollfenster veranlasst, die maximale Größe zu überschreiten, als Verbindungsfehler (Abschnitt 5.4.1) vom Typ FLOW_CONTROL_ERROR behandeln.

6.9.3. Reducing the Stream Window Size (Reduzierung der Stream-Fenstergröße)

Ein Empfänger, der ein kleineres Flusskontrollfenster als die aktuelle Größe verwenden möchte, kann einen neuen SETTINGS-Frame senden. Der Empfänger MUSS jedoch darauf vorbereitet sein, Daten zu empfangen, die diese Fenstergröße überschreiten, da der Sender möglicherweise Daten sendet, die die untere Grenze überschreiten, bevor er den SETTINGS-Frame verarbeitet.

Nach dem Senden eines SETTINGS-Frames, der die anfängliche Flusskontrollfenstergröße reduziert, KANN ein Empfänger die Verarbeitung von Streams fortsetzen, die die Flusskontrollgrenzen überschreiten. Das Zulassen der Fortsetzung von Streams erlaubt es dem Empfänger nicht, den Platz, den er für Flusskontrollfenster reserviert, sofort zu reduzieren. Der Fortschritt bei diesen Streams kann auch ins Stocken geraten, da WINDOW_UPDATE-Frames erforderlich sind, damit der Sender das Senden fortsetzen kann. Der Empfänger KANN stattdessen einen RST_STREAM mit einem Fehlercode von FLOW_CONTROL_ERROR für die betroffenen Streams senden.

6.10. CONTINUATION

Der CONTINUATION-Frame (type=0x09) wird verwendet, um eine Sequenz von Feldblockfragmenten fortzusetzen (Abschnitt 4.3). Eine beliebige Anzahl von CONTINUATION-Frames kann gesendet werden, solange der vorhergehende Frame auf demselben Stream ist und ein HEADERS-, PUSH_PROMISE- oder CONTINUATION-Frame ohne gesetztes END_HEADERS-Flag ist.

CONTINUATION Frame {
Length (24),
Type (8) = 0x09,

Unused Flags (5),
END_HEADERS Flag (1),
Unused Flags (2),

Reserved (1),
Stream Identifier (31),

Field Block Fragment (..),
}

Abbildung 12: CONTINUATION-Frame-Format

Die Felder Length, Type, Unused Flag(s), Reserved und Stream Identifier werden in Abschnitt 4 beschrieben. Die CONTINUATION-Frame-Nutzlast enthält ein Feldblockfragment (Abschnitt 4.3).

Der CONTINUATION-Frame definiert das folgende Flag:

END_HEADERS (0x04): Wenn gesetzt, zeigt das END_HEADERS-Flag an, dass dieser Frame einen Feldblock beendet (Abschnitt 4.3).

Wenn das END_HEADERS-Flag nicht gesetzt ist, MUSS diesem Frame ein weiterer CONTINUATION-Frame folgen. Ein Empfänger MUSS den Empfang eines anderen Frame-Typs oder eines Frames auf einem anderen Stream als Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR behandeln.

Der CONTINUATION-Frame ändert den Verbindungszustand wie in Abschnitt 4.3 definiert.

CONTINUATION-Frames MÜSSEN einem Stream zugeordnet sein. Wenn ein CONTINUATION-Frame mit einem Stream Identifier-Feld von 0x00 empfangen wird, MUSS der Empfänger mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.

Einem CONTINUATION-Frame MUSS ein HEADERS-, PUSH_PROMISE- oder CONTINUATION-Frame ohne gesetztes END_HEADERS-Flag vorausgehen. Ein Empfänger, der eine Verletzung dieser Regel beobachtet, MUSS mit einem Verbindungsfehler (Abschnitt 5.4.1) vom Typ PROTOCOL_ERROR antworten.


Kapitel 6 abgeschlossen!