Aller au contenu principal

7. Champs d'en-tête de réponse (Response Header Fields)

Les champs d'en-tête de réponse permettent au serveur de transmettre des informations supplémentaires sur la réponse au-delà de ce qui est placé dans la ligne d'état. Ces champs d'en-tête fournissent des informations sur le serveur, sur l'accès supplémentaire à la ressource cible ou sur les ressources associées.

Bien que chaque champ d'en-tête de réponse ait une signification définie, en général, la sémantique précise peut être encore affinée par la sémantique de la méthode de requête et/ou du code d'état de réponse.

7.1. Données de contrôle (Control Data)

Les champs d'en-tête de réponse peuvent fournir des données de contrôle qui complètent le code d'état, dirigent la mise en cache ou indiquent au client où aller ensuite.

7.1.1. Date d'origine (Origination Date)

7.1.1.1. Date

Le champ d'en-tête "Date" représente la date et l'heure auxquelles le message a été créé, ayant la même sémantique que le champ Date d'origine (orig-date) défini dans la section 3.6.1 de [RFC5322]. La valeur du champ est une HTTP-date, telle que définie dans la section 7.1.1.1 de [RFC7231].

Date = HTTP-date

Un exemple:

Date: Tue, 15 Nov 1994 08:12:31 GMT

Lorsqu'un champ d'en-tête Date est généré, l'expéditeur DEVRAIT (SHOULD) générer sa valeur de champ comme la meilleure approximation disponible de la date et de l'heure de génération du message. En théorie, la date devrait représenter le moment juste avant que la charge utile ne soit générée. En pratique, la date peut être générée à tout moment pendant l'origination du message.

Un serveur d'origine NE DOIT PAS (MUST NOT) envoyer un champ d'en-tête Date s'il n'a pas d'horloge capable de fournir une approximation raisonnable de l'instant actuel en temps universel coordonné (UTC). Un serveur d'origine PEUT (MAY) envoyer un champ d'en-tête Date si la réponse est dans la classe de codes d'état 1xx (Informationnel) ou 5xx (Erreur serveur). Un serveur d'origine DOIT (MUST) envoyer un champ d'en-tête Date dans tous les autres cas.

Un destinataire avec une horloge qui reçoit un message de réponse sans champ d'en-tête Date DOIT (MUST) enregistrer l'heure à laquelle il a été reçu et ajouter un champ d'en-tête Date correspondant à la section d'en-tête du message s'il est mis en cache ou transféré en aval.

Un agent utilisateur PEUT (MAY) envoyer un champ d'en-tête Date dans une requête, bien qu'il ne le fasse généralement pas à moins qu'il ne soit considéré comme transmettant des informations utiles au serveur. Par exemple, les applications personnalisées de HTTP peuvent transmettre une Date si le serveur est censé ajuster son interprétation de la requête de l'utilisateur en fonction des différences entre les horloges de l'agent utilisateur et du serveur.

7.1.1.2. HTTP-date

Les applications HTTP ont historiquement autorisé trois formats différents pour la représentation des horodatages de date/heure:

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

Le premier format est préféré en tant que norme Internet et représente un sous-ensemble de longueur fixe de celui défini par [RFC5322] (Section 3.3). Le deuxième format est d'usage courant, mais est basé sur le format de date obsolète RFC 850 [RFC0850] et manque d'une année à quatre chiffres. Les clients et serveurs HTTP/1.1 qui analysent la valeur de date DOIVENT (MUST) accepter les trois formats (pour la compatibilité avec HTTP/1.0), bien qu'ils NE DOIVENT (MUST) générer que le format IMF-fixdate pour représenter les valeurs HTTP-date dans les champs d'en-tête.

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

Une valeur HTTP-date représente le temps comme une instance du temps universel coordonné (UTC). Les deux premiers formats indiquent UTC par l'abréviation de trois lettres pour Greenwich Mean Time, "GMT", un prédécesseur du nom UTC; les valeurs au format asctime sont supposées être en UTC. Un expéditeur qui génère des valeurs HTTP-date à partir d'une horloge locale devrait (ought to) utiliser NTP ([RFC5905]) ou un protocole similaire pour synchroniser son horloge avec UTC.

Format préféré:

HTTP-date    = IMF-fixdate / obs-date

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

day-name = %x4D.6F.6E ; "Mon", sensible à la casse
/ %x54.75.65 ; "Tue", sensible à la casse
/ %x57.65.64 ; "Wed", sensible à la casse
/ %x54.68.75 ; "Thu", sensible à la casse
/ %x46.72.69 ; "Fri", sensible à la casse
/ %x53.61.74 ; "Sat", sensible à la casse
/ %x53.75.6E ; "Sun", sensible à la casse

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

day = 2DIGIT
month = %x4A.61.6E ; "Jan", sensible à la casse
/ %x46.65.62 ; "Feb", sensible à la casse
/ %x4D.61.72 ; "Mar", sensible à la casse
/ %x41.70.72 ; "Apr", sensible à la casse
/ %x4D.61.79 ; "May", sensible à la casse
/ %x4A.75.6E ; "Jun", sensible à la casse
/ %x4A.75.6C ; "Jul", sensible à la casse
/ %x41.75.67 ; "Aug", sensible à la casse
/ %x53.65.70 ; "Sep", sensible à la casse
/ %x4F.63.74 ; "Oct", sensible à la casse
/ %x4E.6F.76 ; "Nov", sensible à la casse
/ %x44.65.63 ; "Dec", sensible à la casse
year = 4DIGIT

GMT = %x47.4D.54 ; "GMT", sensible à la casse

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

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 exemple, 02-Jun-82

day-name-l = %x4D.6F.6E.64.61.79 ; "Monday", sensible à la casse
/ %x54.75.65.73.64.61.79 ; "Tuesday", sensible à la casse
/ %x57.65.64.6E.65.73.64.61.79 ; "Wednesday", sensible à la casse
/ %x54.68.75.72.73.64.61.79 ; "Thursday", sensible à la casse
/ %x46.72.69.64.61.79 ; "Friday", sensible à la casse
/ %x53.61.74.75.72.64.61.79 ; "Saturday", sensible à la casse
/ %x53.75.6E.64.61.79 ; "Sunday", sensible à la casse

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

HTTP-date est sensible à la casse. Un expéditeur NE DOIT PAS (MUST NOT) générer d'espace blanc supplémentaire dans une 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 Internet Message Format avec le nom correspondant ([RFC5322], Section 3.3).

7.1.2. Location

Le champ d'en-tête "Location" est utilisé dans certaines réponses pour faire référence à une ressource spécifique en relation avec la réponse. Le type de relation est défini par la combinaison de la méthode de requête et de la sémantique du code d'état.

Location = URI-reference

La valeur du champ consiste en une seule URI-reference. Lorsqu'elle a la forme d'une référence relative ([RFC3986], Section 4.2), la valeur finale est calculée en la résolvant par rapport à l'URI de requête effective ([RFC7230], Section 5.5).

Pour les réponses 201 (Created), la valeur Location est une référence URI vers une ressource qui identifie la ressource principale créée par la requête. Pour les réponses 3xx (Redirection), la valeur Location fait référence à la ressource cible préférée pour rediriger automatiquement la requête.

Si la valeur Location fournie dans une réponse 3xx (Redirection) n'a pas de composant fragment, un agent utilisateur DOIT (MUST) traiter la redirection comme si la valeur héritait du composant fragment de la référence URI utilisée pour générer la cible de la requête (c'est-à-dire que la redirection hérite du fragment de la référence d'origine, s'il y en a un).

Par exemple, une requête GET générée pour la référence URI "http://www.example.org/~tim" pourrait entraîner plusieurs redirections avant d'arriver finalement à "http://www.example.com/~tim/". Si la première redirection est vers "http://www.example.org/people/~tim", cette redirection sera vers "http://www.example.org/people/~tim" et non vers "http://www.example.org/people/~tim#fred".

Il existe des circonstances dans lesquelles un identifiant de fragment dans une valeur Location ne serait pas approprié. Par exemple, le champ d'en-tête Location dans une réponse 201 (Created) est censé fournir un URI spécifique à la ressource créée.

Note: Certains destinataires tentent de récupérer à partir de champs Location qui ne sont pas des références URI valides. Cette spécification n'impose ni ne définit un tel traitement, mais le permet par souci de robustesse. Une valeur de champ Location qui est un chemin absolu est acceptable, mais sera interprétée relativement à l'URI de requête effective.

Note: La négociation de contenu de la réponse peut entraîner une valeur Location différente de l'URI de requête effective. Si la réponse est cacheable, un cache peut utiliser cette valeur Location pour déterminer une clé plus appropriée pour la réponse (voir Section 4.1 de [RFC7234]).

7.1.3. Retry-After

Les serveurs envoient le champ d'en-tête "Retry-After" pour indiquer combien de temps l'agent utilisateur devrait attendre avant de faire une requête de suivi. Lorsqu'il est envoyé avec une réponse 503 (Service Unavailable), Retry-After indique combien de temps le service devrait être indisponible pour le client. Lorsqu'il est envoyé avec une réponse 429 (Too Many Requests), Retry-After indique combien de temps l'agent utilisateur devrait attendre avant de faire une requête de suivi. Lorsqu'il est envoyé avec une réponse 3xx (Redirection), Retry-After indique le temps minimum que l'agent utilisateur est invité à attendre avant d'émettre la requête redirigée.

La valeur de ce champ peut être soit une HTTP-date, soit un nombre de secondes de délai après réception de la réponse.

Retry-After = HTTP-date / delay-seconds

Une valeur delay-seconds est un entier décimal non négatif, représentant le temps en secondes.

delay-seconds = 1*DIGIT

Deux exemples de son utilisation:

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120

Dans ce dernier exemple, le délai est de 2 minutes.

7.1.4. Vary

Le champ d'en-tête "Vary" dans une réponse décrit quelles parties d'un message de requête, en dehors de la méthode et de la cible de requête, pourraient influencer le processus du serveur d'origine pour sélectionner et représenter cette réponse. La valeur consiste soit en un seul astérisque ("*"), soit en une liste de noms de champs d'en-tête (insensibles à la casse).

Vary = "*" / 1#field-name

Une valeur de champ Vary de "" signale que n'importe quoi concernant la requête pourrait jouer un rôle dans la sélection de la représentation de la réponse, incluant éventuellement des éléments en dehors de la syntaxe du message (par exemple, l'adresse réseau du client). Un destinataire ne pourra pas déterminer si cette réponse est appropriée pour une requête ultérieure sans transférer la requête au serveur d'origine. Un proxy NE DOIT PAS (MUST NOT) générer un champ Vary avec une valeur "".

Une valeur de champ Vary consistant en une liste de noms séparés par des virgules indique que les champs d'en-tête de requête nommés, appelés champs d'en-tête de requête sélectifs, pourraient avoir un rôle dans la sélection de la représentation. Les champs d'en-tête de requête sélectifs potentiels ne sont pas limités à ceux définis par cette spécification.

Par exemple, une réponse contenant:

Vary: accept-encoding, accept-language

indique que le serveur d'origine pourrait avoir utilisé les champs Accept-Encoding et Accept-Language de la requête (ou leur absence) comme facteurs déterminants lors du choix du contenu pour cette réponse.

Un serveur d'origine pourrait envoyer Vary avec une liste de champs pour deux objectifs:

  1. Informer les destinataires du cache qu'ils NE DOIVENT PAS (MUST NOT) utiliser cette réponse pour satisfaire une requête ultérieure à moins que la requête ultérieure n'ait les mêmes valeurs pour les champs listés que la requête d'origine (Section 4.1 de [RFC7234]). En d'autres termes, Vary étend la clé de cache nécessaire pour faire correspondre une nouvelle requête à l'entrée de cache stockée.

  2. Informer les destinataires de l'agent utilisateur que cette réponse est sujette à la négociation de contenu (Section 3.4) et qu'une représentation différente pourrait être envoyée dans une requête ultérieure si des paramètres supplémentaires sont fournis dans les champs d'en-tête listés (négociation proactive).

Un serveur d'origine DEVRAIT (SHOULD) envoyer un champ d'en-tête Vary lorsque son algorithme de sélection d'une représentation varie en fonction d'aspects du message de requête autres que la méthode et la cible de requête, à moins que la variance ne puisse être croisée ou que le serveur d'origine n'ait été délibérément configuré pour empêcher la transparence du cache. Par exemple, il n'est pas nécessaire d'envoyer le nom de champ Authorization dans Vary car la réutilisation entre utilisateurs est contrainte par la définition du champ (Section 4.2 de [RFC7235]). De même, un serveur d'origine pourrait utiliser un champ d'en-tête de requête pour sélectionner une représentation qui est entièrement sous son contrôle (par exemple, via un champ d'en-tête privé ou des métadonnées de requête internes) et, dans ce cas, n'aurait pas besoin de le publier dans Vary.

7.2. Champs d'en-tête de validation (Validator Header Fields)

Les champs d'en-tête de validation transmettent des métadonnées sur la représentation sélectionnée (Section 3). Dans les réponses aux méthodes sûres, les champs de validation décrivent la représentation sélectionnée. Dans les réponses aux méthodes de changement d'état, les champs de validation décrivent la nouvelle représentation qui a remplacé la représentation sélectionnée précédente suite au traitement réussi de la requête.

7.2.1. ETag

Le champ d'en-tête "ETag" dans une réponse fournit l'entité-tag actuelle pour la représentation sélectionnée, telle que déterminée à la conclusion du traitement de la requête. Une entité-tag est un validateur opaque pour différencier plusieurs représentations de la même ressource, que ces multiples représentations soient dues à des changements d'état de ressource au fil du temps, à une négociation de contenu résultant en plusieurs représentations valides en même temps, ou les deux.

ETag = entity-tag

La grammaire entity-tag est définie dans la Section 2.3 de [RFC7232]:

entity-tag = [ weak ] opaque-tag
weak = %x57.2F ; "W/", sensible à la casse
opaque-tag = DQUOTE *etagc DQUOTE
etagc = %x21 / %x23-7E / obs-text
; VCHAR sauf guillemets doubles, plus obs-text

Note: Précédemment, opaque-tag était défini comme étant une quoted-string ([RFC2616], Section 3.11); ainsi, certains destinataires pourraient effectuer un échappement des antislashs. Les serveurs devraient donc (ought to) éviter les caractères antislash dans les entités-tags.

Une entité-tag peut être soit un validateur faible, soit un validateur fort, le fort étant la valeur par défaut. Si un serveur d'origine fournit une entité-tag pour une représentation et que la génération de cette entité-tag ne satisfait pas toutes les caractéristiques d'un validateur fort (Section 2.1 de [RFC7232]), alors le serveur d'origine DOIT (MUST) marquer l'entité-tag comme faible en préfixant sa valeur opaque de "W/" (sensible à la casse).

Un expéditeur PEUT (MAY) envoyer le champ ETag dans une section de remorque (trailer section) (Section 4.1.2 de [RFC7230]), mais cela n'est utile que pour les réponses qui n'ont pas d'encodage de contenu et où l'agent utilisateur peut calculer l'entité-tag avant de recevoir la section de remorque. Lorsque ETag est envoyé dans la section de remorque, il remplace toute valeur de champ ETag envoyée dans la section d'en-tête.

Exemples:

ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""

Un serveur d'origine DEVRAIT (SHOULD) envoyer un ETag pour toute représentation sélectionnée pour laquelle la détection des changements peut être raisonnablement et systématiquement déterminée, car l'utilisation de l'entité-tag dans les requêtes conditionnelles et l'évaluation de la fraîcheur du cache ([RFC7234]) peut réduire substantiellement les transferts inutiles et améliorer significativement la disponibilité et l'évolutivité du service.

7.2.2. Last-Modified

Le champ d'en-tête "Last-Modified" dans une réponse fournit un horodatage indiquant la date et l'heure auxquelles le serveur d'origine estime que la représentation sélectionnée a été modifiée pour la dernière fois, comme déterminé à la conclusion du traitement de la requête.

Last-Modified = HTTP-date

Un exemple de son utilisation:

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

Un serveur d'origine DEVRAIT (SHOULD) envoyer Last-Modified pour toute représentation sélectionnée pour laquelle une date de dernière modification peut être raisonnablement et systématiquement déterminée, car son utilisation dans les requêtes conditionnelles et l'évaluation de la fraîcheur du cache ([RFC7234]) peut réduire substantiellement les transferts inutiles et améliorer significativement la disponibilité et l'évolutivité du service. Une représentation est généralement la somme de nombreuses parties derrière l'interface de la ressource. Le temps de dernière modification serait généralement le temps le plus récent auquel l'une de ces parties a été modifiée.

Un serveur d'origine DEVRAIT (SHOULD) obtenir la valeur Last-Modified de la représentation aussi proche que possible du moment où il génère la valeur du champ Date pour la réponse. Cela permet à un destinataire de faire une évaluation précise du temps de modification de la représentation, en particulier si la représentation change près du moment où la réponse est générée.

Un serveur d'origine avec une horloge (telle que définie dans la Section 7.1.1.1) NE DOIT PAS (MUST NOT) envoyer une date Last-Modified postérieure à l'heure d'origine du message du serveur (Date). Si le temps de dernière modification est dérivé de métadonnées spécifiques à l'implémentation qui s'évaluent à un moment futur, selon l'horloge du serveur d'origine, alors le serveur d'origine DOIT (MUST) remplacer cette valeur par la date d'origine du message. Cela empêche une date de modification future d'avoir un impact négatif sur la validation du cache.

Un serveur d'origine sans horloge NE DOIT PAS (MUST NOT) attribuer de valeurs Last-Modified à une réponse à moins que ces valeurs n'aient été associées à la ressource par un autre système avec une horloge ou à moins que les valeurs n'aient été précédemment reçues du serveur d'origine (par exemple, d'une base de données backend).


7.3. Défis d'authentification (Authentication Challenges)

Les défis d'authentification indiquent quels mécanismes sont disponibles pour que le client fournisse des informations d'authentification dans les requêtes futures.

7.3.1. WWW-Authenticate

Le champ d'en-tête "WWW-Authenticate" indique le(s) schéma(s) d'authentification et les paramètres applicables à la ressource cible.

WWW-Authenticate = 1#challenge

Un serveur générant une réponse 401 (Unauthorized) DOIT (MUST) envoyer un champ d'en-tête WWW-Authenticate contenant au moins un défi. Un serveur PEUT (MAY) générer un champ d'en-tête WWW-Authenticate dans d'autres messages de réponse pour indiquer que la fourniture d'informations d'identification (ou d'informations différentes) pourrait affecter la réponse.

Un proxy transférant une réponse NE DOIT PAS (MUST NOT) modifier les champs WWW-Authenticate dans cette réponse.

Il est conseillé aux agents utilisateurs de prendre un soin particulier lors de l'analyse de la valeur du champ, car elle peut contenir plus d'un défi, et chaque défi peut contenir une liste de paramètres d'authentification séparés par des virgules. De plus, le champ d'en-tête lui-même peut apparaître plusieurs fois.

Pour plus de détails, voir la Section 4.1 de [RFC7235].

7.3.2. Proxy-Authenticate

Le champ d'en-tête "Proxy-Authenticate" consiste en au moins un défi qui indique le(s) schéma(s) d'authentification et les paramètres applicables au proxy pour cette cible de requête. Un proxy DOIT (MUST) envoyer au moins un champ d'en-tête Proxy-Authenticate dans chaque réponse 407 (Proxy Authentication Required) qu'il génère.

Proxy-Authenticate = 1#challenge

Contrairement à WWW-Authenticate, le champ d'en-tête Proxy-Authenticate s'applique uniquement au prochain client sortant dans la chaîne de réponse. En effet, seul le client qui a choisi un proxy donné est susceptible d'avoir les informations d'identification nécessaires pour l'authentification. Cependant, lorsque plusieurs proxys sont utilisés dans le même domaine administratif, comme les proxys de mise en cache de bureau et régionaux dans un grand réseau d'entreprise, il est courant que les informations d'identification soient générées par l'agent utilisateur et transmises à travers la hiérarchie jusqu'à ce qu'elles soient consommées. Par conséquent, dans une telle configuration, il apparaîtra comme si Proxy-Authenticate était transféré car chaque proxy enverra le même ensemble de défis.

Pour plus de détails, voir la Section 4.3 de [RFC7235].

7.4. Contexte de réponse (Response Context)

Les champs d'en-tête de réponse suivants fournissent des informations supplémentaires sur la réponse, au-delà de ce qui est impliqué par le code d'état, ou sur le serveur traitant la réponse.

7.4.1. Allow

Le champ d'en-tête "Allow" répertorie l'ensemble des méthodes annoncées comme étant prises en charge par la ressource cible. Le but de ce champ est strictement d'informer le destinataire des méthodes de requête valides associées à la ressource.

Allow = #method

Exemple d'utilisation:

Allow: GET, HEAD, PUT

L'ensemble réel des méthodes autorisées est défini par le serveur d'origine au moment de chaque requête. Un serveur d'origine DOIT (MUST) générer un champ Allow dans une réponse 405 (Method Not Allowed) et PEUT (MAY) le faire dans toute autre réponse. Une valeur de champ Allow vide indique que la ressource n'autorise aucune méthode, ce qui pourrait se produire dans une réponse 405 si la ressource a été temporairement désactivée par configuration.

Un proxy NE DOIT PAS (MUST NOT) modifier le champ d'en-tête Allow -- il n'a pas besoin de comprendre toutes les méthodes indiquées pour les gérer selon les règles générales de traitement des messages.

7.4.2. Server

Le champ d'en-tête "Server" contient des informations sur le logiciel utilisé par le serveur d'origine pour traiter la requête, qui est souvent utilisé par les clients pour aider à identifier l'étendue des problèmes d'interopérabilité signalés, pour contourner ou adapter les requêtes afin d'éviter des limitations particulières du serveur, et pour l'analyse concernant l'utilisation du serveur ou du système d'exploitation. Un serveur d'origine PEUT (MAY) générer un champ Server dans n'importe quelle réponse.

Server = product *( RWS ( product / comment ) )

La valeur du champ Server consiste en un ou plusieurs identifiants de produit, chacun suivi de zéro ou plusieurs commentaires (Section 3.2 de [RFC7230]), qui ensemble identifient le logiciel du serveur d'origine et ses sous-produits significatifs. Par convention, les identifiants de produit sont listés dans l'ordre décroissant de leur importance pour l'identification du logiciel du serveur d'origine. Chaque identifiant de produit consiste en un nom et une version optionnelle, comme défini dans la Section 5.5.3 de [RFC7230].

Exemple:

Server: CERN/3.0 libwww/2.17

Un serveur d'origine NE DEVRAIT PAS (SHOULD NOT) générer un champ Server contenant des détails inutilement fins et DEVRAIT (SHOULD) limiter l'ajout de sous-produits par des tiers. Les valeurs de champ Server trop longues et détaillées augmentent la latence de réponse et révèlent potentiellement des détails d'implémentation internes qui pourraient rendre (légèrement) plus facile pour les attaquants de trouver et d'exploiter des failles de sécurité connues.