Aller au contenu principal

5. Champs

HTTP utilise des "champs" (Fields) pour fournir des données sous forme de paires nom/valeur extensibles avec un espace de noms de clés enregistrées. Les champs sont envoyés et reçus dans les sections d'en-tête et de bande-annonce des messages (Section 6).

5.1. Noms de Champs

Un nom de champ (Field Name) étiquette la valeur de champ correspondante comme ayant la sémantique définie par ce nom. Par exemple, le champ d'en-tête Date est défini dans la Section 6.6.1 comme contenant l'horodatage d'origine du message dans lequel il apparaît.

field-name     = token

Les noms de champs ne sont pas sensibles à la casse et devraient être enregistrés dans le "Registre des Noms de Champs du Protocole de Transfert Hypertexte (HTTP)"; voir Section 16.3.1.

L'interprétation d'un champ ne change pas entre les versions mineures de la même version majeure HTTP, bien que le comportement par défaut d'un destinataire en l'absence d'un tel champ puisse changer. Sauf indication contraire, les champs sont définis pour toutes les versions de HTTP. En particulier, les champs Host et Connection devraient être reconnus par toutes les implémentations HTTP, qu'elles annoncent ou non la conformité avec HTTP/1.1.

De nouveaux champs peuvent être introduits sans changer la version du protocole si leur sémantique définie leur permet d'être ignorés en toute sécurité par les destinataires qui ne les reconnaissent pas; voir Section 16.3.

Un proxy DOIT (MUST) transférer les champs d'en-tête non reconnus sauf si le nom du champ est répertorié dans le champ d'en-tête Connection (Section 7.6.1) ou si le proxy est spécifiquement configuré pour bloquer ou autrement transformer de tels champs. Les autres destinataires DEVRAIENT (SHOULD) ignorer les champs d'en-tête et de bande-annonce non reconnus. Le respect de ces exigences permet d'étendre les fonctionnalités de HTTP sans mise à jour ou suppression des intermédiaires déployés.

5.2. Lignes de Champs et Valeur de Champ Combinée

Les sections de champs (Field Sections) sont composées d'un nombre quelconque de "lignes de champs" (Field Lines), chacune avec un "nom de champ" (voir Section 5.1) identifiant le champ, et une "valeur de ligne de champ" (Field Line Value) qui transmet les données pour cette instance du champ.

Lorsqu'un nom de champ n'est présent qu'une seule fois dans une section, la "valeur de champ" (Field Value) combinée pour ce champ consiste en la valeur de ligne de champ correspondante. Lorsqu'un nom de champ est répété dans une section, sa valeur de champ combinée consiste en la liste des valeurs de ligne de champ correspondantes dans cette section, concaténées dans l'ordre, chaque valeur de ligne de champ étant séparée par une virgule.

Par exemple, cette section:

Example-Field: Foo, Bar
Example-Field: Baz

contient deux lignes de champs, toutes deux avec le nom de champ "Example-Field". La première ligne de champ a une valeur de ligne de champ de "Foo, Bar", tandis que la deuxième valeur de ligne de champ est "Baz". La valeur de champ pour "Example-Field" est la liste "Foo, Bar, Baz".

5.3. Ordre des Champs

Un destinataire PEUT (MAY) combiner plusieurs lignes de champs dans une section de champs qui ont le même nom de champ en une seule ligne de champ, sans changer la sémantique du message, en ajoutant chaque valeur de ligne de champ suivante à la valeur de ligne de champ initiale dans l'ordre, séparée par une virgule (",") et un espace blanc optionnel (OWS, défini dans la Section 5.6.3). Pour la cohérence, utilisez virgule SP.

L'ordre dans lequel les lignes de champs avec le même nom sont reçues est donc significatif pour l'interprétation de la valeur du champ; un proxy NE DOIT PAS (MUST NOT) changer l'ordre de ces valeurs de ligne de champ lors du transfert d'un message.

Cela signifie que, mis à part l'exception bien connue notée ci-dessous, un expéditeur NE DOIT PAS (MUST NOT) générer plusieurs lignes de champs avec le même nom dans un message (que ce soit dans les en-têtes ou les bandes-annonces) ou ajouter une ligne de champ lorsqu'une ligne de champ du même nom existe déjà dans le message, sauf si la définition de ce champ permet que plusieurs valeurs de ligne de champ soient recombinées sous forme de liste séparée par des virgules (c'est-à-dire qu'au moins une alternative de la définition du champ autorise une liste séparée par des virgules, comme une règle ABNF de #(values) définie dans la Section 5.6.1).

Note: En pratique, le champ d'en-tête "Set-Cookie" ([COOKIE]) apparaît souvent dans un message de réponse sur plusieurs lignes de champs et n'utilise pas la syntaxe de liste, violant les exigences ci-dessus sur plusieurs lignes de champs avec le même nom de champ. Puisqu'il ne peut pas être combiné en une seule valeur de champ, les destinataires devraient traiter "Set-Cookie" comme un cas spécial lors du traitement des champs. (Voir l'Annexe A.2.3 de [Kri2001] pour plus de détails.)

L'ordre dans lequel les lignes de champs avec des noms de champs différents sont reçues dans une section n'est pas significatif. Cependant, il est de bonne pratique d'envoyer d'abord les champs d'en-tête qui contiennent des données de contrôle supplémentaires, tels que Host sur les requêtes et Date sur les réponses, afin que les implémentations puissent décider le plus tôt possible de ne pas traiter un message.

Un serveur NE DOIT PAS (MUST NOT) appliquer une requête à la ressource cible tant qu'il n'a pas reçu l'ensemble de la section d'en-tête de la requête, car les lignes de champ d'en-tête ultérieures peuvent inclure des conditions, des informations d'identification d'authentification ou des champs d'en-tête dupliqués délibérément trompeurs qui pourraient impacter le traitement de la requête.

5.4. Limites des Champs

HTTP n'impose pas de limite prédéfinie sur la longueur de chaque ligne de champ, valeur de champ, ou sur la longueur d'une section d'en-tête ou de bande-annonce dans son ensemble, comme décrit dans la Section 2. Diverses limitations ad hoc sur les longueurs individuelles se trouvent dans la pratique, dépendant souvent de la sémantique du champ spécifique.

Un serveur qui reçoit une ligne de champ d'en-tête de requête, une valeur de champ ou un ensemble de champs plus grand que ce qu'il souhaite traiter DOIT répondre avec un code d'état 4xx (Erreur Client) approprié. Ignorer de tels champs d'en-tête augmenterait la vulnérabilité du serveur aux attaques de contrebande de requêtes (Section 11.2 de [HTTP/1.1]).

Un client PEUT (MAY) rejeter ou tronquer les lignes de champ reçues qui sont plus grandes que ce que le client souhaite traiter si la sémantique du champ est telle que la ou les valeurs rejetées peuvent être ignorées en toute sécurité sans changer l'encadrement du message ou la sémantique de la réponse.

5.5. Valeurs de Champs

Les valeurs de champs HTTP (Field Values) consistent en une séquence de caractères dans un format défini par la grammaire du champ. La grammaire de chaque champ est généralement définie en utilisant ABNF ([RFC5234]).

field-value    = *field-content
field-content = field-vchar
[ 1*( SP / HTAB / field-vchar ) field-vchar ]
field-vchar = VCHAR / obs-text
obs-text = %x80-FF

Les valeurs de champs n'incluent pas d'espace blanc de début ou de fin. Lorsqu'une version spécifique de HTTP permet à de tels espaces blancs d'apparaître dans un message, une implémentation d'analyse de champ DOIT exclure ces espaces blancs avant d'évaluer la valeur du champ.

Les valeurs de champs sont généralement limitées à la plage de caractères US-ASCII [USASCII]. Les champs nécessitant une plage de caractères plus large peuvent utiliser un encodage, tel que celui défini dans [RFC8187]. Historiquement, HTTP a permis un contenu de champ avec du texte dans le jeu de caractères ISO-8859-1 [ISO-8859-1], ne supportant d'autres jeux de caractères que par l'utilisation de l'encodage [RFC2047]. Les spécifications pour les champs nouvellement définis DEVRAIENT (SHOULD) limiter leurs valeurs aux octets US-ASCII visibles (VCHAR), SP et HTAB. Un destinataire DEVRAIT (SHOULD) traiter les autres octets autorisés dans le contenu du champ (c'est-à-dire obs-text) comme des données opaques.

Les valeurs de champs contenant des caractères CR, LF ou NUL sont invalides et dangereuses, en raison des différentes façons dont les implémentations peuvent analyser et interpréter ces caractères; un destinataire de CR, LF ou NUL dans une valeur de champ DOIT soit rejeter le message, soit remplacer chacun de ces caractères par SP avant tout traitement ou transfert ultérieur de ce message. Les valeurs de champs contenant d'autres caractères CTL sont également invalides; cependant, les destinataires PEUVENT (MAY) conserver de tels caractères pour des raisons de robustesse lorsqu'ils apparaissent dans un contexte sûr (par exemple, une chaîne entre guillemets spécifique à l'application qui ne sera pas traitée par un analyseur HTTP en aval).

Les champs qui n'anticipent qu'un seul membre comme valeur de champ sont appelés "champs singleton" (Singleton Fields).

Les champs qui permettent plusieurs membres comme valeur de champ sont appelés "champs basés sur des listes" (List-Based Fields). L'extension d'opérateur de liste de la Section 5.6.1 est utilisée comme notation commune pour définir les valeurs de champs qui peuvent contenir plusieurs membres.

Parce que les virgules (",") sont utilisées comme séparateur entre les membres, elles doivent être traitées avec soin si elles sont autorisées comme données dans un membre. Ceci est vrai pour les champs basés sur des listes et les champs singleton, car un champ singleton peut être envoyé par erreur avec plusieurs membres et la détection de telles erreurs améliore l'interopérabilité. Les champs qui s'attendent à contenir une virgule dans un membre, comme dans une date HTTP ou un élément de référence URI, devraient définir des délimiteurs autour de cet élément pour distinguer toute virgule dans ces données des séparateurs de liste potentiels.

Par exemple, une date textuelle et un URI (l'un ou l'autre pouvant contenir une virgule) pourraient être transportés en toute sécurité dans des valeurs de champ basées sur des listes comme celles-ci:

Example-URIs: "http://example.com/a.html,foo",
"http://without-a-comma.example.com/"
Example-Dates: "Sat, 04 May 1996", "Wed, 14 Sep 2005"

Notez que les délimiteurs guillemets doubles sont presque toujours utilisés avec la production quoted-string (Section 5.6.4); l'utilisation d'une syntaxe différente à l'intérieur des guillemets doubles causera probablement une confusion inutile.

De nombreux champs (par exemple, Content-Type, défini dans la Section 8.3) utilisent une syntaxe commune pour les paramètres qui permet à la fois une syntaxe non citée (token) et citée (quoted-string) pour une valeur de paramètre (Section 5.6.6). L'utilisation d'une syntaxe commune permet aux destinataires de réutiliser les composants d'analyse existants. Lorsque les deux formes sont autorisées, la signification d'une valeur de paramètre devrait être indépendante de la forme utilisée pour transmettre cette valeur.

Note: Pour définir la syntaxe de valeur de champ, cette spécification utilise une règle ABNF nommée d'après le nom du champ pour définir la grammaire autorisée pour la valeur de ce champ (après que la valeur du champ a été extraite de la syntaxe de messagerie sous-jacente et que plusieurs instances ont été combinées en une liste).

5.6. Règles Communes pour Définir les Valeurs de Champs

5.6.1. Listes (Extension ABNF de la règle #)

Une extension de règle # aux règles ABNF de [RFC5234] est utilisée pour améliorer la lisibilité dans les définitions de certaines valeurs de champ basées sur des listes.

Une construction "#" est définie, similaire à "*", pour définir des listes d'éléments délimitées par des virgules. La forme complète est "<n>#<m>element" indiquant au moins <n> et au plus <m> éléments, chacun séparé par une seule virgule (",") et un espace blanc optionnel (OWS, défini dans la Section 5.6.3).

5.6.1.1. Exigences de l'Expéditeur

Dans toute production qui utilise la construction de liste, un expéditeur NE DOIT PAS (MUST NOT) générer d'éléments de liste vides. En d'autres termes, un expéditeur doit générer des listes qui satisfont la syntaxe suivante:

1#element => element *( OWS "," OWS element )

et:

#element => [ 1#element ]

et pour n >= 1 et m > 1:

<n>#<m>element => element <n-1>*<m-1>( OWS "," OWS element )

L'Annexe A montre l'ABNF collecté pour les expéditeurs après l'expansion des constructions de liste.

5.6.1.2. Exigences du Destinataire

Les éléments vides ne contribuent pas au compte des éléments présents. Un destinataire DOIT analyser et ignorer un nombre raisonnable d'éléments de liste vides: suffisamment pour gérer les erreurs courantes des expéditeurs qui fusionnent des valeurs, mais pas au point qu'ils puissent être utilisés comme mécanisme de déni de service. En d'autres termes, un destinataire DOIT accepter des listes qui satisfont la syntaxe suivante:

#element => [ element ] *( OWS "," OWS [ element ] )

Notez qu'en raison de la présence potentielle d'éléments de liste vides, l'ABNF RFC 5234 ne peut pas imposer la cardinalité des éléments de liste, et par conséquent tous les cas sont mappés comme s'il n'y avait pas de cardinalité spécifiée.

Par exemple, étant donné ces productions ABNF:

example-list      = 1#example-list-elmt
example-list-elmt = token ; voir Section 5.6.2

Alors les suivants sont des valeurs valides pour example-list (sans inclure les guillemets doubles, qui sont présents uniquement pour la délimitation):

"foo,bar"
"foo ,bar,"
"foo , ,bar,charlie"

En revanche, les suivants seraient invalides, car au moins un élément non vide est requis par la production example-list:

""
","
", ,"

5.6.2. Jetons

Les jetons (Tokens) sont de courts identifiants textuels qui n'incluent pas d'espace blanc ou de délimiteurs.

token          = 1*tchar

tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; tout VCHAR, sauf les délimiteurs

De nombreuses valeurs de champs HTTP sont définies à l'aide de composants de syntaxe commune, séparés par des espaces blancs ou des caractères de délimitation spécifiques. Les délimiteurs sont choisis dans l'ensemble des caractères visuels US-ASCII non autorisés dans un jeton (DQUOTE et "(),/:;<=>?@[\]{}").

5.6.3. Espaces Blancs

Cette spécification utilise trois règles pour désigner l'utilisation d'espaces blancs linéaires: OWS (espace blanc optionnel, Optional Whitespace), RWS (espace blanc requis, Required Whitespace) et BWS (espace blanc "mauvais", "Bad" Whitespace).

La règle OWS est utilisée là où zéro ou plusieurs octets d'espace blanc linéaire peuvent apparaître. Pour les éléments de protocole où l'espace blanc optionnel est préféré pour améliorer la lisibilité, un expéditeur DEVRAIT (SHOULD) générer l'espace blanc optionnel comme un seul SP; sinon, un expéditeur NE DEVRAIT PAS (SHOULD NOT) générer d'espace blanc optionnel sauf si nécessaire pour filtrer des éléments de protocole invalides ou indésirables lors du filtrage de messages sur place.

La règle RWS est utilisée lorsqu'au moins un octet d'espace blanc linéaire est requis pour séparer les jetons de champ. Un expéditeur DEVRAIT (SHOULD) générer RWS comme un seul SP.

Les règles OWS et RWS ont la même sémantique qu'un seul SP. Tout contenu connu pour être défini comme OWS ou RWS PEUT (MAY) être remplacé par un seul SP avant de l'interpréter ou de transférer le message en aval.

La règle BWS est utilisée là où la grammaire autorise l'espace blanc optionnel uniquement pour des raisons historiques. Un expéditeur NE DOIT PAS (MUST NOT) générer de BWS dans les messages. Un destinataire DOIT analyser de tels mauvais espaces blancs et les supprimer avant d'interpréter l'élément de protocole.

BWS n'a pas de sémantique. Tout contenu connu pour être défini comme BWS PEUT (MAY) être supprimé avant de l'interpréter ou de transférer le message en aval.

OWS            = *( SP / HTAB )
; espace blanc optionnel
RWS = 1*( SP / HTAB )
; espace blanc requis
BWS = OWS
; espace blanc "mauvais"

5.6.4. Chaînes Entre Guillemets

Une chaîne de texte est analysée comme une valeur unique si elle est entre guillemets en utilisant des marques de guillemets doubles.

quoted-string  = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text

L'octet barre oblique inverse ("") peut être utilisé comme mécanisme de citation à un seul octet dans les constructions quoted-string et comment. Les destinataires qui traitent la valeur d'une quoted-string DOIVENT gérer un quoted-pair comme s'il était remplacé par l'octet suivant la barre oblique inverse.

quoted-pair    = "\" ( HTAB / SP / VCHAR / obs-text )

Un expéditeur NE DEVRAIT PAS (SHOULD NOT) générer un quoted-pair dans une quoted-string sauf là où c'est nécessaire pour citer les octets DQUOTE et barre oblique inverse apparaissant dans cette chaîne. Un expéditeur NE DEVRAIT PAS (SHOULD NOT) générer un quoted-pair dans un commentaire sauf là où c'est nécessaire pour citer les parenthèses ["(" et ")"] et les octets barre oblique inverse apparaissant dans ce commentaire.

5.6.5. Commentaires

Des commentaires peuvent être inclus dans certains champs HTTP en entourant le texte du commentaire de parenthèses. Les commentaires ne sont autorisés que dans les champs contenant "comment" comme partie de leur définition de valeur de champ.

comment        = "(" *( ctext / quoted-pair / comment ) ")"
ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text

5.6.6. Paramètres

Les paramètres (Parameters) sont des instances de paires nom/valeur; ils sont souvent utilisés dans les valeurs de champ comme syntaxe commune pour ajouter des informations auxiliaires à un élément. Chaque paramètre est généralement délimité par un point-virgule immédiatement précédent.

parameters      = *( OWS ";" OWS [ parameter ] )
parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )

Les noms de paramètres ne sont pas sensibles à la casse. Les valeurs de paramètres peuvent être sensibles à la casse ou non, selon la sémantique du nom de paramètre. Des exemples de paramètres et certaines formes équivalentes peuvent être vus dans les types de médias (Section 8.3.1) et le champ d'en-tête Accept (Section 12.5.1).

Une valeur de paramètre qui correspond à la production token peut être transmise soit comme token, soit dans une quoted-string. Les valeurs citées et non citées sont équivalentes.

Note: Les paramètres ne permettent pas d'espace blanc (pas même d'espace blanc "mauvais") autour du caractère "=".

5.6.7. Formats Date/Heure

Avant 1995, il existait trois formats différents couramment utilisés par les serveurs pour communiquer les horodatages. Pour des raisons de compatibilité avec les anciennes implémentations, les trois sont définis ici. Le format préféré est un sous-ensemble à longueur fixe et à zone unique de la spécification de date et d'heure utilisée par le Format de Message Internet [RFC5322].

HTTP-date    = IMF-fixdate / obs-date

Un exemple du format préféré est

Sun, 06 Nov 1994 08:49:37 GMT    ; IMF-fixdate

Des exemples des deux formats obsolètes sont

Sunday, 06-Nov-94 08:49:37 GMT   ; format RFC 850 obsolète
Sun Nov 6 08:49:37 1994 ; format asctime() d'ANSI C

Un destinataire qui analyse une valeur d'horodatage dans un champ HTTP DOIT accepter les trois formats HTTP-date. Lorsqu'un expéditeur génère un champ qui contient un ou plusieurs horodatages définis comme HTTP-date, l'expéditeur DOIT générer ces horodatages au format IMF-fixdate.

Une valeur HTTP-date représente le temps comme une instance du Temps Universel Coordonné (Coordinated Universal Time, UTC). Les deux premiers formats indiquent UTC par l'abréviation à trois lettres pour le Temps Moyen de Greenwich, "GMT", un prédécesseur du nom UTC; les valeurs au format asctime sont supposées être en UTC.

Une "horloge" (Clock) est une implémentation capable de fournir une approximation raisonnable de l'instant actuel en UTC. Une implémentation d'horloge devrait utiliser NTP ([RFC5905]) ou un protocole similaire pour se synchroniser avec UTC.

Format préféré:

IMF-fixdate  = day-name "," SP date1 SP time-of-day SP GMT
; sous-ensemble à longueur/zone/capitalisation fixe du format
; voir Section 3.3 de [RFC5322]

day-name = %s"Mon" / %s"Tue" / %s"Wed"
/ %s"Thu" / %s"Fri" / %s"Sat" / %s"Sun"

date1 = day SP month SP year
; par ex., 02 Jun 1982

day = 2DIGIT
month = %s"Jan" / %s"Feb" / %s"Mar" / %s"Apr"
/ %s"May" / %s"Jun" / %s"Jul" / %s"Aug"
/ %s"Sep" / %s"Oct" / %s"Nov" / %s"Dec"
year = 4DIGIT

GMT = %s"GMT"

time-of-day = hour ":" minute ":" second
; 00:00:00 - 23:59:60 (seconde bissextile)

hour = 2DIGIT
minute = 2DIGIT
second = 2DIGIT

Formats obsolètes:

obs-date     = rfc850-date / asctime-date

rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
date2 = day "-" month "-" 2DIGIT
; par ex., 02-Jun-82

day-name-l = %s"Monday" / %s"Tuesday" / %s"Wednesday"
/ %s"Thursday" / %s"Friday" / %s"Saturday"
/ %s"Sunday"

asctime-date = day-name SP date3 SP time-of-day SP year
date3 = month SP ( 2DIGIT / ( SP 1DIGIT ))
; par ex., Jun 2

HTTP-date est sensible à la casse. Notez que la Section 4.2 de [CACHING] assouplit ceci pour les destinataires de cache.

Un expéditeur NE DOIT PAS (MUST NOT) générer d'espace blanc supplémentaire dans un HTTP-date au-delà de celui spécifiquement inclus comme SP dans la grammaire. La sémantique de day-name, day, month, year et time-of-day est la même que celle définie pour les constructions de Format de Message Internet avec le nom correspondant ([RFC5322], Section 3.3).

Les destinataires d'une valeur d'horodatage au format rfc850-date, qui utilise une année à deux chiffres, DOIVENT interpréter un horodatage qui semble être plus de 50 ans dans le futur comme représentant l'année la plus récente dans le passé qui avait les deux mêmes derniers chiffres.

Les destinataires de valeurs d'horodatage sont encouragés à être robustes dans l'analyse des horodatages sauf restriction contraire par la définition du champ. Par exemple, les messages sont parfois transférés via HTTP depuis une source non-HTTP qui peut générer n'importe laquelle des spécifications de date et d'heure définies par le Format de Message Internet.

Note: Les exigences HTTP pour le format d'horodatage date/heure s'appliquent uniquement à leur utilisation dans le flux de protocole. Les implémentations ne sont pas tenues d'utiliser ces formats pour la présentation à l'utilisateur, l'enregistrement des requêtes, etc.