RFC 6570 - URI-Vorlagen
- Status: Proposed Standard
- Veröffentlicht: March 2012
- Stream: IETF
- Errata: Keine Errata
Zusammenfassung (Abstract)
Eine URI-Vorlage (URI Template) ist eine kompakte Zeichenfolge zur Beschreibung eines Bereichs von Uniform Resource Identifiers durch Variablenexpansion. Diese Spezifikation definiert die URI-Vorlagen-Syntax und den Prozess zur Expansion einer URI-Vorlage in eine URI-Referenz sowie Richtlinien für die Verwendung von URI-Vorlagen im Internet.
Inhaltsverzeichnis (Contents)
- 1. Introduction (Einführung)
- 1.1. Overview (Überblick)
- 1.2. Levels and Expression Types (Ebenen und Ausdruckstypen)
- 1.3. Design Considerations (Designüberlegungen)
- 1.4. Limitations (Einschränkungen)
- 1.5. Notational Conventions (Notationskonventionen)
- 1.6. Character Encoding and Unicode Normalization (Zeichenkodierung und Unicode-Normalisierung)
- 2. Syntax
- 2.1. Literals (Literale)
- 2.2. Expressions (Ausdrücke)
- 2.3. Variables (Variablen)
- 2.4. Value Modifiers (Wertmodifikatoren)
- 2.4.1. Prefix Values (Präfixwerte)
- 2.4.2. Composite Values (Zusammengesetzte Werte)
- 3. Expansion
- 3.1. Literal Expansion (Literal-Expansion)
- 3.2. Expression Expansion (Ausdrucksexpansion)
- 3.2.1. Variable Expansion (Variablenexpansion)
- 3.2.2. Simple String Expansion:
{var}(Einfache Zeichenkettenexpansion) - 3.2.3. Reserved Expansion:
{+var}(Reservierte Zeichenexpansion) - 3.2.4. Fragment Expansion:
{#var}(Fragment-Expansion) - 3.2.5. Label Expansion with Dot-Prefix:
{.var}(Label-Expansion mit Punkt-Präfix) - 3.2.6. Path Segment Expansion:
{/var}(Pfadsegment-Expansion) - 3.2.7. Path-Style Parameter Expansion:
{;var}(Pfadstil-Parameterexpansion) - 3.2.8. Form-Style Query Expansion:
{?var}(Formularstil-Abfrageexpansion) - 3.2.9. Form-Style Query Continuation:
{&var}(Formularstil-Abfragefortsetzung)
- 4. Security Considerations (Sicherheitserwägungen)
- 5. Acknowledgments (Danksagungen)
- 6. References (Referenzen)
- 6.1. Normative References (Normative Referenzen)
- 6.2. Informative References (Informative Referenzen)
Anhänge (Appendices)
Verwandte Ressourcen
- Offizieller Originaltext: RFC 6570
- Offizielle Seite: RFC 6570 DataTracker
- Errata: RFC Editor Errata
2. Syntax
Eine URI-Vorlage ist eine Zeichenkette aus druckbaren Unicode-Zeichen, die null oder mehr eingebettete Variablenausdrücke (Variable Expressions) enthält, wobei jeder Ausdruck durch ein passendes Paar geschweifter Klammern ('{', '}') begrenzt wird.
URI-Template = *( literals / expression )
Obwohl Vorlagen (und Vorlagenprozessor-Implementierungen) oben in Bezug auf vier graduelle Ebenen beschrieben werden, definieren wir die URI-Template-Syntax in Bezug auf die ABNF für Level 4. Ein Vorlagenprozessor, der auf Vorlagen niedrigerer Ebenen beschränkt ist, KANN (MAY) die ABNF-Regeln ausschließen, die nur für höhere Ebenen gelten. Es wird jedoch EMPFOHLEN (RECOMMENDED), dass alle Parser die vollständige Syntax implementieren, sodass nicht unterstützte Ebenen als solche für den Endbenutzer ordnungsgemäß identifiziert werden können.
2.1. Literals (Literale)
Die Zeichen außerhalb von Ausdrücken in einer URI-Vorlagenzeichenkette sollen wörtlich in die URI-Referenz kopiert werden, wenn das Zeichen in einem URI erlaubt ist (reserved / unreserved / pct-encoded), oder, wenn nicht erlaubt, als Sequenz von prozentkodiert
en Triplets, die der Kodierung dieses Zeichens in UTF-8 [RFC3629] entsprechen, in die URI-Referenz kopiert werden.
literals = %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B
/ %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate
/ pct-encoded
; jedes Unicode-Zeichen außer: CTL, SP,
; DQUOTE, "'", "%" (außer pct-encoded),
; "<", ">", "\", "^", "`", "{", "|", "}"
2.2. Expressions (Ausdrücke)
Vorlagenausdrücke sind die parametrisierten Teile einer URI-Vorlage. Jeder Ausdruck enthält einen optionalen Operator (Operator), der den Ausdruckstyp und seinen entsprechenden Expansionsprozess definiert, gefolgt von einer durch Kommas getrennten Liste von Variablenspezifizierern (Variable Specifiers) (Variablennamen und optionale Wertmodifikatoren). Wenn kein Operator bereitgestellt wird, verwendet der Ausdruck standardmäßig die einfache Variablenexpansion von nicht reservierten Werten.
expression = "{" [ operator ] variable-list "}"
operator = op-level2 / op-level3 / op-reserve
op-level2 = "+" / "#"
op-level3 = "." / "/" / ";" / "?" / "&"
op-reserve = "=" / "," / "!" / "@" / "|"
Die Operatorzeichen wurden gewählt, um ihre jeweilige Rolle als reservierte Zeichen in der URI-generischen Syntax widerzuspiegeln. Die in Abschnitt 3 dieser Spezifikation definierten Operatoren umfassen:
+Reservierte Zeichenketten (Reserved character strings)#Fragment-Identifikatoren mit "#"-Präfix (Fragment identifiers).Namensbezeichnungen oder Erweiterungen mit "."-Präfix (Name labels or extensions)/Pfadsegmente mit "/"-Präfix (Path segments);Pfadparametername oder name=value-Paare mit ";"-Präfix (Path parameter name or name=value pairs)?Abfragekomponente, die mit "?" beginnt und aus name=value-Paaren besteht, die durch "&" getrennt sind (Query component)&Fortsetzung von Abfrage-Stil-&name=value-Paaren innerhalb einer literalen Abfragekomponente (Continuation of query-style pairs)
Die Operatorzeichen Gleichheitszeichen ("="), Komma (","), Ausrufezeichen ("!"), At-Zeichen ("@") und Pipe ("|") sind für zukünftige Erweiterungen reserviert.
Die Ausdruckssyntax schließt die Verwendung des Dollar-Zeichens ("$") und der Klammern ["(" und ")"] ausdrücklich aus, sodass sie für die Verwendung außerhalb des Geltungsbereichs dieser Spezifikation verfügbar bleiben. Beispielsweise könnte eine Makrosprache diese Zeichen verwenden, um eine Makrosubstitution auf eine Zeichenkette anzuwenden, bevor diese Zeichenkette als URI-Vorlage verarbeitet wird.
2.3. Variables (Variablen)
Nach dem Operator (falls vorhanden) enthält jeder Ausdruck eine Liste von einem oder mehreren durch Kommas getrennten Variablenspezifizierern (varspec). Die Variablennamen dienen mehreren Zwecken: Dokumentation für die erwarteten Werttypen, Identifikatoren zum Zuordnen von Werten innerhalb eines Vorlagenprozessors und die literale Zeichenkette, die für den Namen in name=value-Expansionen verwendet wird (außer beim Explodieren eines assoziativen Arrays). Variablennamen sind groß- und kleinschreibungssensitiv, da der Name in einer groß- und kleinschreibungssensitiven URI-Komponente expandiert werden kann.
variable-list = varspec *( "," varspec )
varspec = varname [ modifier-level4 ]
varname = varchar *( ["."] varchar )
varchar = ALPHA / DIGIT / "_" / pct-encoded
Ein varname KANN (MAY) ein oder mehrere prozentkodierte Triplets enthalten. Diese Triplets werden als wesentlicher Bestandteil des Variablennamens betrachtet und während der Verarbeitung nicht dekodiert. Ein varname, der prozentkodierte Zeichen enthält, ist nicht dieselbe Variable wie ein varname mit denselben dekodierten Zeichen. Von Anwendungen, die URI-Vorlagen bereitstellen, wird erwartet, dass sie in ihrer Verwendung von Prozentkodierung in Variablennamen konsistent sind.
Ein Ausdruck KANN (MAY) auf Variablen verweisen, die dem Vorlagenprozessor unbekannt sind oder deren Wert auf einen speziellen "undefined (undefiniert)"-Wert wie undef oder null gesetzt ist. Solche undefinierten Variablen erhalten eine spezielle Behandlung durch den Expansionsprozess (Abschnitt 3.2.1).
Ein Variablenwert, der eine Zeichenkette der Länge null ist, wird nicht als undefiniert betrachtet; er hat den definierten Wert einer leeren Zeichenkette.
In Level 4-Vorlagen kann eine Variable einen zusammengesetzten Wert (Composite Value) in Form einer Werteliste oder eines assoziativen Arrays von (name, value)-Paaren haben. Solche Werttypen werden nicht direkt durch die Vorlagensyntax angezeigt, aber sie haben Auswirkungen auf den Expansionsprozess (Abschnitt 3.2.1).
Eine als Listenwert definierte Variable wird als undefiniert betrachtet, wenn die Liste null Mitglieder enthält. Eine als assoziatives Array von (name, value)-Paaren definierte Variable wird als undefiniert betrachtet, wenn das Array null Mitglieder enthält oder wenn alle Mitgliedsnamen im Array mit undefinierten Werten verknüpft sind.
2.4. Value Modifiers (Wertmodifikatoren)
Jede der Variablen in einem Level 4-Vorlagenausdruck kann einen Modifikator haben, der entweder anzeigt, dass ihre Expansion auf ein Präfix der Wertzeichenkette der Variable beschränkt ist, oder dass ihre Expansion als zusammengesetzter Wert in Form einer Werteliste oder eines assoziativen Arrays von (name, value)-Paaren explodiert wird.
modifier-level4 = prefix / explode
2.4.1. Prefix Values (Präfixwerte)
Ein Präfixmodifikator (Prefix Modifier) zeigt an, dass die Variablenexpansion auf ein Präfix der Wertzeichenkette der Variable beschränkt ist. Präfixmodifikatoren werden häufig verwendet, um einen Identifikatorraum hierarchisch zu partitionieren, wie es bei Referenzindizes und hashbasiertem Speicher üblich ist. Es dient auch dazu, den expandierten Wert auf eine maximale Anzahl von Zeichen zu beschränken. Präfixmodifikatoren sind nicht auf Variablen anwendbar, die zusammengesetzte Werte haben.
prefix = ":" max-length
max-length = %x31-39 0*3DIGIT ; positive Ganzzahl < 10000
Der max-length ist eine positive Ganzzahl, die sich auf eine maximale Anzahl von Zeichen vom Anfang des Variablenwerts als Unicode-Zeichenkette bezieht. Beachten Sie, dass diese Nummerierung in Zeichen, nicht in Oktetten erfolgt, um eine Aufteilung zwischen den Oktetten eines mehrfach-Oktett-kodierten Zeichens oder innerhalb eines prozentkodierte Triplets zu vermeiden. Wenn der max-length größer als die Länge des Variablenwerts ist, wird die gesamte Wertzeichenkette verwendet.
Zum Beispiel:
Gegebene Variablenzuweisungen
var := "value"
semi := ";"
Beispielvorlage Expansion
{var} value
{var:20} value
{var:3} val
{semi} %3B
{semi:2} %3B
2.4.2. Composite Values (Zusammengesetzte Werte)
Ein Explode-Modifikator (Explode Modifier) ("*") zeigt an, dass die Variable als zusammengesetzter Wert behandelt werden soll, der entweder aus einer Werteliste oder einem assoziativen Array von (name, value)-Paaren besteht. Daher wird der Expansionsprozess auf jedes Mitglied des Verbunds angewendet, als ob es als separate Variable aufgeführt wäre. Diese Art der Variablenspezifikation ist deutlich weniger selbstdokumentierend als nicht-explodierte Variablen, da es weniger Entsprechung zwischen dem Variablennamen und dem Erscheinungsbild der URI-Referenz nach der Expansion gibt.
explode = "*"
Da URI-Vorlagen keine Angabe von Typ oder Schema enthalten, wird angenommen, dass der Typ für eine explodierte Variable durch den Kontext bestimmt wird. Beispielsweise könnte dem Prozessor Werte in einer Form zur Verfügung gestellt werden, die Werte als Zeichenketten, Listen oder assoziative Arrays unterscheidet. Ebenso könnte der Kontext, in dem die Vorlage verwendet wird (Skript, Auszeichnungssprache, Schnittstellendefinitionssprache usw.), Regeln zur Zuordnung von Variablennamen zu Typen, Strukturen oder Schema definieren.
Explode-Modifikatoren verbessern die Kürze in der URI-Vorlagen-Syntax. Beispielsweise könnte eine Ressource, die eine geografische Karte für eine bestimmte Straßenadresse bereitstellt, hundert Permutationen von Feldern für die Adresseingabe akzeptieren, einschließlich Teiladressen (z. B. nur die Stadt oder Postleitzahl). Eine solche Ressource könnte als Vorlage mit jeder einzelnen Adresskomponente in der Reihenfolge aufgelistet oder mit einer weitaus einfacheren Vorlage beschrieben werden, die einen Explode-Modifikator verwendet, wie in:
/mapper{?address*}
zusammen mit einem Kontext, der definiert, was die Variable namens "address" enthalten kann, beispielsweise durch Verweis auf einen anderen Standard für Adressierung (z. B. [UPU-S42]). Ein Empfänger, der das Schema kennt, kann dann geeignete Expansionen bereitstellen, wie z. B.:
/mapper?city=Newport%20Beach&state=CA
Der Expansionsprozess für explodierte Variablen hängt sowohl vom verwendeten Operator als auch davon ab, ob der zusammengesetzte Wert als Werteliste oder als assoziatives Array von (name, value)-Paaren behandelt werden soll. Strukturen werden als assoziatives Array mit Namen verarbeitet, die den Feldern in der Strukturdefinition entsprechen, und "."-Trennzeichen werden verwendet, um die Namenshierarchie in Unterstrukturen anzuzeigen.
Wenn eine Variable eine zusammengesetzte Struktur hat und nur einige der Felder in dieser Struktur definierte Werte haben, sind nur die definierten Paare in der Expansion vorhanden. Dies kann für Vorlagen nützlich sein, die aus einer großen Anzahl potenzieller Abfragebegriffe bestehen.
Ein Explode-Modifikator, der auf eine Listenvariable angewendet wird, führt dazu, dass die Expansion die Expansion dieser Variablen gemäß dem Operator wiederholt, einmal für jedes Listenmitglied.
3. Expansion (Erweiterung)
Der Prozess der URI-Template-Expansion besteht darin, die Template-Zeichenkette von Anfang bis Ende zu scannen, literale Zeichen zu kopieren und jeden Ausdruck durch das Ergebnis der Anwendung des Operators des Ausdrucks auf den Wert jeder im Ausdruck genannten Variable zu ersetzen. Der Wert jeder Variable MUSS (MUST) vor der Template-Expansion gebildet werden.
Die Anforderungen an die Expansion für jeden Aspekt der URI-Template-Grammatik sind in diesem Abschnitt definiert. Ein nicht-normativer Algorithmus für den gesamten Expansionsprozess wird in Anhang A bereitgestellt.
Wenn ein Template-Prozessor auf eine Zeichenfolge außerhalb eines Ausdrucks trifft, die nicht mit der <URI-Template>-Grammatik übereinstimmt, dann SOLLTE (SHOULD) die Verarbeitung des Templates beendet werden, das URI-Referenz-Ergebnis SOLLTE (SHOULD) den expandierten Teil des Templates gefolgt vom nicht expandierten Rest enthalten, und die Position und Art des Fehlers SOLLTEN (SHOULD) der aufrufenden Anwendung angezeigt werden.
Wenn ein Fehler in einem Ausdruck auftritt, wie z. B. ein Operator oder Wert-Modifikator, den der Template-Prozessor nicht erkennt oder noch nicht unterstützt, oder wenn ein Zeichen gefunden wird, das von der <expression>-Grammatik nicht erlaubt ist, dann SOLLTEN (SHOULD) die nicht verarbeiteten Teile des Ausdrucks nicht expandiert in das Ergebnis kopiert werden, die Verarbeitung des Rests des Templates SOLLTE (SHOULD) fortgesetzt werden, und die Position und Art des Fehlers SOLLTEN (SHOULD) der aufrufenden Anwendung angezeigt werden.
Wenn ein Fehler auftritt, ist das zurückgegebene Ergebnis möglicherweise keine gültige URI-Referenz; es wird eine unvollständig expandierte Template-Zeichenkette sein, die nur für Diagnosezwecke vorgesehen ist.
3.1. Literal Expansion (Literale Expansion)
Wenn das literale Zeichen irgendwo in der URI-Syntax erlaubt ist (unreserved / reserved / pct-encoded), wird es direkt in die Ergebniszeichenkette kopiert. Andernfalls wird das prozentkodierte Äquivalent des literalen Zeichens in die Ergebniszeichenkette kopiert, indem das Zeichen zuerst als seine Oktettsequenz in UTF-8 kodiert und dann jedes solche Oktett als prozentkodiertes Triplet kodiert wird.
3.2. Expression Expansion (Ausdrucksexpansion)
Jeder Ausdruck wird durch ein öffnendes geschweiftes Klammerzeichen ("{") angezeigt und setzt sich bis zur nächsten schließenden geschweiften Klammer ("}") fort. Ausdrücke können nicht verschachtelt werden.
Ein Ausdruck wird expandiert, indem sein Ausdruckstyp bestimmt wird und dann für jedes kommagetrennte varspec im Ausdruck dem Expansionsprozess dieses Typs gefolgt wird. Level-1-Templates sind auf den Standardoperator (einfache Zeichenkettenwert-Expansion) und eine einzelne Variable pro Ausdruck beschränkt. Level-2-Templates sind auf ein einzelnes varspec pro Ausdruck beschränkt.
Der Ausdruckstyp wird bestimmt, indem das erste Zeichen nach der öffnenden Klammer betrachtet wird. Wenn das Zeichen ein Operator ist, wird der mit diesem Operator verbundene Ausdruckstyp für spätere Expansionsentscheidungen gespeichert und zum nächsten Zeichen für die Variablenliste gesprungen. Wenn das erste Zeichen kein Operator ist, ist der Ausdruckstyp einfache Zeichenkettenexpansion und das erste Zeichen ist der Beginn der Variablenliste.
Die Beispiele in den folgenden Unterabschnitten verwenden die folgenden Variablenwertdefinitionen:
count := ("one", "two", "three")
dom := ("example", "com")
dub := "me/too"
hello := "Hello World!"
half := "50%"
var := "value"
who := "fred"
base := "http://example.com/home/"
path := "/foo/bar"
list := ("red", "green", "blue")
keys := [("semi",";"),("dot","."),("comma",",")]
v := "6"
x := "1024"
y := "768"
empty := ""
empty_keys := []
undef := null
3.2.1. Variable Expansion (Variablenexpansion)
Eine Variable, die undefiniert ist (Abschnitt 2.3), hat keinen Wert und wird vom Expansionsprozess ignoriert. Wenn alle Variablen in einem Ausdruck undefiniert sind, ist die Expansion des Ausdrucks die leere Zeichenkette.
Die Variablenexpansion eines definierten, nicht leeren Werts ergibt eine Teilzeichenkette erlaubter URI-Zeichen. Wie in Abschnitt 1.6 beschrieben, ist der Expansionsprozess in Bezug auf Unicode-Codepunkte definiert, um sicherzustellen, dass Nicht-ASCII-Zeichen in der resultierenden URI-Referenz konsistent prozentkodiert werden. Eine Möglichkeit für einen Template-Prozessor, eine konsistente Expansion zu erhalten, besteht darin, die Wertzeichenkette in UTF-8 zu transkodieren (falls sie nicht bereits UTF-8 ist) und dann jedes Oktett, das nicht im erlaubten Satz ist, in das entsprechende prozentkodierte Triplet umzuwandeln.
Der erlaubte Satz für eine gegebene Expansion hängt vom Ausdruckstyp ab: Reservierte ("+") und Fragment ("#") Expansionen erlauben den Zeichensatz in der Vereinigung von (unreserved / reserved / pct-encoded) ohne Prozentkodierung durchzulassen, während alle anderen Ausdruckstypen nur nicht reservierte Zeichen ohne Prozentkodierung durchlassen. Beachten Sie, dass das Prozentzeichen ("%") nur als Teil eines prozentkodier ten Triplets und nur für reservierte/Fragment-Expansion erlaubt ist: in allen anderen Fällen MUSS (MUST) ein Wertzeichen "%" durch Variablenexpansion als "%25" prozentkodiert werden.
Wenn eine Variable mehr als einmal in einem Ausdruck oder innerhalb mehrerer Ausdrücke eines URI-Templates erscheint, MUSS (MUST) der Wert dieser Variable während des gesamten Expansionsprozesses statisch bleiben (d. h. die Variable muss für die Berechnung jeder Expansion denselben Wert haben). Wenn jedoch reservierte Zeichen oder prozentkodierte Triplets im Wert vorkommen, werden sie von einigen Ausdruckstypen prozentkodiert und von anderen nicht.
Für eine Variable, die einen einfachen Zeichenkettenwert hat, besteht die Expansion darin, den kodierten Wert an die Ergebniszeichenkette anzuhängen. Ein Explode-Modifikator hat keine Wirkung. Ein Präfix-Modifikator beschränkt die Expansion auf die ersten max-length Zeichen des dekodierten Werts. Wenn der Wert Mehroktett- oder prozentkodierte Zeichen enthält, muss darauf geachtet werden, den Wert nicht mitten in einem Zeichen aufzuteilen: zählen Sie jeden Unicode-Codepunkt als ein Zeichen.
Für eine Variable, die ein assoziatives Array ist, hängt die Expansion sowohl vom Ausdruckstyp als auch von der Anwesenheit eines Explode-Modifikators ab. Wenn es keinen Explode-Modifikator gibt, besteht die Expansion darin, eine kommagetrennte Verkettung jedes (name, value) Paares anzuhängen, das einen definierten Wert hat. Wenn es einen Explode-Modifikator gibt, besteht die Expansion darin, jedes Paar mit einem definierten Wert als "name=value" anzuhängen oder, wenn der Wert die leere Zeichenkette ist und der Ausdruckstyp keine Formular-Stil-Parameter anzeigt (d. h. kein "?" oder "&" Typ), einfach "name". Sowohl Name- als auch Wertzeichenketten werden auf die gleiche Weise wie einfache Zeichenkettenwerte kodiert. Eine Trennzeichenkette wird zwischen definierten Paaren gemäß dem Ausdruckstyp angehängt, wie in der folgenden Tabelle definiert:
Typ Trennzeichen
"," (Standard)
+ ","
# ","
. "."
/ "/"
; ";"
? "&"
& "&"
Für eine Variable mit einem Listenwert besteht die Expansion ohne Explode-Modifikator darin, eine kommagetrennte Verkettung jedes Listenmitgliedswerts mit einem definierten Wert als Wert eines einzelnen Namens für diese Variable anzuhängen. Wenn ein Explode-Modifikator vorhanden ist, besteht die Expansion darin, jeden Listenmitgliedswert mit einem definierten Wert als separaten Wert mit dem Namen dieser Variable anzuhängen oder, für Ausdruckstypen ohne benannte Variablen (kein ";", "?" oder "&"), einfach jeden Wert anzuhängen, getrennt durch das typspezifische Trennzeichen.
Ein Präfix-Modifikator auf einem Listenwert oder assoziativen Array-Wert hat keine Wirkung.
3.2.2. Simple String Expansion: {var} (Einfache Zeichenkettenexpansion)
Einfache Zeichenkettenexpansion ist der Standard-Ausdruckstyp, wenn kein Operator angegeben ist.
Für jede definierte Variable in der Variablenliste führen Sie Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im nicht reservierten Satz sind. Wenn mehr als eine Variable einen definierten Wert hat, hängen Sie ein Komma (",") als Trennzeichen zwischen Variablenexpansionen an die Ergebniszeichenkette an.
Beispiel-Template Expansion
```{var}``` value
{hello} Hello%20World%21
{half} 50%25
O{empty}X OX
O{undef}X OX
{x,y} 1024,768
{x,hello,y} 1024,Hello%20World%21,768
?{x,empty} ?1024,
?{x,undef} ?1024
?{undef,y} ?768
{var:3} val
{var:30} value
{list} red,green,blue
{list*} red,green,blue
{keys} semi,%3B,dot,.,comma,%2C
{keys*} semi=%3B,dot=.,comma=%2C
3.2.3. Reserved Expansion: {+var} (Reservierte Expansion)
Reservierte Expansion, angezeigt durch den Plus ("+") Operator für Level-2- und höhere Templates, ist identisch mit einfacher Zeichenkettenexpansion, außer dass die substituierten Werte auch prozentkodierte Triplets und Zeichen im reservierten Satz enthalten können.
Für jede definierte Variable in der Variablenliste führen Sie Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im Satz (unreserved / reserved / pct-encoded) sind. Wenn mehr als eine Variable einen definierten Wert hat, hängen Sie ein Komma (",") als Trennzeichen zwischen Variablenexpansionen an die Ergebniszeichenkette an.
Beispiel-Template Expansion
{+var} value
{+hello} Hello%20World!
{+half} 50%25
{base}index http%3A%2F%2Fexample.com%2Fhome%2Findex
{+base}index http://example.com/home/index
O{+empty}X OX
O{+undef}X OX
{+path}/here /foo/bar/here
here?ref={+path} here?ref=/foo/bar
{+x,hello,y} 1024,Hello%20World!,768
{+path,x}/here /foo/bar,1024/here
{+path:6}/here /foo/b,1024/here
{+list} red,green,blue
{+list*} red,green,blue
{+keys} semi,;,dot,.,comma,,
{+keys*} semi=;,dot=.,comma=,
3.2.4. Fragment Expansion: {#var} (Fragment-Expansion)
Fragment-Expansion, angezeigt durch den Raute ("#") Operator für Level-2- und höhere Templates, ist identisch mit reservierter Expansion, außer dass ein Rautezeichen (Fragment-Trennzeichen) zuerst an die Ergebniszeichenkette angehängt wird, wenn eine der Variablen definiert ist.
Beispiel-Template Expansion
{#var} #value
{#hello} #Hello%20World!
{#half} #50%25
foo{#empty} foo#
foo{#undef} foo
{#x,hello,y} #1024,Hello%20World!,768
{#path,x}/here #/foo/bar,1024/here
{#path:6}/here #/foo/b/here
{#list} #red,green,blue
{#list*} #red,green,blue
{#keys} #semi,;,dot,.,comma,,
{#keys*} #semi=;,dot=.,comma=,
3.2.5. Label Expansion with Dot-Prefix: {.var} (Label-Expansion mit Punkt-Präfix)
Label-Expansion, angezeigt durch den Punkt (".") Operator für Level-3- und höhere Templates, ist nützlich für die Beschreibung von URI-Räumen mit variierenden Domainnamen oder Pfadselektoren (z. B. Dateierweiterungen).
Für jede definierte Variable in der Variablenliste hängen Sie "." an die Ergebniszeichenkette an und führen dann Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im nicht reservierten Satz sind.
Da "." im nicht reservierten Satz ist, hat ein Wert, der einen "." enthält, den Effekt, mehrere Labels hinzuzufügen.
Beispiel-Template Expansion
{.who} .fred
{.who,who} .fred.fred
{.half,who} .50%25.fred
www{.dom*} www.example.com
X{.var} X.value
X{.empty} X.
X{.undef} X
X{.var:3} X.val
X{.list} X.red,green,blue
X{.list*} X.red.green.blue
X{.keys} X.semi,%3B,dot,.,comma,%2C
X{.keys*} X.semi=%3B.dot=..comma=%2C
X{.empty_keys} X
X{.empty_keys*} X
3.2.6. Path Segment Expansion: {/var} (Pfadsegment-Expansion)
Pfadsegment-Expansion, angezeigt durch den Schrägstrich ("/") Operator in Level-3- und höheren Templates, ist nützlich für die Beschreibung von URI-Pfadhierarchien.
Für jede definierte Variable in der Variablenliste hängen Sie "/" an die Ergebniszeichenkette an und führen dann Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im nicht reservierten Satz sind.
Beachten Sie, dass der Expansionsprozess für Pfadsegment-Expansion identisch mit dem der Label-Expansion ist, abgesehen von der Substitution von "/" anstelle von ".". Im Gegensatz zu "." ist "/" jedoch ein reserviertes Zeichen und wird prozentkodiert, wenn es in einem Wert gefunden wird.
Beispiel-Template Expansion
{/who} /fred
{/who,who} /fred/fred
{/half,who} /50%25/fred
{/who,dub} /fred/me%2Ftoo
{/var} /value
{/var,empty} /value/
{/var,undef} /value
{/var,x}/here /value/1024/here
{/var:1,var} /v/value
{/list} /red,green,blue
{/list*} /red/green/blue
{/list*,path:4} /red/green/blue/%2Ffoo
{/keys} /semi,%3B,dot,.,comma,%2C
{/keys*} /semi=%3B/dot=./comma=%2C
3.2.7. Path-Style Parameter Expansion: {;var} (Pfad-Stil-Parameter-Expansion)
Pfad-Stil-Parameter-Expansion, angezeigt durch den Semikolon (";") Operator in Level-3- und höheren Templates, ist nützlich für die Beschreibung von URI-Pfadparametern, wie "path;property" oder "path;name=value".
Für jede definierte Variable in der Variablenliste:
- hängen Sie ";" an die Ergebniszeichenkette an;
- wenn die Variable einen einfachen Zeichenkettenwert hat oder kein Explode-Modifikator angegeben ist, dann:
- hängen Sie den Variablennamen (kodiert, als wäre es eine literale Zeichenkette) an die Ergebniszeichenkette an;
- wenn der Wert der Variable nicht leer ist, hängen Sie "=" an die Ergebniszeichenkette an;
- führen Sie Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im nicht reservierten Satz sind.
Beispiel-Template Expansion
{;who} ;who=fred
{;half} ;half=50%25
{;empty} ;empty
{;v,empty,who} ;v=6;empty;who=fred
{;v,bar,who} ;v=6;who=fred
{;x,y} ;x=1024;y=768
{;x,y,empty} ;x=1024;y=768;empty
{;x,y,undef} ;x=1024;y=768
{;hello:5} ;hello=Hello
{;list} ;list=red,green,blue
{;list*} ;list=red;list=green;list=blue
{;keys} ;keys=semi,%3B,dot,.,comma,%2C
{;keys*} ;semi=%3B;dot=.;comma=%2C
3.2.8. Form-Style Query Expansion: {?var} (Formular-Stil-Abfrage-Expansion)
Formular-Stil-Abfrage-Expansion, angezeigt durch den Fragezeichen ("?") Operator in Level-3- und höheren Templates, ist nützlich für die Beschreibung einer gesamten optionalen Abfragekomponente.
Für jede definierte Variable in der Variablenliste:
- hängen Sie "?" an die Ergebniszeichenkette an, wenn dies der erste definierte Wert ist, oder hängen Sie danach "&" an;
- wenn die Variable einen einfachen Zeichenkettenwert hat oder kein Explode-Modifikator angegeben ist, hängen Sie den Variablennamen (kodiert, als wäre es eine literale Zeichenkette) und ein Gleichheitszeichen ("=") an die Ergebniszeichenkette an; und,
- führen Sie Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im nicht reservierten Satz sind.
Beispiel-Template Expansion
{?who} ?who=fred
{?half} ?half=50%25
{?x,y} ?x=1024&y=768
{?x,y,empty} ?x=1024&y=768&empty=
{?x,y,undef} ?x=1024&y=768
{?var:3} ?var=val
{?list} ?list=red,green,blue
{?list*} ?list=red&list=green&list=blue
{?keys} ?keys=semi,%3B,dot,.,comma,%2C
{?keys*} ?semi=%3B&dot=.&comma=%2C
3.2.9. Form-Style Query Continuation: {&var} (Formular-Stil-Abfrage-Fortsetzung)
Formular-Stil-Abfrage-Fortsetzung, angezeigt durch den Und-Zeichen ("&") Operator in Level-3- und höheren Templates, ist nützlich für die Beschreibung optionaler &name=value Paare in einem Template, das bereits eine literale Abfragekomponente mit festen Parametern enthält.
Für jede definierte Variable in der Variablenliste:
- hängen Sie "&" an die Ergebniszeichenkette an;
- wenn die Variable einen einfachen Zeichenkettenwert hat oder kein Explode-Modifikator angegeben ist, hängen Sie den Variablennamen (kodiert, als wäre es eine literale Zeichenkette) und ein Gleichheitszeichen ("=") an die Ergebniszeichenkette an; und,
- führen Sie Variablenexpansion durch, wie in Abschnitt 3.2.1 definiert, wobei die erlaubten Zeichen diejenigen im nicht reservierten Satz sind.
Beispiel-Template Expansion
{&who} &who=fred
{&half} &half=50%25
?fixed=yes{&x} ?fixed=yes&x=1024
{&x,y,empty} &x=1024&y=768&empty=
{&x,y,undef} &x=1024&y=768
{&var:3} &var=val
{&list} &list=red,green,blue
{&list*} &list=red&list=green&list=blue
{&keys} &keys=semi,%3B,dot,.,comma,%2C
{&keys*} &semi=%3B&dot=.&comma=%2C
4. Security Considerations (Sicherheitsüberlegungen)
Eine URI-Vorlage enthält keinen aktiven oder ausführbaren Inhalt. Es könnte jedoch möglich sein, unerwartete URIs zu erstellen, wenn ein Angreifer die Kontrolle über die Vorlage oder über die Variablenwerte innerhalb eines Ausdrucks erhält, der reservierte Zeichen in der Expansion zulässt. In beiden Fällen werden die Sicherheitsüberlegungen weitgehend dadurch bestimmt, wer die Vorlage bereitstellt, wer die Werte für Variablen innerhalb der Vorlage bereitstellt, in welchem Ausführungskontext die Expansion stattfindet (Client oder Server) und wo die resultierenden URIs verwendet werden.
Diese Spezifikation schränkt nicht ein, wo URI-Vorlagen verwendet werden könnten. Aktuelle Implementierungen existieren innerhalb von serverseitigen Entwicklungs-Frameworks und innerhalb von clientseitigem JavaScript für berechnete Links oder Formulare.
Innerhalb von Frameworks fungieren Vorlagen normalerweise als Leitfäden dafür, wo Daten in späteren (Anforderungszeit-)URIs in Client-Anforderungen auftreten könnten. Daher liegen die Sicherheitsbedenken nicht in den Vorlagen selbst, sondern vielmehr darin, wie der Server die vom Benutzer bereitgestellten Daten in einer normalen Web-Anforderung extrahiert und verarbeitet.
Innerhalb clientseitiger Implementierungen hat eine URI-Vorlage viele der gleichen Eigenschaften wie HTML-Formulare, außer dass sie auf URI-Zeichen beschränkt ist und möglicherweise in HTTP-Header-Feldwerten anstatt nur im Nachrichteninhalt enthalten ist. Es sollte darauf geachtet werden, dass potenziell gefährliche URI-Referenzzeichenketten, wie solche, die mit "javascript:" beginnen, nicht in der Expansion erscheinen, es sei denn, sowohl die Vorlage als auch die Werte werden von einer vertrauenswürdigen Quelle bereitgestellt.
Andere Sicherheitsüberlegungen sind die gleichen wie die für URIs, wie in Abschnitt 7 von [RFC3986] beschrieben.
Appendix A. Implementation Hints (Implementierungshinweise)
Die normativen Abschnitte zur Expansion beschreiben jeden Operator mit einem separaten Expansionsprozess zur deskriptiven Klarheit. In tatsächlichen Implementierungen erwarten wir, dass die Ausdrücke von links nach rechts unter Verwendung eines gemeinsamen Algorithmus verarbeitet werden, der nur geringe Prozessvariationen pro Operator aufweist. Dieser nicht-normative Anhang beschreibt einen solchen Algorithmus.
Initialisieren Sie eine leere Ergebniszeichenkette und ihren Nicht-Fehlerzustand.
Scannen Sie die Vorlage und kopieren Sie Literale in die Ergebniszeichenkette (wie in Abschnitt 3.1), bis ein Ausdruck durch ein "{" angezeigt wird, ein Fehler durch das Vorhandensein eines Nicht-Literal-Zeichens außer "{" angezeigt wird oder die Vorlage endet. Wenn sie endet, geben Sie die Ergebniszeichenkette und ihren aktuellen Fehler- oder Nicht-Fehlerzustand zurück.
- Wenn ein Ausdruck gefunden wird, scannen Sie die Vorlage bis zum nächsten
"}"und extrahieren Sie die Zeichen zwischen den Klammern. - Wenn die Vorlage vor einem
"}"endet, hängen Sie dann das"{"und die extrahierten Zeichen an die Ergebniszeichenkette an und kehren mit einem Fehlerstatus zurück, der anzeigt, dass der Ausdruck fehlerhaft ist.
Untersuchen Sie das erste Zeichen des extrahierten Ausdrucks auf einen Operator.
- Wenn der Ausdruck endete (d.h. ist "{}"), ein unbekannter oder nicht implementierter Operator gefunden wird oder das Zeichen nicht im varchar-Satz ist (Abschnitt 2.3), dann hängen Sie
"{", den extrahierten Ausdruck und"}"an die Ergebniszeichenkette an, merken Sie sich, dass das Ergebnis in einem Fehlerzustand ist, und kehren dann zum Scannen des Rests der Vorlage zurück. - Wenn ein bekannter und implementierter Operator gefunden wird, speichern Sie den Operator und springen zum nächsten Zeichen, um die varspec-Liste zu beginnen.
- Andernfalls speichern Sie den Operator als NUL (einfache Zeichenkettenexpansion).
Verwenden Sie die folgende Wertetabelle, um das Verarbeitungsverhalten nach Ausdruckstyp-Operator zu bestimmen. Der Eintrag für "first" ist die Zeichenkette, die zuerst an das Ergebnis angehängt werden soll, wenn eine der Variablen des Ausdrucks definiert ist. Der Eintrag für "sep" ist das Trennzeichen, das vor jeder zweiten (oder nachfolgenden) definierten Variablenexpansion an das Ergebnis angehängt werden soll. Der Eintrag für "named" ist ein boolescher Wert dafür, ob die Expansion den Variablen- oder Schlüsselnamen enthält, wenn kein Explode-Modifikator gegeben ist. Der Eintrag für "ifemp" ist eine Zeichenkette, die an den Namen angehängt werden soll, wenn sein entsprechender Wert leer ist. Der Eintrag für "allow" gibt an, welche Zeichen innerhalb der Wertexpansion unkodiert erlaubt sind: (U) bedeutet, dass jedes Zeichen, das nicht im nicht reservierten Satz ist, kodiert wird; (U+R) bedeutet, dass jedes Zeichen, das nicht in der Vereinigung von (unreserved / reserved / pct-encoding) ist, kodiert wird; und für beide Fälle wird jedes nicht erlaubte Zeichen zuerst als seine Oktettsequenz in UTF-8 kodiert und dann wird jedes solche Oktett als prozentkodiertes Triplet kodiert.
┌──────────────────────────────────────────────────────────────┐
│ NUL + . / ; ? & #│
├──────────────────────────────────────────────────────────────┤
│ first │ "" "" "." "/" ";" "?" "&" "#"│
│ sep │ "," "," "." "/" ";" "&" "&" "," │
│ named │ false false false false true true true false│
│ ifemp │ "" "" "" "" "" "=" "=" "" │
│ allow │ U U+R U U U U U U+R │
└──────────────────────────────────────────────────────────────┘
Mit der obigen Tabelle im Hinterkopf verarbeiten Sie die Variablenliste wie folgt:
Für jedes varspec extrahieren Sie einen Variablennamen und optionalen Modifikator aus dem Ausdruck, indem Sie die Variablenliste scannen, bis ein Zeichen gefunden wird, das nicht im varname-Satz ist, oder das Ende des Ausdrucks erreicht wird.
- Wenn es das Ende des Ausdrucks ist und der varname leer ist, kehren Sie zum Scannen des Rests der Vorlage zurück.
- Wenn es nicht das Ende des Ausdrucks ist und das zuletzt gefundene Zeichen einen Modifikator anzeigt ("" oder ":"), merken Sie sich diesen Modifikator. Wenn es ein Explode ("") ist, scannen Sie das nächste Zeichen. Wenn es ein Präfix (":") ist, fahren Sie fort, die nächsten ein bis vier Zeichen für die als Dezimalzahl dargestellte max-length zu scannen, und dann, wenn es immer noch nicht das Ende des Ausdrucks ist, scannen Sie das nächste Zeichen.
- Wenn es nicht das Ende des Ausdrucks ist und das zuletzt gefundene Zeichen kein Komma (",") ist, hängen Sie
"{", den gespeicherten Operator (falls vorhanden), den gescannten varname und Modifikator, den verbleibenden Ausdruck und"}"an die Ergebniszeichenkette an, merken Sie sich, dass das Ergebnis in einem Fehlerzustand ist, und kehren dann zum Scannen des Rests der Vorlage zurück.
Suchen Sie den Wert für den gescannten Variablennamen und dann
- Wenn der varname unbekannt ist oder einer Variable mit einem undefinierten Wert entspricht (Abschnitt 2.3), dann springen Sie zum nächsten varspec.
- Wenn dies die erste definierte Variable für diesen Ausdruck ist, hängen Sie die first-Zeichenkette für diesen Ausdruckstyp an die Ergebniszeichenkette an und merken Sie sich, dass es getan wurde. Andernfalls hängen Sie die sep-Zeichenkette an die Ergebniszeichenkette an.
- Wenn der Wert dieser Variable eine Zeichenkette ist, dann
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- wenn der Wert leer ist, hängen Sie die ifemp-Zeichenkette an die Ergebniszeichenkette an und springen zum nächsten varspec;
- andernfalls hängen Sie "=" an die Ergebniszeichenkette an.
- wenn ein Präfix-Modifikator vorhanden ist und die Präfixlänge kleiner ist als die Wertzeichenkettenlänge in Anzahl von Unicode-Zeichen, hängen Sie diese Anzahl von Zeichen vom Anfang der Wertzeichenkette an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, wobei Sie darauf achten, Mehroktett- oder prozentkodierte Triplettzeichen, die einen einzelnen Unicode-Codepunkt darstellen, nicht zu teilen;
- andernfalls hängen Sie den Wert an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben.
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- andernfalls, wenn kein Explode-Modifikator gegeben ist, dann
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- wenn der Wert leer ist, hängen Sie die ifemp-Zeichenkette an die Ergebniszeichenkette an und springen zum nächsten varspec;
- andernfalls hängen Sie "=" an die Ergebniszeichenkette an; und
- wenn der Wert dieser Variable eine Liste ist, hängen Sie jedes definierte Listenmitglied an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit einem Komma (","), das zwischen jedem definierten Listenmitglied an das Ergebnis angehängt wird;
- wenn der Wert dieser Variable ein assoziatives Array oder eine andere Form einer gepaarten (name, value) Struktur ist, hängen Sie jedes Paar mit einem definierten Wert an die Ergebniszeichenkette als "name,value" an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit einem Komma (","), das zwischen jedem definierten Paar an das Ergebnis angehängt wird.
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- andernfalls, wenn ein Explode-Modifikator gegeben ist, dann
- wenn named true ist, dann für jedes definierte Listenmitglied oder Array (name, value) Paar mit einem definierten Wert, tun Sie:
- wenn dies nicht das erste definierte Mitglied/Wert ist, hängen Sie die sep-Zeichenkette an die Ergebniszeichenkette an;
- wenn dies eine Liste ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an;
- wenn dies ein Paar ist, hängen Sie den name an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an;
- wenn das Mitglied/Wert leer ist, hängen Sie die ifemp-Zeichenkette an die Ergebniszeichenkette an; andernfalls hängen Sie "=" und das Mitglied/Wert an die Ergebniszeichenkette an, nachdem Sie alle Mitglied/Wert-Zeichen, die nicht im allow-Satz sind, prozentkodiert haben.
- andernfalls, wenn named false ist, dann
- wenn dies eine Liste ist, hängen Sie jedes definierte Listenmitglied an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit der sep-Zeichenkette, die zwischen jedem definierten Listenmitglied an das Ergebnis angehängt wird.
- wenn dies ein Array von (name, value) Paaren ist, hängen Sie jedes Paar mit einem definierten Wert an die Ergebniszeichenkette als "name=value" an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit der sep-Zeichenkette, die zwischen jedem definierten Paar an das Ergebnis angehängt wird.
- wenn named true ist, dann für jedes definierte Listenmitglied oder Array (name, value) Paar mit einem definierten Wert, tun Sie:
Wenn die Variablenliste für diesen Ausdruck erschöpft ist, kehren Sie zum Scannen des Rests der Vorlage zurück.