4. Working with Structured Fields in HTTP (Arbeiten mit strukturierten Feldern in HTTP)
Dieser Abschnitt definiert, wie strukturierte Felder in textuellen HTTP-Feldwerten und anderen kompatiblen Kodierungen (z. B. in HTTP/2 [RFC7540] vor der Komprimierung mit HPACK [RFC7541]) serialisiert und geparst werden.
4.1 Serializing Structured Fields (Strukturierte Felder serialisieren)
Gegeben eine in dieser Spezifikation definierte Struktur, wird eine ASCII-Zeichenkette zurückgegeben, die zur Verwendung in einem HTTP-Feldwert geeignet ist.
Hauptalgorithmus
-
Wenn die Struktur ein Dictionary oder eine List ist und ihr Wert leer ist (d. h. keine Mitglieder hat), wird das Feld überhaupt nicht serialisiert (d. h. field-name und field-value werden weggelassen).
-
Wenn die Struktur eine List ist, sei output_string das Ergebnis der Ausführung von „Liste serialisieren" (Abschnitt 4.1.1).
-
Andernfalls, wenn die Struktur ein Dictionary ist, sei output_string das Ergebnis der Ausführung von „Dictionary serialisieren" (Abschnitt 4.1.2).
-
Andernfalls, wenn die Struktur ein Item ist, sei output_string das Ergebnis der Ausführung von „Item serialisieren" (Abschnitt 4.1.3).
-
Andernfalls schlägt die Serialisierung fehl.
-
output_string mit ASCII-Kodierung [RFC0020] in ein Byte-Array umwandeln und zurückgeben.
4.1.1 Serializing a List (Liste serialisieren)
Gegeben ein Array von (member_value, parameters)-Tupeln als input_list, wird eine ASCII-Zeichenkette zurückgegeben, die zur Verwendung in einem HTTP-Feldwert geeignet ist.
Algorithmus
-
Sei output eine leere Zeichenkette.
-
Für jedes (member_value, parameters) in input_list:
- Wenn member_value ein Array ist, das Ergebnis der Ausführung von „Inner List serialisieren" (Abschnitt 4.1.1.1) an output anhängen
- Andernfalls das Ergebnis der Ausführung von „Item serialisieren" (Abschnitt 4.1.3) an output anhängen
- Wenn es weitere member_values in input_list gibt:
- „," an output anhängen
- Ein einzelnes Leerzeichen (SP) an output anhängen
-
output zurückgeben.
Beispiele
Eingabe: [(1, {}), (2, {}), (3, {})]
Ausgabe: "1, 2, 3"
Eingabe: [("foo", {}), ("bar", {a: 1})]
Ausgabe: "foo, bar;a=1"
4.1.1.1 Serializing an Inner List (Inner List serialisieren)
Gegeben ein Array von (member_value, parameters)-Tupeln als inner_list und Parameter als list_parameters, wird eine ASCII-Zeichenkette zurückgegeben.
Algorithmus
-
Sei output die Zeichenkette „(".
-
Für jedes (member_value, parameters) in inner_list:
- Das Ergebnis der Ausführung von „Item serialisieren" an output anhängen
- Wenn es weitere Werte in inner_list gibt, ein einzelnes Leerzeichen an output anhängen
-
„)" an output anhängen.
-
Das Ergebnis der Ausführung von „Parameters serialisieren" (Abschnitt 4.1.1.2) an output anhängen.
-
output zurückgeben.
Beispiele
Eingabe: [(1, {}), (2, {})] mit Parametern {lvl: 5}
Ausgabe: "(1 2);lvl=5"
4.1.1.2 Serializing Parameters (Parameter serialisieren)
Gegeben ein geordnetes Dictionary als input_parameters (jedes Mitglied hat param_key und param_value), wird eine ASCII-Zeichenkette zurückgegeben.
Algorithmus
-
Sei output eine leere Zeichenkette.
-
Für jeden param_key mit Wert param_value in input_parameters:
- „;" an output anhängen
- Das Ergebnis der Ausführung von „Key serialisieren" (Abschnitt 4.1.1.3) an output anhängen
- Wenn param_value nicht Boolean true ist:
- „=" an output anhängen
- Das Ergebnis der Ausführung von „Bare Item serialisieren" an output anhängen
-
output zurückgeben.
Beispiele
Eingabe: {a: 1, b: true, c: "value"}
Ausgabe: ";a=1;b;c=\"value\""
4.1.1.3 Serializing a Key (Key serialisieren)
Gegeben key als input_key, wird eine ASCII-Zeichenkette zurückgegeben.
Algorithmus
-
input_key in eine ASCII-Zeichenfolge umwandeln; wenn die Umwandlung fehlschlägt, schlägt die Serialisierung fehl.
-
Wenn input_key Zeichen enthält, die nicht in lcalpha, DIGIT, „_", „-", „." oder „*" enthalten sind, schlägt die Serialisierung fehl.
-
Wenn das erste Zeichen von input_key nicht lcalpha oder „*" ist, schlägt die Serialisierung fehl.
-
input_key zurückgeben.
Gültige Key-Beispiele
✓ "foo"
✓ "foo_bar"
✓ "foo-bar"
✓ "*star"
✗ "Foo" (Großbuchstabe)
✗ "123foo" (beginnt mit Ziffer)
4.1.2 Serializing a Dictionary (Dictionary serialisieren)
Gegeben ein geordnetes Dictionary als input_dictionary (jedes Mitglied hat member_key und Tupelwert (member_value, parameters)), wird eine ASCII-Zeichenkette zurückgegeben.
Algorithmus
-
Sei output eine leere Zeichenkette.
-
Für jeden member_key mit Wert (member_value, parameters) in input_dictionary:
- Das Ergebnis der Ausführung von „Key serialisieren" an output anhängen
- Wenn member_value Boolean true ist:
- Das Ergebnis der Ausführung von „Parameters serialisieren" an output anhängen
- Andernfalls:
- „=" an output anhängen
- Wenn member_value ein Array ist, das Ergebnis der Ausführung von „Inner List serialisieren" anhängen
- Andernfalls das Ergebnis der Ausführung von „Item serialisieren" anhängen
- Wenn es weitere Mitglieder in input_dictionary gibt:
- „," an output anhängen
- Ein einzelnes Leerzeichen an output anhängen
-
output zurückgeben.
Beispiele
Eingabe: {a: 1, b: true, c: (2, 3)}
Ausgabe: "a=1, b, c=(2 3)"
4.1.3 Serializing an Item (Item serialisieren)
Gegeben ein Item als bare_item und Parameters als item_parameters, wird eine ASCII-Zeichenkette zurückgegeben.
Algorithmus
- Sei output eine leere Zeichenkette.
- Das Ergebnis der Ausführung von „Bare Item serialisieren" (Abschnitt 4.1.3.1) an output anhängen.
- Das Ergebnis der Ausführung von „Parameters serialisieren" an output anhängen.
- output zurückgeben.
4.1.3.1 Serializing a Bare Item (Bare Item serialisieren)
Gegeben ein Item als input_item, die entsprechende Serialisierungsfunktion je nach Typ aufrufen:
- Integer → Abschnitt 4.1.4
- Decimal → Abschnitt 4.1.5
- String → Abschnitt 4.1.6
- Token → Abschnitt 4.1.7
- Byte Sequence → Abschnitt 4.1.8
- Boolean → Abschnitt 4.1.9
4.1.4 Serializing an Integer (Integer serialisieren)
Algorithmus
- Wenn input_integer nicht im Bereich -999.999.999.999.999 bis 999.999.999.999.999 (einschließlich) liegt, schlägt die Serialisierung fehl.
- Wenn input_integer < 0, „-" anhängen.
- Die Dezimaldarstellung von input_integer anhängen.
Beispiele
42 → "42"
-100 → "-100"
0 → "0"
4.1.5 Serializing a Decimal (Decimal serialisieren)
Algorithmus
- Wenn es keine Dezimalzahl ist, schlägt die Serialisierung fehl.
- Wenn rechts vom Dezimalpunkt mehr als 3 signifikante Stellen vorhanden sind, auf 3 Stellen runden.
- Wenn links vom Dezimalpunkt mehr als 12 signifikante Stellen vorhanden sind, schlägt die Serialisierung fehl.
- Wenn input_decimal < 0, „-" anhängen.
- Die Dezimaldarstellung des ganzzahligen Teils anhängen.
- „." anhängen.
- Den Dezimalteil anhängen (wenn 0, „0" anhängen).
Beispiele
4.5 → "4.5"
-0.123 → "-0.123"
3.14159 → "3.142" (gerundet)
4.1.6 Serializing a String (String serialisieren)
Algorithmus
- In ASCII-Zeichenfolge umwandeln; wenn fehlgeschlagen, schlägt die Serialisierung fehl.
- Wenn Zeichen im Bereich %x00-1f oder %x7f-ff enthalten sind, schlägt die Serialisierung fehl.
- DQUOTE (") anhängen.
- Für jedes Zeichen:
- Wenn es „" oder DQUOTE ist, „" anhängen
- Das Zeichen anhängen
- DQUOTE anhängen.
Beispiele
hello world → "\"hello world\""
say "hi" → "\"say \\\"hi\\\"\""
4.1.7 Serializing a Token (Token serialisieren)
Algorithmus
- In ASCII-Zeichenfolge umwandeln; wenn fehlgeschlagen, schlägt die Serialisierung fehl.
- Überprüfen, ob das erste Zeichen ALPHA oder „*" ist.
- Überprüfen, ob die übrigen Zeichen in tchar, „:" oder „/" enthalten sind.
- input_token zurückgeben.
Beispiele
foo123/456 → "foo123/456"
application/json → "application/json"
* → "*"
4.1.8 Serializing a Byte Sequence (Byte Sequence serialisieren)
Algorithmus
- Wenn es keine Byte Sequence ist, schlägt die Serialisierung fehl.
- „:" anhängen.
- Die base64-kodierten input_bytes anhängen (gemäß Abschnitt 4 von [RFC4648]).
- „:" anhängen.
Beispiele
[0x48, 0x65, 0x6c, 0x6c, 0x6f] → ":SGVsbG8=:"
4.1.9 Serializing a Boolean (Boolean serialisieren)
Algorithmus
- Wenn es kein Boolean ist, schlägt die Serialisierung fehl.
- „?" anhängen.
- Wenn true, „1" anhängen; wenn false, „0" anhängen.
Beispiele
true → "?1"
false → "?0"
4.2 Parsing Structured Fields (Strukturierte Felder parsen)
Wenn eine empfangende Implementierung ein HTTP-Feld parst, das als strukturiertes Feld bekannt ist, ist Vorsicht geboten, da es viele Randfälle gibt, die zu Interoperabilitäts- oder sogar Sicherheitsproblemen führen können. Dieser Abschnitt spezifiziert die Algorithmen zur Durchführung dieser Aufgabe.
Hauptalgorithmus
Gegeben ein Byte-Array input_bytes, das den field-value des ausgewählten Feldes darstellt (oder leer ist, wenn das Feld nicht vorhanden ist), und field_type (eines von „dictionary", „list" oder „item"), wird der geparste Header-Wert zurückgegeben.
-
input_bytes in eine ASCII-Zeichenkette input_string umwandeln; wenn die Umwandlung fehlschlägt, schlägt das Parsen fehl.
-
Alle SP-Zeichen am Anfang von input_string verwerfen.
-
Wenn field_type „list" ist, sei output das Ergebnis der Ausführung von „Liste parsen" (Abschnitt 4.2.1).
-
Wenn field_type „dictionary" ist, sei output das Ergebnis der Ausführung von „Dictionary parsen" (Abschnitt 4.2.2).
-
Wenn field_type „item" ist, sei output das Ergebnis der Ausführung von „Item parsen" (Abschnitt 4.2.3).
-
Alle SP-Zeichen am Anfang von input_string verwerfen.
-
Wenn input_string nicht leer ist, schlägt das Parsen fehl.
-
Andernfalls output zurückgeben.
Grundprinzipien
- Strenges Parsen: Jeder Fehler führt dazu, dass das gesamte Feld ignoriert wird
- Keine Fehlertoleranz: Kein Versuch, fehlerhafte Eingaben zu „korrigieren"
- Sicherheit zuerst: Schutz vor Injection-Angriffen und Mehrdeutigkeiten
- Feldzusammenführung: Der Parser MUSS alle Feldzeilen mit Feldnamen, die im selben Abschnitt (Header oder Trailer) ohne Berücksichtigung der Groß-/Kleinschreibung übereinstimmen, zu einem einzigen durch Komma getrennten field-value zusammenführen
Wichtiger Hinweis
Bei Lists und Dictionaries werden alle Zeilen des Feldes korrekt zusammengeführt, solange die einzelnen Mitglieder der übergeordneten Datenstruktur nicht über mehrere Header-Instanzen aufgeteilt werden.
Wenn das Parsen fehlschlägt (einschließlich beim Aufruf anderer Algorithmen), MUSS (MUST) der gesamte Feldwert ignoriert werden (d. h. so behandelt werden, als ob das Feld in diesem Abschnitt nicht vorhanden wäre). Dies ist bewusst streng, um Interoperabilität und Sicherheit zu verbessern; Spezifikationen, die dieses Dokument referenzieren, dürfen diese Anforderung nicht lockern.
4.2.1 Parsing a List (Liste parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Array von (item_or_inner_list, parameters)-Tupeln zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Sei members ein leeres Array.
-
Solange input_string nicht leer ist:
- Das Ergebnis der Ausführung von „Item oder Inner List parsen" (Abschnitt 4.2.1.1) an members anhängen
- Alle OWS-Zeichen am Anfang von input_string verwerfen
- Wenn input_string leer ist, members zurückgeben
- Das erste Zeichen von input_string verbrauchen; wenn es nicht „," ist, schlägt das Parsen fehl
- Alle OWS-Zeichen am Anfang von input_string verwerfen
- Wenn input_string leer ist, gibt es ein abschließendes Komma; Parsen schlägt fehl
-
Keine strukturierten Daten gefunden; members zurückgeben (leer).
4.2.1.1 Parsing an Item or Inner List (Item oder Inner List parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Tupel (item_or_inner_list, parameters) zurückgegeben, wobei item_or_inner_list entweder ein einzelnes Bare Item oder ein Array von (bare_item, parameters)-Tupeln sein kann. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Wenn das erste Zeichen von input_string „(" ist, das Ergebnis der Ausführung von „Inner List parsen" (Abschnitt 4.2.1.2) zurückgeben.
-
Das Ergebnis der Ausführung von „Item parsen" (Abschnitt 4.2.3) zurückgeben.
4.2.1.2 Parsing an Inner List (Inner List parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Tupel (inner_list, parameters) zurückgegeben, wobei inner_list ein Array von (bare_item, parameters)-Tupeln ist. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Das erste Zeichen von input_string verbrauchen; wenn es nicht „(" ist, schlägt das Parsen fehl.
-
Sei inner_list ein leeres Array.
-
Solange input_string nicht leer ist:
- Alle SP-Zeichen am Anfang von input_string verwerfen
- Wenn das erste Zeichen von input_string „)" ist:
- Das erste Zeichen von input_string verbrauchen
- Sei parameters das Ergebnis der Ausführung von „Parameters parsen" (Abschnitt 4.2.3.2)
- Tupel (inner_list, parameters) zurückgeben
- Sei item das Ergebnis der Ausführung von „Item parsen" (Abschnitt 4.2.3)
- item an inner_list anhängen
- Wenn das erste Zeichen von input_string nicht SP oder „)" ist, schlägt das Parsen fehl
-
Ende der Inner List nicht gefunden; Parsen schlägt fehl.
4.2.2 Parsing a Dictionary (Dictionary parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird eine geordnete Zuordnung mit (item_or_inner_list, parameters)-Tupeln als Werte zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Sei dictionary eine leere geordnete Zuordnung.
-
Solange input_string nicht leer ist:
- Sei this_key das Ergebnis der Ausführung von „Key parsen" (Abschnitt 4.2.3.3)
- Wenn das erste Zeichen von input_string „=" ist:
- Das erste Zeichen von input_string verbrauchen
- Sei member das Ergebnis der Ausführung von „Item oder Inner List parsen" (Abschnitt 4.2.1.1)
- Andernfalls:
- Sei value Boolean true
- Sei parameters das Ergebnis der Ausführung von „Parameters parsen" (Abschnitt 4.2.3.2)
- Sei member das Tupel (value, parameters)
- Wenn dictionary bereits den Schlüssel this_key enthält (zeichenweise Vergleich), seinen Wert mit member überschreiben
- Andernfalls Schlüssel this_key mit Wert member an dictionary anhängen
- Alle OWS-Zeichen am Anfang von input_string verwerfen
- Wenn input_string leer ist, dictionary zurückgeben
- Das erste Zeichen von input_string verbrauchen; wenn es nicht „," ist, schlägt das Parsen fehl
- Alle OWS-Zeichen am Anfang von input_string verwerfen
- Wenn input_string leer ist, gibt es ein abschließendes Komma; Parsen schlägt fehl
-
Keine strukturierten Daten gefunden; dictionary zurückgeben (leer).
Hinweis: Bei doppelten Dictionary-Schlüsseln werden alle Instanzen außer der letzten ignoriert.
4.2.3 Parsing an Item (Item parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein (bare_item, parameters)-Tupel zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Sei bare_item das Ergebnis der Ausführung von „Bare Item parsen" (Abschnitt 4.2.3.1).
-
Sei parameters das Ergebnis der Ausführung von „Parameters parsen" (Abschnitt 4.2.3.2).
-
Tupel (bare_item, parameters) zurückgeben.
4.2.3.1 Parsing a Bare Item (Bare Item parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Bare Item zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Wenn das erste Zeichen von input_string „-" oder DIGIT ist, das Ergebnis der Ausführung von „Integer oder Decimal parsen" (Abschnitt 4.2.4) zurückgeben.
-
Wenn das erste Zeichen von input_string DQUOTE ist, das Ergebnis der Ausführung von „String parsen" (Abschnitt 4.2.5) zurückgeben.
-
Wenn das erste Zeichen von input_string ALPHA oder „*" ist, das Ergebnis der Ausführung von „Token parsen" (Abschnitt 4.2.6) zurückgeben.
-
Wenn das erste Zeichen von input_string „:" ist, das Ergebnis der Ausführung von „Byte Sequence parsen" (Abschnitt 4.2.7) zurückgeben.
-
Wenn das erste Zeichen von input_string „?" ist, das Ergebnis der Ausführung von „Boolean parsen" (Abschnitt 4.2.8) zurückgeben.
-
Andernfalls ist der Item-Typ nicht erkennbar; Parsen schlägt fehl.
4.2.3.2 Parsing Parameters (Parameter parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird eine geordnete Zuordnung mit Bare Items als Werte zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Sei parameters eine leere geordnete Zuordnung.
-
Solange input_string nicht leer ist:
- Wenn das erste Zeichen von input_string nicht „;" ist, Schleife beenden
- Das „;"-Zeichen am Anfang von input_string verbrauchen
- Alle SP-Zeichen am Anfang von input_string verwerfen
- Sei param_key das Ergebnis der Ausführung von „Key parsen" (Abschnitt 4.2.3.3)
- Sei param_value Boolean true
- Wenn das erste Zeichen von input_string „=" ist:
- Das „="-Zeichen am Anfang von input_string verbrauchen
- Sei param_value das Ergebnis der Ausführung von „Bare Item parsen" (Abschnitt 4.2.3.1)
- Wenn parameters bereits den Schlüssel param_key enthält (zeichenweise Vergleich), seinen Wert mit param_value überschreiben
- Andernfalls Schlüssel param_key mit Wert param_value an parameters anhängen
-
parameters zurückgeben.
Hinweis: Bei doppelten Parameterschlüsseln werden alle Instanzen außer der letzten ignoriert.
4.2.3.3 Parsing a Key (Key parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Key zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Wenn das erste Zeichen von input_string nicht lcalpha oder „*" ist, schlägt das Parsen fehl.
-
Sei output_string eine leere Zeichenkette.
-
Solange input_string nicht leer ist:
- Wenn das erste Zeichen von input_string nicht lcalpha, DIGIT, „_", „-", „." oder „*" ist, output_string zurückgeben
- Sei char das Ergebnis des Verbrauchens des ersten Zeichens von input_string
- char an output_string anhängen
-
output_string zurückgeben.
4.2.4 Parsing an Integer or Decimal (Integer oder Decimal parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Integer oder Decimal zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Hinweis: Dieser Algorithmus parst sowohl Integers (Abschnitt 3.3.1) als auch Decimals (Abschnitt 3.3.2) und gibt die entsprechende Struktur zurück.
Algorithmus
-
Sei type „integer".
-
Sei sign 1.
-
Sei input_number eine leere Zeichenkette.
-
Wenn das erste Zeichen von input_string „-" ist, es verbrauchen und sign auf -1 setzen.
-
Wenn input_string leer ist, gibt es einen leeren Integer; Parsen schlägt fehl.
-
Wenn das erste Zeichen von input_string nicht DIGIT ist, schlägt das Parsen fehl.
-
Solange input_string nicht leer ist:
- Sei char das Ergebnis des Verbrauchens des ersten Zeichens von input_string
- Wenn char DIGIT ist, es an input_number anhängen
- Andernfalls, wenn type „integer" ist und char „." ist:
- Wenn input_number mehr als 12 Zeichen enthält, schlägt das Parsen fehl
- Andernfalls char an input_number anhängen und type auf „decimal" setzen
- Andernfalls char an den Anfang von input_string stellen und Schleife beenden
- Wenn type „integer" ist und input_number mehr als 15 Zeichen enthält, schlägt das Parsen fehl
- Wenn type „decimal" ist und input_number mehr als 16 Zeichen enthält, schlägt das Parsen fehl
-
Wenn type „integer" ist:
- input_number als Integer parsen, sei output_number das Ergebnis multipliziert mit sign
-
Andernfalls:
- Wenn das letzte Zeichen von input_number „." ist, schlägt das Parsen fehl
- Wenn die Anzahl der Zeichen nach „." in input_number größer als 3 ist, schlägt das Parsen fehl
- input_number als Dezimalzahl parsen, sei output_number das Ergebnis multipliziert mit sign
-
output_number zurückgeben.
4.2.5 Parsing a String (String parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein String ohne Anführungszeichen zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Sei output_string eine leere Zeichenkette.
-
Wenn das erste Zeichen von input_string nicht DQUOTE ist, schlägt das Parsen fehl.
-
Das erste Zeichen von input_string verwerfen.
-
Solange input_string nicht leer ist:
- Sei char das Ergebnis des Verbrauchens des ersten Zeichens von input_string
- Wenn char Backslash („\") ist:
- Wenn input_string jetzt leer ist, schlägt das Parsen fehl
- Sei next_char das Ergebnis des Verbrauchens des ersten Zeichens von input_string
- Wenn next_char nicht DQUOTE oder „\" ist, schlägt das Parsen fehl
- next_char an output_string anhängen
- Andernfalls, wenn char DQUOTE ist, output_string zurückgeben
- Andernfalls, wenn char im Bereich %x00-1f oder %x7f-ff liegt (d. h. nicht in VCHAR oder SP), schlägt das Parsen fehl
- Andernfalls char an output_string anhängen
-
Ende von input_string erreicht ohne abschließendes DQUOTE; Parsen schlägt fehl.
4.2.6 Parsing a Token (Token parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Token zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Wenn das erste Zeichen von input_string nicht ALPHA oder „*" ist, schlägt das Parsen fehl.
-
Sei output_string eine leere Zeichenkette.
-
Solange input_string nicht leer ist:
- Wenn das erste Zeichen von input_string nicht in tchar, „:" oder „/" enthalten ist, output_string zurückgeben
- Sei char das Ergebnis des Verbrauchens des ersten Zeichens von input_string
- char an output_string anhängen
-
output_string zurückgeben.
4.2.7 Parsing a Byte Sequence (Byte Sequence parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird eine Byte Sequence zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Wenn das erste Zeichen von input_string nicht „:" ist, schlägt das Parsen fehl.
-
Das erste Zeichen von input_string verwerfen.
-
Wenn vor dem Ende von input_string kein „:"-Zeichen vorhanden ist, schlägt das Parsen fehl.
-
Sei b64_content das Ergebnis des Verbrauchens des Inhalts von input_string bis zum (aber nicht einschließlich) ersten „:"-Zeichen.
-
Das „:"-Zeichen am Anfang von input_string verbrauchen.
-
Wenn b64_content Zeichen enthält, die nicht in ALPHA, DIGIT, „+", „/" und „=" enthalten sind, schlägt das Parsen fehl.
-
Sei binary_content das Ergebnis der base64-Dekodierung [RFC4648] von b64_content, bei Bedarf mit synthetischem Padding (beachte die folgenden Anforderungen an das Empfängerverhalten). Wenn die base64-Dekodierung fehlschlägt, schlägt das Parsen fehl.
-
binary_content zurückgeben.
Implementierungshinweise:
- Da einige base64-Implementierungen nicht in der Lage sind, nicht korrekt mit „=" aufgefüllte kodierte Daten abzulehnen, SOLLTEN (SHOULD NOT) Parser nicht fehlschlagen, wenn „="-Padding fehlt, es sei denn, sie können nicht so konfiguriert werden.
- Da einige base64-Implementierungen nicht in der Lage sind, kodierte Daten mit Nicht-Null-Padding-Bits abzulehnen, SOLLTEN (SHOULD NOT) Parser nicht fehlschlagen, wenn Nicht-Null-Padding-Bits vorhanden sind, es sei denn, sie können nicht so konfiguriert werden.
- Parser MÜSSEN (MUST) bei Zeichen außerhalb des base64-Alphabets und bei Zeilenumbrüchen in den kodierten Daten fehlschlagen.
4.2.8 Parsing a Boolean (Boolean parsen)
Gegeben eine ASCII-Zeichenkette input_string, wird ein Boolean zurückgegeben. input_string wird modifiziert, um die geparsten Werte zu entfernen.
Algorithmus
-
Wenn das erste Zeichen von input_string nicht „?" ist, schlägt das Parsen fehl.
-
Das erste Zeichen von input_string verwerfen.
-
Wenn das erste Zeichen von input_string „1" ist, das erste Zeichen verwerfen und true zurückgeben.
-
Wenn das erste Zeichen von input_string „0" ist, das erste Zeichen verwerfen und false zurückgeben.
-
Kein Wert gefunden; Parsen schlägt fehl.
Vollständige Parse-Beispiele
Listen-Parse-Beispiel
// Eingabezeichenkette
"42;a=1, foo, (1 2);b"
// Parse-Ergebnis
[
(42, {a: 1}),
("foo", {}),
([1, 2], {b: true})
]
Dictionary-Parse-Beispiel
// Eingabezeichenkette
"key1=42;a=1, key2, key3=(1 2)"
// Parse-Ergebnis
{
key1: (42, {a: 1}),
key2: (true, {}),
key3: ([1, 2], {})
}
Item-Parse-Beispiel
// Eingabezeichenkette
"42;foo=\"bar\";flag"
// Parse-Ergebnis
(42, {foo: "bar", flag: true})
Vollständige Serialisierungsbeispiele
Listen-Beispiel
// Eingabe
[
(42, {a: 1}),
("foo", {}),
([1, 2], {b: true})
]
// Ausgabe
"42;a=1, foo, (1 2);b"
Dictionary-Beispiel
// Eingabe
{
key1: (42, {a: 1}),
key2: (true, {}),
key3: ([1, 2], {})
}
// Ausgabe
"key1=42;a=1, key2, key3=(1 2)"
Item-Beispiel
// Eingabe
(42, {foo: "bar", flag: true})
// Ausgabe
"42;foo=\"bar\";flag"
Wesentliche Erkenntnisse (Key Takeaways)
Serialisierung
- Behandlung leerer Werte: Leere Lists und Dictionaries werden nicht serialisiert (gesamtes Feld wird weggelassen)
- Boolean-Kurzform: true-Werte lassen den „=value"-Teil weg
- Striktes Format: Jeder Typ hat genaue Formatanforderungen
- Fehler = Abbruch: Jeder Validierungsfehler lässt die gesamte Serialisierung sofort fehlschlagen
Implementierungsempfehlungen
// Pseudocode-Beispiel
function serializeStructuredField(field) {
if (isEmpty(field)) {
return null; // Nicht serialisieren
}
try {
if (field.type === 'list') {
return serializeList(field.value);
} else if (field.type === 'dictionary') {
return serializeDictionary(field.value);
} else if (field.type === 'item') {
return serializeItem(field.value, field.parameters);
}
} catch (error) {
// Serialisierung fehlgeschlagen, Fehler zurückgeben
throw new SerializationError(error);
}
}
Hinweis zur Implementierung
Abschnitt 4.2 (Parse-Algorithmen) ist ebenso wichtig und definiert, wie HTTP-Feldwerte zurück in strukturierte Daten geparst werden. Die Parse-Algorithmen gewährleisten eine strenge Validierung und konsistente Fehlerbehandlung.
Hinweis: Da die Parse-Algorithmen sehr detailliert und symmetrisch zur Serialisierung sind, sollte bei der Implementierung die vollständige RFC 8941-Spezifikation herangezogen werden, um vollständige Konformität sicherzustellen.