Aller au contenu principal

10. Contexte du Message (Message Context)

10.1. Champs de Contexte de Requête (Request Context Fields)

Les champs d'en-tête de requête suivants fournissent des informations supplémentaires sur le contexte de la requête, y compris des informations sur l'utilisateur, l'agent utilisateur et la ressource derrière la requête.

10.1.1. Expect

Le champ d'en-tête "Expect" dans une requête indique un certain ensemble de comportements (attentes) qui doivent être pris en charge par le serveur afin de traiter correctement cette requête.

Expect =      #expectation
expectation = token [ "=" ( token / quoted-string ) parameters ]

La valeur du champ Expect est insensible à la casse.

La seule attente définie par cette spécification est "100-continue" (sans paramètres définis).

Un serveur qui reçoit une valeur de champ Expect contenant un membre autre que 100-continue PEUT répondre avec un code d'état 417 (Expectation Failed) pour indiquer que l'attente inattendue ne peut pas être satisfaite.

L'attente "100-continue" informe les destinataires que le client est sur le point d'envoyer un contenu (probablement volumineux) dans cette requête et souhaite recevoir une réponse intermédiaire 100 (Continue) si la méthode, l'URI cible et les champs d'en-tête ne suffisent pas à provoquer une réponse de succès, de redirection ou d'erreur immédiate. Cela permet au client d'attendre une indication qu'il vaut la peine d'envoyer le contenu avant de le faire réellement, ce qui peut améliorer l'efficacité lorsque les données sont volumineuses ou lorsque le client s'attend à ce qu'une erreur soit probable (par exemple, lors de l'envoi d'une méthode de changement d'état, sans identifiants d'authentification préalablement vérifiés).

Par exemple, une requête qui commence par

PUT /somewhere/fun HTTP/1.1
Host: origin.example.com
Content-Type: video/h264
Content-Length: 1234567890987
Expect: 100-continue

permet au serveur d'origine de répondre immédiatement avec un message d'erreur, tel que 401 (Unauthorized) ou 405 (Method Not Allowed), avant que le client ne commence à remplir les tuyaux avec un transfert de données inutile.

Exigences pour les clients :

  • Un client NE DOIT PAS (MUST NOT) générer une attente 100-continue dans une requête qui n'inclut pas de contenu.
  • Un client qui attendra une réponse 100 (Continue) avant d'envoyer le contenu de la requête DOIT (MUST) envoyer un champ d'en-tête Expect contenant une attente 100-continue.
  • Un client qui envoie une attente 100-continue n'est pas tenu d'attendre une durée spécifique ; un tel client PEUT (MAY) continuer à envoyer le contenu même s'il n'a pas encore reçu de réponse. De plus, étant donné que les réponses 100 (Continue) ne peuvent pas être envoyées via un intermédiaire HTTP/1.0, un tel client NE DEVRAIT PAS (SHOULD NOT) attendre indéfiniment avant d'envoyer le contenu.
  • Un client qui reçoit un code d'état 417 (Expectation Failed) en réponse à une requête contenant une attente 100-continue DEVRAIT (SHOULD) répéter cette requête sans attente 100-continue, car la réponse 417 indique simplement que la chaîne de réponse ne prend pas en charge les attentes (par exemple, elle passe par un serveur HTTP/1.0).

Exigences pour les serveurs :

  • Un serveur qui reçoit une attente 100-continue dans une requête HTTP/1.0 DOIT (MUST) ignorer cette attente.
  • Un serveur PEUT (MAY) omettre d'envoyer une réponse 100 (Continue) s'il a déjà reçu une partie ou la totalité du contenu de la requête correspondante, ou si le cadrage indique qu'il n'y a pas de contenu.
  • Un serveur qui envoie une réponse 100 (Continue) DOIT (MUST) finalement envoyer un code d'état final, une fois qu'il a reçu et traité le contenu de la requête, sauf si la connexion est fermée prématurément.
  • Un serveur qui répond avec un code d'état final avant de lire tout le contenu de la requête DEVRAIT (SHOULD) indiquer s'il a l'intention de fermer la connexion (par exemple, voir Section 9.6 de [HTTP/1.1]) ou de continuer à lire le contenu de la requête.

Lors de la réception d'une requête HTTP/1.1 (ou ultérieure) qui a une méthode, un URI cible et une section d'en-tête complète qui contient une attente 100-continue et indique qu'un contenu de requête suivra, un serveur d'origine DOIT (MUST) envoyer soit :

  • une réponse immédiate avec un code d'état final, si ce statut peut être déterminé en examinant uniquement la méthode, l'URI cible et les champs d'en-tête, ou
  • une réponse immédiate 100 (Continue) pour encourager le client à envoyer le contenu de la requête.

Le serveur d'origine NE DOIT PAS (MUST NOT) attendre le contenu avant d'envoyer la réponse 100 (Continue).

Lors de la réception d'une requête HTTP/1.1 (ou ultérieure) qui a une méthode, un URI cible et une section d'en-tête complète qui contient une attente 100-continue et indique qu'un contenu de requête suivra, un proxy DOIT (MUST) soit :

  • envoyer une réponse immédiate avec un code d'état final, si ce statut peut être déterminé en examinant uniquement la méthode, l'URI cible et les champs d'en-tête, ou
  • transférer la requête vers le serveur d'origine en envoyant une ligne de requête et une section d'en-tête correspondantes au serveur entrant suivant.

Si le proxy croit (d'après la configuration ou une interaction passée) que le serveur entrant suivant ne prend en charge que HTTP/1.0, le proxy PEUT (MAY) générer une réponse immédiate 100 (Continue) pour encourager le client à commencer à envoyer le contenu.

10.1.2. From

Le champ d'en-tête "From" contient une adresse e-mail Internet pour un utilisateur humain qui contrôle l'agent utilisateur demandeur. L'adresse devrait être utilisable par machine, comme défini par "mailbox" dans la Section 3.4 de [RFC5322] :

From    = mailbox

mailbox = <mailbox, see [RFC5322], Section 3.4>

Un exemple est :

Le champ d'en-tête From est rarement envoyé par des agents utilisateur non robotiques. Un agent utilisateur NE DEVRAIT PAS (SHOULD NOT) envoyer un champ d'en-tête From sans configuration explicite de l'utilisateur, car cela pourrait entrer en conflit avec les intérêts de confidentialité de l'utilisateur ou la politique de sécurité de son site.

Un agent utilisateur robotique DEVRAIT (SHOULD) envoyer un champ d'en-tête From valide afin que la personne responsable de l'exécution du robot puisse être contactée en cas de problèmes sur les serveurs, par exemple si le robot envoie des requêtes excessives, non désirées ou invalides.

Un serveur NE DEVRAIT PAS (SHOULD NOT) utiliser le champ d'en-tête From pour le contrôle d'accès ou l'authentification, car sa valeur est censée être visible pour toute personne qui reçoit ou observe la requête et est souvent enregistrée dans les fichiers journaux et les rapports d'erreur sans aucune attente de confidentialité.

10.1.3. Referer

Le champ d'en-tête "Referer" [sic] permet à l'agent utilisateur de spécifier une référence URI pour la ressource à partir de laquelle l'URI cible a été obtenu (c'est-à-dire, le "référent", bien que le nom du champ soit mal orthographié). Un agent utilisateur NE DOIT PAS (MUST NOT) inclure les composants fragment et userinfo de la référence URI [URI], le cas échéant, lors de la génération de la valeur du champ Referer.

Referer = absolute-URI / partial-URI

La valeur du champ est soit un absolute-URI soit un partial-URI. Dans ce dernier cas (Section 4), l'URI référé est relatif à l'URI cible ([URI], Section 5).

Le champ d'en-tête Referer permet aux serveurs de générer des rétroliens vers d'autres ressources pour des analyses simples, la journalisation, la mise en cache optimisée, etc. Il permet également de trouver des liens obsolètes ou mal orthographiés à des fins de maintenance. Certains serveurs utilisent le champ d'en-tête Referer comme moyen de refuser les liens provenant d'autres sites (ce qu'on appelle le "deep linking") ou de restreindre la falsification de requête intersite (CSRF), mais toutes les requêtes ne le contiennent pas.

Exemple :

Referer: http://www.example.org/hypertext/Overview.html

Si l'URI cible a été obtenu à partir d'une source qui n'a pas son propre URI (par exemple, une entrée du clavier de l'utilisateur ou une entrée dans les signets/favoris de l'utilisateur), l'agent utilisateur DOIT (MUST) soit exclure le champ d'en-tête Referer, soit l'envoyer avec une valeur de "about:blank".

La valeur du champ d'en-tête Referer n'a pas besoin de transmettre l'URI complet de la ressource référente ; un agent utilisateur PEUT (MAY) tronquer les parties autres que l'origine référente.

Le champ d'en-tête Referer a le potentiel de révéler des informations sur le contexte de la requête ou l'historique de navigation de l'utilisateur, ce qui constitue un problème de confidentialité si l'identifiant de la ressource référente révèle des informations personnelles (telles qu'un nom de compte) ou une ressource censée être confidentielle (telle que derrière un pare-feu ou à l'intérieur d'un service sécurisé). La plupart des agents utilisateur à usage général n'envoient pas le champ d'en-tête Referer lorsque la ressource référente est un URI "file" ou "data" local. Un agent utilisateur NE DEVRAIT PAS (SHOULD NOT) envoyer un champ d'en-tête Referer si la ressource référente a été accédée avec un protocole sécurisé et que l'origine de la cible de la requête diffère de celle de la ressource référente, à moins que la ressource référente ne permette explicitement l'envoi du Referer. Un agent utilisateur NE DOIT PAS (MUST NOT) envoyer un champ d'en-tête Referer dans une requête HTTP non sécurisée si la ressource référente a été accédée avec un protocole sécurisé. Voir Section 17.9 pour des considérations de sécurité supplémentaires.

Certains intermédiaires sont connus pour supprimer indistinctement les champs d'en-tête Referer des requêtes sortantes. Cela a l'effet secondaire malheureux d'interférer avec la protection contre les attaques CSRF, ce qui peut être beaucoup plus préjudiciable pour leurs utilisateurs. Les intermédiaires et les extensions d'agent utilisateur qui souhaitent limiter la divulgation d'informations dans Referer devraient limiter leurs modifications à des modifications spécifiques, telles que le remplacement des noms de domaine internes par des pseudonymes ou la troncature des composants de requête et/ou de chemin. Un intermédiaire NE DEVRAIT PAS (SHOULD NOT) modifier ou supprimer le champ d'en-tête Referer lorsque la valeur du champ partage le même schéma et hôte que la cible de la requête.

10.1.4. TE

Le champ d'en-tête "TE" décrit les capacités du client concernant les codages de transfert et les sections de remorque.

Comme décrit dans la Section 6.5, l'envoi de TE avec un membre "trailers" dans une requête indique que le client ne rejettera pas les champs de remorque.

TE est également utilisé dans HTTP/1.1 pour informer les serveurs des codages de transfert que le client est capable d'accepter dans la réponse. Au moment de la publication, seul HTTP/1.1 utilise les codages de transfert (voir Section 7 de [HTTP/1.1]).

La valeur du champ TE est une liste de membres, chaque membre (à part "trailers") consistant en un jeton de nom de codage de transfert avec un poids optionnel qui indique la préférence relative du client pour ce codage de transfert (Section 12.4.2) et des paramètres optionnels pour ce codage de transfert.

TE                 = #t-codings
t-codings = "trailers" / ( transfer-coding [ weight ] )
transfer-coding = token *( OWS ";" OWS transfer-parameter )
transfer-parameter = token BWS "=" BWS ( token / quoted-string )

Un expéditeur de TE DOIT (MUST) également envoyer une option de connexion "TE" dans le champ d'en-tête Connection (Section 7.6.1) pour empêcher le champ TE d'être transféré par des intermédiaires qui ne prennent pas en charge sa sémantique.

10.1.5. User-Agent

Le champ d'en-tête "User-Agent" contient des informations sur l'agent utilisateur à l'origine de la requête, qui est souvent utilisé par les serveurs pour aider à identifier la portée des problèmes d'interopérabilité signalés, pour contourner ou adapter les réponses afin d'éviter des limitations particulières de l'agent utilisateur, et pour des analyses concernant l'utilisation du navigateur ou du système d'exploitation. Un agent utilisateur DEVRAIT (SHOULD) envoyer un champ d'en-tête User-Agent dans chaque requête, sauf s'il est spécifiquement configuré pour ne pas le faire.

User-Agent = product *( RWS ( product / comment ) )

La valeur du champ User-Agent se compose d'un ou plusieurs identifiants de produit, chacun suivi de zéro ou plusieurs commentaires (Section 5.6.5), qui identifient ensemble le logiciel de l'agent utilisateur et ses sous-produits importants. Par convention, les identifiants de produit sont listés par ordre décroissant de leur importance pour identifier le logiciel de l'agent utilisateur. Chaque identifiant de produit se compose d'un nom et d'une version optionnelle.

product         = token ["/" product-version]
product-version = token

Un expéditeur DEVRAIT (SHOULD) limiter les identifiants de produit générés à ce qui est nécessaire pour identifier le produit ; un expéditeur NE DOIT PAS (MUST NOT) générer de publicité ou d'autres informations non essentielles dans l'identifiant de produit. Un expéditeur NE DEVRAIT PAS (SHOULD NOT) générer d'informations dans product-version qui ne soient pas un identifiant de version (c'est-à-dire que les versions successives du même nom de produit ne devraient différer que dans la partie product-version de l'identifiant de produit).

Exemple :

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Un agent utilisateur NE DEVRAIT PAS (SHOULD NOT) générer un champ d'en-tête User-Agent contenant des détails inutilement précis et DEVRAIT (SHOULD) limiter l'ajout de sous-produits par des tiers. Des valeurs de champ User-Agent excessivement longues et détaillées augmentent la latence des requêtes et le risque qu'un utilisateur soit identifié contre son gré ("empreinte digitale").

De même, les implémentations sont encouragées à ne pas utiliser les jetons de produit d'autres implémentations afin de déclarer leur compatibilité avec elles, car cela contourne le but du champ. Si un agent utilisateur se fait passer pour un agent utilisateur différent, les destinataires peuvent supposer que l'utilisateur souhaite intentionnellement voir des réponses adaptées à cet agent utilisateur identifié, même si elles peuvent ne pas fonctionner aussi bien pour l'agent utilisateur réellement utilisé.

10.2. Champs de Contexte de Réponse (Response Context Fields)

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, y compris des informations sur le serveur, la ressource cible ou les ressources associées.

10.2.1. Allow

Le champ d'en-tête "Allow" liste l'ensemble des méthodes annoncées comme 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 d'en-tête Allow dans une réponse 405 (Method Not Allowed) et PEUT (MAY) le faire dans n'importe quelle autre réponse. Une valeur de champ Allow vide indique que la ressource n'autorise aucune méthode, ce qui peut 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 traiter selon les règles générales de traitement des messages.

10.2.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 se compose d'une seule URI-reference. Lorsqu'elle a la forme d'une référence relative ([URI], Section 4.2), la valeur finale est calculée en la résolvant par rapport à l'URI cible ([URI], Section 5).

Pour les réponses 201 (Created), la valeur Location fait référence à 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 l'URI cible (c'est-à-dire que la redirection hérite du fragment de la référence originale, le cas échéant).

Par exemple, une requête GET générée pour la référence URI "http://www.example.org/~tim" peut entraîner une réponse 303 (See Other) contenant le champ d'en-tête :

Location: /People.html#tim

ce qui suggère que l'agent utilisateur redirige vers "http://www.example.org/People.html#tim"

De même, une requête GET générée pour la référence URI "http://www.example.org/index.html#larry" peut entraîner une réponse 301 (Moved Permanently) contenant le champ d'en-tête :

Location: http://www.example.net/index.html

ce qui suggère que l'agent utilisateur redirige vers "http://www.example.net/index.html#larry", en préservant l'identifiant de fragment original.

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 d'en-tête 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 ne peut pas permettre une liste de membres, car le séparateur de liste par virgule est une donnée valide dans une URI-reference. Si un message invalide est envoyé avec plusieurs lignes de champ Location, un destinataire le long du chemin peut combiner ces lignes de champ en une seule valeur. La récupération d'une valeur de champ Location valide à partir d'une telle situation est difficile et n'est pas interopérable entre les implémentations.

Note : Le champ d'en-tête Content-Location (Section 8.7) diffère de Location en ce que Content-Location fait référence à la ressource la plus spécifique correspondant à la représentation incluse. Il est donc possible qu'une réponse contienne à la fois les champs d'en-tête Location et Content-Location.

10.2.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 n'importe quelle 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 du champ Retry-After peut être soit une HTTP-date soit un nombre de secondes à retarder 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 sont

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

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

10.2.4. 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 la portée 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 des analyses concernant l'utilisation du serveur ou du système d'exploitation. Un serveur d'origine PEUT (MAY) générer un champ d'en-tête Server dans ses réponses.

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

La valeur du champ d'en-tête Server se compose d'un ou plusieurs identifiants de produit, chacun suivi de zéro ou plusieurs commentaires (Section 5.6.5), qui identifient ensemble le logiciel du serveur d'origine et ses sous-produits importants. Par convention, les identifiants de produit sont listés par ordre décroissant de leur importance pour identifier le logiciel du serveur d'origine. Chaque identifiant de produit se compose d'un nom et d'une version optionnelle, comme défini dans la Section 10.1.5.

Exemple :

Server: CERN/3.0 libwww/2.17

Un serveur d'origine NE DEVRAIT PAS (SHOULD NOT) générer un champ d'en-tête Server contenant des détails inutilement précis et DEVRAIT (SHOULD) limiter l'ajout de sous-produits par des tiers. Des valeurs de champ Server excessivement longues et détaillées augmentent la latence des réponses 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.