Aller au contenu principal

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