Aller au contenu principal

RFC 6570 - Modèles d'URI

  • Statut: Proposed Standard
  • Publié: March 2012
  • Stream: IETF
  • Errata: Pas d'errata

Résumé (Abstract)​

Un modèle d'URI (URI Template) est une séquence compacte de caractères permettant de décrire une plage d'identificateurs de ressources uniformes (Uniform Resource Identifiers) par l'expansion de variables. Cette spécification définit la syntaxe des modèles d'URI et le processus d'expansion d'un modèle d'URI en référence d'URI, ainsi que des directives pour l'utilisation des modèles d'URI sur Internet.


Table des matières (Contents)​

  • 1. Introduction
    • 1.1. Overview (Vue d'ensemble)
    • 1.2. Levels and Expression Types (Niveaux et types d'expressions)
    • 1.3. Design Considerations (Considérations de conception)
    • 1.4. Limitations
    • 1.5. Notational Conventions (Conventions de notation)
    • 1.6. Character Encoding and Unicode Normalization (Encodage des caractères et normalisation Unicode)
  • 2. Syntax (Syntaxe)
    • 2.1. Literals (Littéraux)
    • 2.2. Expressions
    • 2.3. Variables
    • 2.4. Value Modifiers (Modificateurs de valeur)
      • 2.4.1. Prefix Values (Valeurs de préfixe)
      • 2.4.2. Composite Values (Valeurs composites)
  • 3. Expansion
    • 3.1. Literal Expansion (Expansion des littéraux)
    • 3.2. Expression Expansion (Expansion des expressions)
      • 3.2.1. Variable Expansion (Expansion des variables)
      • 3.2.2. Simple String Expansion: {var} (Expansion de chaîne simple)
      • 3.2.3. Reserved Expansion: {+var} (Expansion avec caractères réservés)
      • 3.2.4. Fragment Expansion: {#var} (Expansion de fragment)
      • 3.2.5. Label Expansion with Dot-Prefix: {.var} (Expansion d'étiquette avec préfixe point)
      • 3.2.6. Path Segment Expansion: {/var} (Expansion de segment de chemin)
      • 3.2.7. Path-Style Parameter Expansion: {;var} (Expansion de paramètre de style chemin)
      • 3.2.8. Form-Style Query Expansion: {?var} (Expansion de requête de style formulaire)
      • 3.2.9. Form-Style Query Continuation: {&var} (Continuation de requête de style formulaire)
  • 4. Security Considerations (Considérations de sécurité)
  • 5. Acknowledgments (Remerciements)
  • 6. References (Références)
    • 6.1. Normative References (Références normatives)
    • 6.2. Informative References (Références informatives)

Annexes (Appendices)​


Ressources connexes​



2. Syntax (Syntaxe)​

Un modèle d'URI est une chaîne de caractères Unicode imprimables contenant zéro ou plusieurs expressions de variables (Variable Expressions) intégrées, chaque expression étant délimitée par une paire correspondante d'accolades ('{', '}').

URI-Template  = *( literals / expression )

Bien que les modèles (et les implémentations de processeurs de modèles) soient décrits ci-dessus en termes de quatre niveaux progressifs, nous définissons la syntaxe URI-Template en termes d'ABNF pour le Level 4. Un processeur de modèle limité aux modèles de niveau inférieur PEUT (MAY) exclure les règles ABNF applicables uniquement aux niveaux supérieurs. Cependant, il est RECOMMANDÉ (RECOMMENDED) que tous les analyseurs implémentent la syntaxe complète afin que les niveaux non pris en charge puissent être correctement identifiés comme tels à l'utilisateur final.

2.1. Literals (Littéraux)​

Les caractères en dehors des expressions dans une chaîne de modèle d'URI sont destinés à être copiés littéralement dans la référence URI si le caractère est autorisé dans un URI (reserved / unreserved / pct-encoded) ou, s'il n'est pas autorisé, copié dans la référence URI en tant que séquence de triplets encodés en pourcentage correspondant à l'encodage de ce caractère en UTF-8 [RFC3629].

literals      =  %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B
/ %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate
/ pct-encoded
; tout caractère Unicode sauf : CTL, SP,
; DQUOTE, "'", "%" (hormis pct-encoded),
; "<", ">", "\", "^", "`", "{", "|", "}"

2.2. Expressions​

Les expressions de modèle sont les parties paramétrées d'un modèle d'URI. Chaque expression contient un opérateur optionnel (Operator) qui définit le type d'expression et son processus d'expansion correspondant, suivi d'une liste séparée par des virgules de spécificateurs de variables (Variable Specifiers) (noms de variables et modificateurs de valeur optionnels). Si aucun opérateur n'est fourni, l'expression par défaut est une expansion de variable simple de valeurs non réservées.

expression    =  "{" [ operator ] variable-list "}"
operator = op-level2 / op-level3 / op-reserve
op-level2 = "+" / "#"
op-level3 = "." / "/" / ";" / "?" / "&"
op-reserve = "=" / "," / "!" / "@" / "|"

Les caractères d'opérateur ont été choisis pour refléter chacun de leurs rôles en tant que caractères réservés dans la syntaxe générique URI. Les opérateurs définis dans la section 3 de cette spécification incluent :

  • + Chaînes de caractères réservées (Reserved character strings)
  • # Identificateurs de fragment préfixés par "#" (Fragment identifiers)
  • . Étiquettes de nom ou extensions préfixées par "." (Name labels or extensions)
  • / Segments de chemin préfixés par "/" (Path segments)
  • ; Nom de paramètre de chemin ou paires name=value préfixées par ";" (Path parameter name or name=value pairs)
  • ? Composant de requête commençant par "?" et constitué de paires name=value séparées par "&" (Query component)
  • & Continuation de paires &name=value de style requête dans un composant de requête littéral (Continuation of query-style pairs)

Les caractères d'opérateur égal ("="), virgule (","), point d'exclamation ("!"), arobase ("@") et pipe ("|") sont réservés pour les extensions futures.

La syntaxe d'expression exclut spécifiquement l'utilisation du dollar ("$") et des parenthèses ["(" et ")"] afin qu'ils restent disponibles pour une utilisation en dehors du champ d'application de cette spécification. Par exemple, un langage de macros pourrait utiliser ces caractères pour appliquer une substitution de macro à une chaîne avant que cette chaîne ne soit traitée comme un modèle d'URI.

2.3. Variables​

Après l'opérateur (le cas échéant), chaque expression contient une liste d'un ou plusieurs spécificateurs de variables (varspec) séparés par des virgules. Les noms de variables servent plusieurs objectifs : documentation sur les types de valeurs attendues, identificateurs pour associer des valeurs dans un processeur de modèle, et chaîne littérale à utiliser pour le nom dans les expansions name=value (sauf lors de l'explosion d'un tableau associatif). Les noms de variables sont sensibles à la casse car le nom peut être expansé dans un composant URI sensible à la casse.

variable-list =  varspec *( "," varspec )
varspec = varname [ modifier-level4 ]
varname = varchar *( ["."] varchar )
varchar = ALPHA / DIGIT / "_" / pct-encoded

Un varname PEUT (MAY) contenir un ou plusieurs triplets encodés en pourcentage. Ces triplets sont considérés comme une partie essentielle du nom de variable et ne sont pas décodés pendant le traitement. Un varname contenant des caractères encodés en pourcentage n'est pas la même variable qu'un varname avec ces mêmes caractères décodés. Les applications qui fournissent des modèles d'URI sont censées être cohérentes dans leur utilisation de l'encodage en pourcentage dans les noms de variables.

Une expression PEUT (MAY) référencer des variables inconnues du processeur de modèle ou dont la valeur est définie sur une valeur spéciale "undefined (indéfinie)" telle que undef ou null. Ces variables indéfinies reçoivent un traitement spécial par le processus d'expansion (Section 3.2.1).

Une valeur de variable qui est une chaîne de longueur zéro n'est pas considérée comme indéfinie ; elle a la valeur définie d'une chaîne vide.

Dans les modèles Level 4, une variable peut avoir une valeur composite (Composite Value) sous forme de liste de valeurs ou de tableau associatif de paires (name, value). Ces types de valeurs ne sont pas directement indiqués par la syntaxe du modèle, mais ils ont un impact sur le processus d'expansion (Section 3.2.1).

Une variable définie comme une valeur de liste est considérée comme indéfinie si la liste contient zéro membre. Une variable définie comme un tableau associatif de paires (name, value) est considérée comme indéfinie si le tableau contient zéro membre ou si tous les noms de membres dans le tableau sont associés à des valeurs indéfinies.

2.4. Value Modifiers (Modificateurs de valeur)​

Chacune des variables dans une expression de modèle Level 4 peut avoir un modificateur indiquant soit que son expansion est limitée à un préfixe de la chaîne de valeur de la variable, soit que son expansion est explosée comme une valeur composite sous forme de liste de valeurs ou de tableau associatif de paires (name, value).

modifier-level4 =  prefix / explode

2.4.1. Prefix Values (Valeurs de préfixe)​

Un modificateur de préfixe (Prefix Modifier) indique que l'expansion de la variable est limitée à un préfixe de la chaîne de valeur de la variable. Les modificateurs de préfixe sont souvent utilisés pour partitionner un espace d'identificateurs de manière hiérarchique, comme c'est courant dans les indices de référence et le stockage basé sur le hachage. Il sert également à limiter la valeur expansée à un nombre maximum de caractères. Les modificateurs de préfixe ne sont pas applicables aux variables qui ont des valeurs composites.

prefix        =  ":" max-length
max-length = %x31-39 0*3DIGIT ; entier positif < 10000

Le max-length est un entier positif qui fait référence à un nombre maximum de caractères depuis le début de la valeur de la variable en tant que chaîne Unicode. Notez que cette numérotation est en caractères, pas en octets, afin d'éviter de diviser entre les octets d'un caractère codé en multi-octets ou dans un triplet encodé en pourcentage. Si le max-length est supérieur à la longueur de la valeur de la variable, la chaîne de valeur entière est utilisée.

Par exemple :

Avec les affectations de variables

var := "value"
semi := ";"

Exemple de modèle Expansion

{var} value
{var:20} value
{var:3} val
{semi} %3B
{semi:2} %3B

2.4.2. Composite Values (Valeurs composites)​

Un modificateur d'explosion (Explode Modifier) ("*") indique que la variable doit être traitée comme une valeur composite composée soit d'une liste de valeurs, soit d'un tableau associatif de paires (name, value). Par conséquent, le processus d'expansion est appliqué à chaque membre du composite comme s'il était répertorié comme une variable distincte. Ce type de spécification de variable est nettement moins auto-documenté que les variables non explosées, car il y a moins de correspondance entre le nom de la variable et la manière dont la référence URI apparaît après l'expansion.

explode       =  "*"

Étant donné que les modèles d'URI ne contiennent pas d'indication de type ou de schéma, le type d'une variable explosée est supposé être déterminé par le contexte. Par exemple, le processeur peut se voir fournir des valeurs sous une forme qui différencie les valeurs en tant que chaînes, listes ou tableaux associatifs. De même, le contexte dans lequel le modèle est utilisé (script, langage de balisage, langage de définition d'interface, etc.) peut définir des règles pour associer les noms de variables aux types, structures ou schémas.

Les modificateurs d'explosion améliorent la concision de la syntaxe du modèle d'URI. Par exemple, une ressource qui fournit une carte géographique pour une adresse de rue donnée pourrait accepter une centaine de permutations sur les champs d'entrée d'adresse, y compris des adresses partielles (par exemple, juste la ville ou le code postal). Une telle ressource pourrait être décrite comme un modèle avec chaque composant d'adresse répertorié dans l'ordre, ou avec un modèle beaucoup plus simple qui utilise un modificateur d'explosion, comme dans :

/mapper{?address*}

avec un contexte qui définit ce que la variable nommée "address" peut inclure, par exemple par référence à une autre norme d'adressage (par exemple, [UPU-S42]). Un destinataire connaissant le schéma peut alors fournir des expansions appropriées, telles que :

/mapper?city=Newport%20Beach&state=CA

Le processus d'expansion pour les variables explosées dépend à la fois de l'opérateur utilisé et du fait que la valeur composite soit traitée comme une liste de valeurs ou comme un tableau associatif de paires (name, value). Les structures sont traitées comme un tableau associatif avec des noms correspondant aux champs de la définition de structure et des séparateurs "." utilisés pour indiquer la hiérarchie des noms dans les sous-structures.

Si une variable a une structure composite et que seuls certains champs de cette structure ont des valeurs définies, alors seules les paires définies sont présentes dans l'expansion. Cela peut être utile pour les modèles composés d'un grand nombre de termes de requête potentiels.

Un modificateur d'explosion appliqué à une variable de liste provoque l'expansion pour répéter l'expansion de cette variable selon l'opérateur, une fois pour chaque membre de la liste.



3. Expansion (Expansion)​

Le processus d'expansion de modèle URI consiste à parcourir la chaîne de modèle du début à la fin, à copier les caractères littéraux et à remplacer chaque expression par le résultat de l'application de l'opérateur de l'expression à la valeur de chaque variable nommée dans l'expression. La valeur de chaque variable DOIT (MUST) être formée avant l'expansion du modèle.

Cette section définit les exigences d'expansion pour chaque aspect de la grammaire de modèle URI. Un algorithme non normatif pour le processus d'expansion dans son ensemble est fourni dans l'annexe A.

Si un processeur de modèle rencontre une séquence de caractères en dehors d'une expression qui ne correspond pas à la grammaire <URI-Template>, alors le traitement du modèle DEVRAIT (SHOULD) cesser, le résultat de référence URI DEVRAIT (SHOULD) contenir la partie expansée du modèle suivie du reste non expansé, et l'emplacement et le type d'erreur DEVRAIENT (SHOULD) être indiqués à l'application appelante.

Si une erreur est rencontrée dans une expression, telle qu'un opérateur ou un modificateur de valeur que le processeur de modèle ne reconnaît pas ou ne supporte pas encore, ou si un caractère n'est pas autorisé par la grammaire <expression>, alors les parties non traitées de l'expression DEVRAIENT (SHOULD) être copiées dans le résultat non expansé, le traitement du reste du modèle DEVRAIT (SHOULD) continuer, et l'emplacement et le type d'erreur DEVRAIENT (SHOULD) être indiqués à l'application appelante.

Si une erreur se produit, le résultat retourné peut ne pas être une référence URI valide ; ce sera une chaîne de modèle incomplètement expansée destinée uniquement à des fins de diagnostic.

3.1. Literal Expansion (Expansion littérale)​

Si le caractère littéral est autorisé n'importe où dans la syntaxe URI (unreserved / reserved / pct-encoded), il est alors copié directement dans la chaîne de résultat. Sinon, l'équivalent encodé en pourcentage du caractère littéral est copié dans la chaîne de résultat en encodant d'abord le caractère comme sa séquence d'octets en UTF-8, puis en encodant chaque octet comme un triplet encodé en pourcentage.

3.2. Expression Expansion (Expansion d'expression)​

Chaque expression est indiquée par un caractère accolade ouvrante ("{") et continue jusqu'à l'accolade fermante suivante ("}"). Les expressions ne peuvent pas être imbriquées.

L'expansion d'une expression se fait en déterminant son type d'expression, puis en suivant le processus d'expansion de ce type pour chaque varspec séparé par une virgule dans l'expression. Les modèles de niveau 1 sont limités à l'opérateur par défaut (expansion de valeur de chaîne simple) et une seule variable par expression. Les modèles de niveau 2 sont limités à un seul varspec par expression.

Le type d'expression est déterminé en regardant le premier caractère après l'accolade ouvrante. Si le caractère est un opérateur, alors on mémorise le type d'expression associé à cet opérateur pour les décisions d'expansion ultérieures et on passe au caractère suivant pour la liste de variables. Si le premier caractère n'est pas un opérateur, alors le type d'expression est l'expansion de chaîne simple et le premier caractère est le début de la liste de variables.

Les exemples dans les sous-sections ci-dessous utilisent les définitions de valeurs de variables suivantes :

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 (Expansion de variable)​

Une variable non définie (Section 2.3) n'a pas de valeur et est ignorée par le processus d'expansion. Si toutes les variables d'une expression sont non définies, alors l'expansion de l'expression est la chaîne vide.

L'expansion de variable d'une valeur définie et non vide résulte en une sous-chaîne de caractères URI autorisés. Comme décrit dans la Section 1.6, le processus d'expansion est défini en termes de points de code Unicode afin de garantir que les caractères non-ASCII sont encodés en pourcentage de manière cohérente dans la référence URI résultante. Une façon pour un processeur de modèle d'obtenir une expansion cohérente est de transcoder la chaîne de valeur en UTF-8 (si ce n'est pas déjà le cas) puis de transformer chaque octet qui n'est pas dans l'ensemble autorisé en triplet encodé en pourcentage correspondant.

L'ensemble autorisé pour une expansion donnée dépend du type d'expression : les expansions réservées ("+") et de fragment ("#") autorisent l'ensemble de caractères dans l'union de (unreserved / reserved / pct-encoded) à passer sans encodage en pourcentage, tandis que tous les autres types d'expression n'autorisent que les caractères non réservés à passer sans encodage en pourcentage. Notez que le caractère pourcentage ("%") n'est autorisé que comme partie d'un triplet encodé en pourcentage et uniquement pour l'expansion réservée/fragment : dans tous les autres cas, un caractère de valeur "%" DOIT (MUST) être encodé en pourcentage comme "%25" par l'expansion de variable.

Si une variable apparaît plus d'une fois dans une expression ou dans plusieurs expressions d'un modèle URI, la valeur de cette variable DOIT (MUST) rester statique tout au long du processus d'expansion (c'est-à-dire que la variable doit avoir la même valeur aux fins du calcul de chaque expansion). Cependant, si des caractères réservés ou des triplets encodés en pourcentage apparaissent dans la valeur, ils seront encodés en pourcentage par certains types d'expression et pas par d'autres.

Pour une variable qui est une valeur de chaîne simple, l'expansion consiste à ajouter la valeur encodée à la chaîne de résultat. Un modificateur d'explosion n'a aucun effet. Un modificateur de préfixe limite l'expansion aux premiers max-length caractères de la valeur décodée. Si la valeur contient des caractères multi-octets ou encodés en pourcentage, il faut veiller à ne pas diviser la valeur au milieu d'un caractère : comptez chaque point de code Unicode comme un caractère.

Pour une variable qui est un tableau associatif, l'expansion dépend à la fois du type d'expression et de la présence d'un modificateur d'explosion. S'il n'y a pas de modificateur d'explosion, l'expansion consiste à ajouter une concaténation séparée par des virgules de chaque paire (name, value) qui a une valeur définie. S'il y a un modificateur d'explosion, l'expansion consiste à ajouter chaque paire qui a une valeur définie sous la forme "name=value" ou, si la valeur est la chaîne vide et que le type d'expression n'indique pas de paramètres de style formulaire (c'est-à-dire, pas un type "?" ou "&"), simplement "name". Les chaînes name et value sont toutes deux encodées de la même manière que les valeurs de chaîne simples. Une chaîne de séparateur est ajoutée entre les paires définies selon le type d'expression, comme défini par le tableau suivant :

Type    Séparateur
"," (par défaut)
+ ","
# ","
. "."
/ "/"
; ";"
? "&"
& "&"

Pour une variable qui est une valeur de liste, s'il n'y a pas de modificateur d'explosion, l'expansion consiste à ajouter une concaténation séparée par des virgules de chaque valeur de membre de liste qui a une valeur définie, en tant que valeur d'un seul nom pour cette variable. S'il y a un modificateur d'explosion, l'expansion consiste à ajouter chaque valeur de membre de liste qui a une valeur définie en tant que valeur séparée avec le nom de cette variable, ou, pour les types d'expression qui n'ont pas de variables nommées (pas de ";", "?" ou "&"), simplement ajouter chaque valeur séparée par le séparateur spécifique au type.

Un modificateur de préfixe sur une valeur de liste ou une valeur de tableau associatif n'a aucun effet.

3.2.2. Simple String Expansion: {var} (Expansion de chaîne simple)​

L'expansion de chaîne simple est le type d'expression par défaut lorsqu'aucun opérateur n'est donné.

Pour chaque variable définie dans la liste de variables, effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble non réservé. Si plus d'une variable a une valeur définie, ajoutez une virgule (",") à la chaîne de résultat comme séparateur entre les expansions de variables.

Exemple de modèle     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} (Expansion réservée)​

L'expansion réservée, indiquée par l'opérateur plus ("+") pour les modèles de niveau 2 et supérieur, est identique à l'expansion de chaîne simple, sauf que les valeurs substituées peuvent également contenir des triplets encodés en pourcentage et des caractères dans l'ensemble réservé.

Pour chaque variable définie dans la liste de variables, effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble (unreserved / reserved / pct-encoded). Si plus d'une variable a une valeur définie, ajoutez une virgule (",") à la chaîne de résultat comme séparateur entre les expansions de variables.

Exemple de modèle          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} (Expansion de fragment)​

L'expansion de fragment, indiquée par l'opérateur dièse ("#") pour les modèles de niveau 2 et supérieur, est identique à l'expansion réservée, sauf qu'un caractère dièse (délimiteur de fragment) est d'abord ajouté à la chaîne de résultat si l'une des variables est définie.

Exemple de modèle     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} (Expansion d'étiquette avec préfixe point)​

L'expansion d'étiquette, indiquée par l'opérateur point (".") pour les modèles de niveau 3 et supérieur, est utile pour décrire les espaces URI avec des noms de domaine variables ou des sélecteurs de chemin (par exemple, extensions de fichier).

Pour chaque variable définie dans la liste de variables, ajoutez "." à la chaîne de résultat, puis effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble non réservé.

Puisque "." est dans l'ensemble non réservé, une valeur qui contient un "." a l'effet d'ajouter plusieurs étiquettes.

Exemple de modèle     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} (Expansion de segment de chemin)​

L'expansion de segment de chemin, indiquée par l'opérateur barre oblique ("/") dans les modèles de niveau 3 et supérieur, est utile pour décrire les hiérarchies de chemins URI.

Pour chaque variable définie dans la liste de variables, ajoutez "/" à la chaîne de résultat, puis effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble non réservé.

Notez que le processus d'expansion pour l'expansion de segment de chemin est identique à celui de l'expansion d'étiquette, à l'exception de la substitution de "/" au lieu de ".". Cependant, contrairement à ".", un "/" est un caractère réservé et sera encodé en pourcentage s'il est trouvé dans une valeur.

Exemple de modèle     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} (Expansion de paramètre de style chemin)​

L'expansion de paramètre de style chemin, indiquée par l'opérateur point-virgule (";") dans les modèles de niveau 3 et supérieur, est utile pour décrire les paramètres de chemin URI, tels que "path;property" ou "path;name=value".

Pour chaque variable définie dans la liste de variables :

  • ajoutez ";" à la chaîne de résultat ;
  • si la variable a une valeur de chaîne simple ou si aucun modificateur d'explosion n'est donné, alors :
    • ajoutez le nom de variable (encodé comme s'il s'agissait d'une chaîne littérale) à la chaîne de résultat ;
    • si la valeur de la variable n'est pas vide, ajoutez "=" à la chaîne de résultat ;
  • effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble non réservé.
Exemple de modèle     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} (Expansion de requête de style formulaire)​

L'expansion de requête de style formulaire, indiquée par l'opérateur point d'interrogation ("?") dans les modèles de niveau 3 et supérieur, est utile pour décrire un composant de requête optionnel entier.

Pour chaque variable définie dans la liste de variables :

  • ajoutez "?" à la chaîne de résultat s'il s'agit de la première valeur définie ou ajoutez "&" par la suite ;
  • si la variable a une valeur de chaîne simple ou si aucun modificateur d'explosion n'est donné, ajoutez le nom de variable (encodé comme s'il s'agissait d'une chaîne littérale) et un caractère égal ("=") à la chaîne de résultat ; et,
  • effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble non réservé.
Exemple de modèle     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} (Continuation de requête de style formulaire)​

La continuation de requête de style formulaire, indiquée par l'opérateur esperluette ("&") dans les modèles de niveau 3 et supérieur, est utile pour décrire des paires optionnelles &name=value dans un modèle qui contient déjà un composant de requête littéral avec des paramètres fixes.

Pour chaque variable définie dans la liste de variables :

  • ajoutez "&" à la chaîne de résultat ;
  • si la variable a une valeur de chaîne simple ou si aucun modificateur d'explosion n'est donné, ajoutez le nom de variable (encodé comme s'il s'agissait d'une chaîne littérale) et un caractère égal ("=") à la chaîne de résultat ; et,
  • effectuez l'expansion de variable, comme défini dans la Section 3.2.1, les caractères autorisés étant ceux de l'ensemble non réservé.
Exemple de modèle     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 (Considérations de sécurité)​

Un modèle URI ne contient pas de contenu actif ou exécutable. Cependant, il pourrait être possible de créer des URI inattendus si un attaquant obtient le contrôle du modèle ou des valeurs de variables dans une expression qui autorise les caractères réservés dans l'expansion. Dans les deux cas, les considérations de sécurité sont largement déterminées par qui fournit le modèle, qui fournit les valeurs à utiliser pour les variables dans le modèle, dans quel contexte d'exécution l'expansion se produit (client ou serveur), et où les URI résultants sont utilisés.

Cette spécification ne limite pas où les modèles URI peuvent être utilisés. Les implémentations actuelles existent dans les frameworks de développement côté serveur et dans JavaScript côté client pour les liens ou formulaires calculés.

Dans les frameworks, les modèles agissent généralement comme des guides pour indiquer où les données peuvent se produire dans les URI ultérieurs (au moment de la requête) dans les requêtes client. Par conséquent, les préoccupations de sécurité ne concernent pas les modèles eux-mêmes, mais plutôt la façon dont le serveur extrait et traite les données fournies par l'utilisateur dans une requête Web normale.

Dans les implémentations côté client, un modèle URI a de nombreuses propriétés identiques aux formulaires HTML, sauf qu'il est limité aux caractères URI et peut être inclus dans les valeurs de champs d'en-tête HTTP au lieu de simplement le contenu du corps du message. Il convient de veiller à ce que les chaînes de référence URI potentiellement dangereuses, telles que celles commençant par "javascript:", n'apparaissent pas dans l'expansion à moins que le modèle et les valeurs ne soient fournis par une source de confiance.

Les autres considérations de sécurité sont les mêmes que celles des URI, comme décrit dans la Section 7 de [RFC3986].



Appendix A. Implementation Hints (Conseils d'implémentation)​

Les sections normatives sur l'expansion décrivent chaque opérateur avec un processus d'expansion distinct par souci de clarté descriptive. Dans les implémentations réelles, nous nous attendons à ce que les expressions soient traitées de gauche à droite en utilisant un algorithme commun qui n'a que des variations mineures de processus par opérateur. Cette annexe non normative décrit un tel algorithme.

Initialisez une chaîne de résultat vide et son état non-erreur.

Scannez le modèle et copiez les littéraux dans la chaîne de résultat (comme dans la Section 3.1) jusqu'à ce qu'une expression soit indiquée par un "{", qu'une erreur soit indiquée par la présence d'un caractère non-littéral autre que "{", ou que le modèle se termine. Lorsqu'il se termine, retournez la chaîne de résultat et son état d'erreur ou de non-erreur actuel.

  • Si une expression est trouvée, scannez le modèle jusqu'au prochain "}" et extrayez les caractères entre les accolades.
  • Si le modèle se termine avant un "}", alors ajoutez le "{" et les caractères extraits à la chaîne de résultat et retournez avec un état d'erreur indiquant que l'expression est mal formée.

Examinez le premier caractère de l'expression extraite pour un opérateur.

  • Si l'expression s'est terminée (c'est-à-dire est "{}"), un opérateur inconnu ou non implémenté est trouvé, ou le caractère n'est pas dans l'ensemble varchar (Section 2.3), alors ajoutez "{", l'expression extraite, et "}" à la chaîne de résultat, mémorisez que le résultat est dans un état d'erreur, puis retournez pour scanner le reste du modèle.
  • Si un opérateur connu et implémenté est trouvé, stockez l'opérateur et passez au caractère suivant pour commencer la varspec-list.
  • Sinon, stockez l'opérateur comme NUL (expansion de chaîne simple).

Utilisez la table de valeurs suivante pour déterminer le comportement de traitement par opérateur de type d'expression. L'entrée pour "first" est la chaîne à ajouter au résultat en premier si l'une des variables de l'expression est définie. L'entrée pour "sep" est le séparateur à ajouter au résultat avant toute deuxième (ou ultérieure) expansion de variable définie. L'entrée pour "named" est un booléen indiquant si l'expansion inclut le nom de variable ou de clé lorsqu'aucun modificateur d'explosion n'est donné. L'entrée pour "ifemp" est une chaîne à ajouter au nom si sa valeur correspondante est vide. L'entrée pour "allow" indique quels caractères autoriser non encodés dans l'expansion de valeur : (U) signifie que tout caractère non dans l'ensemble non réservé sera encodé ; (U+R) signifie que tout caractère non dans l'union de (unreserved / reserved / pct-encoding) sera encodé ; et, pour les deux cas, chaque caractère non autorisé est d'abord encodé comme sa séquence d'octets en UTF-8, puis chaque octet est encodé comme un triplet encodé en pourcentage.

┌──────────────────────────────────────────────────────────────┐
│ NUL + . / ; ? & #│
├──────────────────────────────────────────────────────────────┤
│ first │ "" "" "." "/" ";" "?" "&" "#"│
│ sep │ "," "," "." "/" ";" "&" "&" "," │
│ named │ false false false false true true true false│
│ ifemp │ "" "" "" "" "" "=" "=" "" │
│ allow │ U U+R U U U U U U+R │
└──────────────────────────────────────────────────────────────┘

Avec la table ci-dessus à l'esprit, traitez la liste de variables comme suit :

Pour chaque varspec, extrayez un nom de variable et un modificateur optionnel de l'expression en scannant la liste de variables jusqu'à ce qu'un caractère non dans l'ensemble varname soit trouvé ou que la fin de l'expression soit atteinte.

  • Si c'est la fin de l'expression et que le varname est vide, retournez pour scanner le reste du modèle.
  • Si ce n'est pas la fin de l'expression et que le dernier caractère trouvé indique un modificateur ("" ou ":"), mémorisez ce modificateur. Si c'est une explosion (""), scannez le caractère suivant. Si c'est un préfixe (":"), continuez à scanner les un à quatre caractères suivants pour le max-length représenté comme un entier décimal et ensuite, si ce n'est toujours pas la fin de l'expression, scannez le caractère suivant.
  • Si ce n'est pas la fin de l'expression et que le dernier caractère trouvé n'est pas une virgule (","), ajoutez "{", l'opérateur stocké (le cas échéant), le varname et modificateur scannés, l'expression restante, et "}" à la chaîne de résultat, mémorisez que le résultat est dans un état d'erreur, puis retournez pour scanner le reste du modèle.

Recherchez la valeur du nom de variable scanné, puis

  • Si le varname est inconnu ou correspond à une variable avec une valeur non définie (Section 2.3), alors passez au varspec suivant.
  • Si c'est la première variable définie pour cette expression, ajoutez la chaîne first pour ce type d'expression à la chaîne de résultat et mémorisez que cela a été fait. Sinon, ajoutez la chaîne sep à la chaîne de résultat.
  • Si la valeur de cette variable est une chaîne, alors
    • si named est true, ajoutez le varname à la chaîne de résultat en utilisant le même processus d'encodage que pour les littéraux, et
      • si la valeur est vide, ajoutez la chaîne ifemp à la chaîne de résultat et passez au varspec suivant ;
      • sinon, ajoutez "=" à la chaîne de résultat.
    • si un modificateur de préfixe est présent et que la longueur du préfixe est inférieure à la longueur de la chaîne de valeur en nombre de caractères Unicode, ajoutez ce nombre de caractères du début de la chaîne de valeur à la chaîne de résultat, après encodage en pourcentage des caractères qui ne sont pas dans l'ensemble allow, en veillant à ne pas diviser les caractères multi-octets ou les triplets encodés en pourcentage qui représentent un seul point de code Unicode ;
    • sinon, ajoutez la valeur à la chaîne de résultat après encodage en pourcentage des caractères qui ne sont pas dans l'ensemble allow.
  • sinon si aucun modificateur d'explosion n'est donné, alors
    • si named est true, ajoutez le varname à la chaîne de résultat en utilisant le même processus d'encodage que pour les littéraux, et
      • si la valeur est vide, ajoutez la chaîne ifemp à la chaîne de résultat et passez au varspec suivant ;
      • sinon, ajoutez "=" à la chaîne de résultat ; et
    • si la valeur de cette variable est une liste, ajoutez chaque membre de liste défini à la chaîne de résultat, après encodage en pourcentage des caractères qui ne sont pas dans l'ensemble allow, avec une virgule (",") ajoutée au résultat entre chaque membre de liste défini ;
    • si la valeur de cette variable est un tableau associatif ou toute autre forme de structure pairée (name, value), ajoutez chaque paire avec une valeur définie à la chaîne de résultat comme "name,value", après encodage en pourcentage des caractères qui ne sont pas dans l'ensemble allow, avec une virgule (",") ajoutée au résultat entre chaque paire définie.
  • sinon si un modificateur d'explosion est donné, alors
    • si named est true, alors pour chaque membre de liste défini ou paire de tableau (name, value) avec une valeur définie, faire :
      • si ce n'est pas le premier membre/valeur défini, ajoutez la chaîne sep à la chaîne de résultat ;
      • si c'est une liste, ajoutez le varname à la chaîne de résultat en utilisant le même processus d'encodage que pour les littéraux ;
      • si c'est une paire, ajoutez le name à la chaîne de résultat en utilisant le même processus d'encodage que pour les littéraux ;
      • si le membre/valeur est vide, ajoutez la chaîne ifemp à la chaîne de résultat ; sinon, ajoutez "=" et le membre/valeur à la chaîne de résultat, après encodage en pourcentage des caractères membre/valeur qui ne sont pas dans l'ensemble allow.
    • sinon si named est false, alors
      • si c'est une liste, ajoutez chaque membre de liste défini à la chaîne de résultat, après encodage en pourcentage des caractères qui ne sont pas dans l'ensemble allow, avec la chaîne sep ajoutée au résultat entre chaque membre de liste défini.
      • si c'est un tableau de paires (name, value), ajoutez chaque paire avec une valeur définie à la chaîne de résultat comme "name=value", après encodage en pourcentage des caractères qui ne sont pas dans l'ensemble allow, avec la chaîne sep ajoutée au résultat entre chaque paire définie.

Lorsque la liste de variables pour cette expression est épuisée, retournez pour scanner le reste du modèle.