Aller au contenu principal

4. Constructing Responses from Caches (Construction de réponses à partir des caches)

Lorsqu'une requête est présentée, un cache ne doit pas (MUST NOT) réutiliser une réponse stockée à moins que toutes les conditions suivantes ne soient remplies :

  • L'URI cible présenté (voir la section 7.1 de [HTTP]) correspond à l'URI cible de la réponse stockée, et

  • La méthode de requête associée à la réponse stockée permet de l'utiliser pour la requête présentée, et

  • Les champs d'en-tête de requête spécifiés par la réponse stockée (le cas échéant) correspondent à ceux de la requête présentée (voir la section 4.1), et

  • La réponse stockée ne contient pas de directive no-cache (section 5.2.2.4), sauf si elle a été validée avec succès (section 4.3), et

  • La réponse stockée est l'une des suivantes :

    • Fraîche (voir la section 4.2), ou

    • Autorisée à être servie périmée (voir la section 4.2.4), ou

    • Validée avec succès (voir la section 4.3).

Notez que les extensions de cache peuvent remplacer l'une des exigences énumérées ci-dessus ; voir la section 5.2.3.

Lors de l'utilisation d'une réponse stockée pour satisfaire une requête sans validation, un cache doit (MUST) générer un champ d'en-tête Age (section 5.1), en remplaçant tout champ Age présent dans la réponse par une valeur égale au current_age de la réponse stockée ; voir la section 4.2.3.

Un cache doit (MUST) transmettre directement les requêtes avec des méthodes non sûres (voir la section 9.2.1 de [HTTP]) au serveur d'origine ; c'est-à-dire qu'un cache n'est pas autorisé à générer une réponse à une telle requête avant d'avoir transféré la requête et reçu une réponse correspondante.

De plus, notez que les requêtes non sûres peuvent invalider les réponses stockées ; voir la section 4.4.

Un cache peut (MAY) utiliser une réponse stockée ou stockable pour satisfaire plusieurs requêtes, à condition que la réponse soit autorisée à être réutilisée pour les requêtes en question. Cela permet aux caches de "regrouper les requêtes (Collapse Requests)" -- ou de combiner plusieurs requêtes entrantes en une seule requête de transfert lors d'un échec de cache -- réduisant ainsi la charge sur le serveur d'origine et le réseau. Cependant, notez que si le cache ne peut pas utiliser la réponse renvoyée pour certaines ou toutes les requêtes regroupées, il devra transférer ces requêtes pour les satisfaire, ce qui peut introduire une latence supplémentaire.

Lorsque plusieurs réponses appropriées sont stockées, un cache doit (MUST) utiliser la réponse la plus récente (déterminée par le champ d'en-tête Date). Il peut également transférer la requête avec "Cache-Control: max-age=0" ou "Cache-Control: no-cache" pour lever l'ambiguïté sur la réponse à utiliser.

Un cache sans horloge (voir la section 5.6.7 de [HTTP]) doit (MUST) revalider les réponses stockées à chaque utilisation.

4.1 Calculating Cache Keys with the Vary Header Field (Calcul des clés de cache avec le champ d'en-tête Vary)

Lorsqu'un cache reçoit une requête qui peut être satisfaite par une réponse stockée et que cette réponse stockée contient un champ d'en-tête Vary (voir la section 12.5.5 de [HTTP]), le cache ne doit pas (MUST NOT) utiliser cette réponse stockée sans revalidation à moins que tous les champs d'en-tête de requête désignés par la valeur du champ Vary ne correspondent à la fois dans la requête d'origine (c'est-à-dire la requête qui a provoqué le stockage de la réponse mise en cache) et dans la requête présentée.

Les champs d'en-tête de deux requêtes sont définis comme correspondants si et seulement si les champs d'en-tête de la première requête peuvent être transformés en champs d'en-tête de la deuxième requête en appliquant l'une des opérations suivantes :

  • Ajout ou suppression d'espaces blancs, lorsque cela est autorisé par la syntaxe du champ d'en-tête

  • Combinaison de plusieurs lignes de champ d'en-tête avec le même nom de champ (voir la section 5.2 de [HTTP])

  • Normalisation des deux valeurs de champ d'en-tête d'une manière connue pour avoir une sémantique identique, selon la spécification du champ d'en-tête (par exemple, réorganisation des valeurs de champ lorsque l'ordre n'est pas significatif ; normalisation de la casse, lorsque les valeurs sont définies comme insensibles à la casse)

Si un champ d'en-tête est absent d'une requête, il ne peut correspondre que s'il est également absent de l'autre requête.

Une réponse stockée avec une valeur de champ d'en-tête Vary contenant le membre "*" échoue toujours à correspondre.

Si plusieurs réponses stockées correspondent, un cache devra en choisir une à utiliser. Lorsque les champs d'en-tête de requête désignés ont un mécanisme d'ordre de préférence connu (par exemple, les qvalues sur Accept et des champs d'en-tête de requête similaires), ce mécanisme peut (MAY) être utilisé pour sélectionner la réponse préférée. Si un tel mécanisme n'existe pas ou aboutit à des réponses également préférées, la réponse la plus récente (déterminée par le champ d'en-tête Date) est sélectionnée, conformément à la section 4.

Certaines ressources omettent incorrectement le champ d'en-tête Vary de leur réponse par défaut (c'est-à-dire celle envoyée lorsque la requête n'exprime aucune préférence), avec pour effet qu'elle est sélectionnée pour les requêtes ultérieures à cette ressource même lorsqu'une réponse plus préférée est disponible. Lorsqu'un cache a plusieurs réponses stockées pour un URI cible et qu'une ou plusieurs omettent le champ d'en-tête Vary, le cache devrait (SHOULD) sélectionner la réponse stockée la plus récente (voir la section 4.2.3) qui a une valeur de champ Vary valide.

Si aucune réponse stockée ne correspond, le cache ne peut pas satisfaire la requête présentée. Typiquement, la requête est transférée au serveur d'origine, éventuellement avec des préconditions ajoutées pour décrire les réponses que le cache a déjà stockées (section 4.3).

4.2 Freshness (Fraîcheur)

Une réponse "fraîche (Fresh)" est une réponse dont l'âge n'a pas encore dépassé sa durée de vie de fraîcheur. Inversement, une réponse "périmée (Stale)" est une réponse où elle a été dépassée.

La "durée de vie de fraîcheur (Freshness Lifetime)" d'une réponse est la durée entre sa génération par le serveur d'origine et son temps d'expiration. Un "temps d'expiration explicite (Explicit Expiration Time)" est le moment auquel le serveur d'origine a l'intention qu'un cache n'utilise plus une réponse stockée sans validation supplémentaire, tandis qu'un "temps d'expiration heuristique (Heuristic Expiration Time)" est celui assigné par un cache lorsqu'aucun temps d'expiration explicite n'est disponible.

L'"âge (Age)" d'une réponse est le temps qui s'est écoulé depuis qu'elle a été générée ou validée avec succès au niveau du serveur d'origine.

Lorsqu'une réponse est fraîche, elle peut être utilisée pour satisfaire les requêtes ultérieures sans contacter le serveur d'origine, améliorant ainsi l'efficacité.

Le mécanisme principal pour déterminer la fraîcheur est que le serveur d'origine fournisse un temps d'expiration explicite dans le futur, en utilisant soit le champ d'en-tête Expires (section 5.3), soit la directive de réponse max-age (section 5.2.2.1). Généralement, un serveur d'origine attribuera un temps d'expiration explicite futur à une réponse, croyant que la représentation est peu susceptible de changer de manière sémantiquement significative avant ce temps d'expiration.

Si un serveur d'origine souhaite forcer un cache à valider chaque requête, il peut attribuer un temps d'expiration explicite dans le passé pour indiquer que la réponse est déjà périmée. Les caches conformes valideront normalement une réponse mise en cache périmée avant de la réutiliser (voir la section 4.2.4).

Étant donné que les serveurs d'origine ne fournissent pas toujours des temps d'expiration explicites, les caches sont également autorisés à utiliser une heuristique pour déterminer un temps d'expiration dans certaines circonstances (voir la section 4.2.2).

Le calcul pour déterminer si une réponse est fraîche est :

response_is_fresh = (freshness_lifetime > current_age)

freshness_lifetime est défini dans la section 4.2.1 ; current_age est défini dans la section 4.2.3.

Les clients peuvent envoyer les directives de requête max-age ou min-fresh (section 5.2.1) pour suggérer des limites sur les calculs de fraîcheur pour la réponse correspondante. Cependant, les caches ne sont pas tenus de les honorer.

Lors du calcul de la fraîcheur, pour éviter les problèmes courants d'analyse de date :

  • Bien que tous les formats de date soient spécifiés comme sensibles à la casse, les destinataires de cache devraient (SHOULD) faire correspondre les valeurs de champ de manière insensible à la casse.

  • Si la représentation interne du temps d'un destinataire de cache a une résolution inférieure à la valeur du HTTP-date, le destinataire doit (MUST) représenter en interne la date Expires analysée comme le moment le plus tôt égal ou antérieur à la valeur reçue.

  • Un destinataire de cache ne doit pas (MUST NOT) permettre au fuseau horaire local d'affecter le calcul ou la comparaison de l'âge ou des temps d'expiration.

  • Un destinataire de cache devrait (SHOULD) considérer les dates avec des abréviations de fuseau horaire autres que "GMT" comme non valides pour le calcul de l'expiration.

Notez que la fraîcheur s'applique uniquement aux opérations de cache ; elle ne peut pas être utilisée pour forcer un agent utilisateur à actualiser son affichage ou à recharger une ressource. Voir la section 6 pour une explication des différences entre les caches et les mécanismes d'historique.

4.2.1 Calculating Freshness Lifetime (Calcul de la durée de vie de fraîcheur)

Un cache peut calculer la durée de vie de fraîcheur (désignée comme freshness_lifetime) d'une réponse en évaluant les règles suivantes et en utilisant la première correspondance :

  • Si le cache est partagé et que la directive de réponse s-maxage (section 5.2.2.10) est présente, utiliser sa valeur, ou

  • Si la directive de réponse max-age (section 5.2.2.1) est présente, utiliser sa valeur, ou

  • Si le champ d'en-tête de réponse Expires (section 5.3) est présent, utiliser sa valeur moins la valeur du champ d'en-tête de réponse Date (en utilisant le moment où le message a été reçu s'il n'est pas présent, conformément à la section 6.6.1 de [HTTP]), ou

  • Sinon, aucun temps d'expiration explicite n'est présent dans la réponse. Une durée de vie de fraîcheur heuristique peut être applicable ; voir la section 4.2.2.

Notez que ce calcul est destiné à réduire le décalage d'horloge en utilisant autant que possible les informations de l'horloge du serveur d'origine.

Lorsqu'il y a plusieurs occurrences d'une directive donnée (par exemple, deux lignes de champ d'en-tête Expires ou plusieurs directives Cache-Control: max-age), soit la première occurrence doit être utilisée, soit la réponse doit être considérée comme périmée. Si les directives sont en conflit (par exemple, max-age et no-cache sont tous deux présents), la directive la plus restrictive doit être honorée. Les caches sont encouragés à considérer les réponses avec des informations de fraîcheur non valides (par exemple, une directive max-age avec un contenu non entier) comme périmées.

4.2.2 Calculating Heuristic Freshness (Calcul de la fraîcheur heuristique)

Étant donné que les serveurs d'origine ne fournissent pas toujours des temps d'expiration explicites, un cache peut (MAY) attribuer un temps d'expiration heuristique lorsqu'aucun temps explicite n'est spécifié, en utilisant un algorithme qui emploie d'autres valeurs de champ d'en-tête (telles que l'heure Last-Modified) pour estimer un temps d'expiration plausible. Cette spécification ne fournit pas d'algorithme spécifique mais impose des contraintes de cas extrême sur ses résultats.

Un cache ne doit pas (MUST NOT) utiliser d'heuristiques pour déterminer la fraîcheur lorsqu'un temps d'expiration explicite est présent dans une réponse stockée. Étant donné l'exigence de la section 3, les heuristiques ne peuvent être utilisées que sur des réponses sans fraîcheur explicite qui sont soit autorisées par leur code d'état à être heuristiquement cachables (voir, par exemple, la section 15.1 de [HTTP]), soit ont été marquées comme explicitement cachables (par exemple, avec une directive de réponse public).

Notez que dans les spécifications précédentes, les codes d'état de réponse heuristiquement cachables étaient connus sous le nom de "cachables par défaut (Cacheable by Default)".

Si la réponse a un champ d'en-tête Last-Modified (voir la section 8.8.2 de [HTTP]), les caches sont encouragés à utiliser une valeur d'expiration heuristique qui n'est pas supérieure à une fraction de l'intervalle depuis ce moment. Un réglage typique de cette fraction pourrait être de 10%.

Note : Les versions précédentes de la spécification HTTP ([RFC2616], section 13.9) interdisaient aux caches de calculer la fraîcheur heuristique pour les URI avec des composants de requête (c'est-à-dire ceux contenant "?"). En pratique, cela n'a pas été largement implémenté. Par conséquent, les serveurs d'origine sont encouragés à envoyer des directives explicites (par exemple, Cache-Control: no-cache) s'ils souhaitent empêcher la mise en cache.

4.2.3 Calculating Age (Calcul de l'âge)

Le champ d'en-tête Age est utilisé pour transmettre un âge estimé du message de réponse lorsqu'il est obtenu à partir d'un cache. La valeur du champ Age est l'estimation par le cache du temps en secondes depuis que la réponse a été générée ou validée au serveur d'origine. Ainsi, la valeur Age est la somme du temps pendant lequel la réponse a résidé dans chaque cache le long du chemin depuis le serveur d'origine jusqu'à l'arrivée, plus le temps passé en transit le long du chemin réseau.

Les données suivantes sont utilisées pour le calcul de l'âge :

age_value Le terme "age_value" désigne la valeur du champ d'en-tête Age (section 5.1) sous une forme appropriée pour les opérations arithmétiques ; ou 0, si non disponible.

date_value Le terme "date_value" désigne la valeur du champ d'en-tête Date sous une forme appropriée pour les opérations arithmétiques. Voir la section 6.6.1 de [HTTP] pour la définition du champ d'en-tête Date et les exigences pour les réponses sans celui-ci.

now Le terme "now" désigne la valeur actuelle de l'horloge de cette implémentation (voir la section 5.6.7 de [HTTP]).

request_time La valeur de l'horloge au moment de la requête qui a abouti à la réponse stockée.

response_time La valeur de l'horloge au moment où la réponse a été reçue.

L'âge d'une réponse peut être calculé de deux manières entièrement indépendantes :

  1. Le "apparent_age" : response_time moins date_value, si l'horloge de l'implémentation est raisonnablement bien synchronisée avec l'horloge du serveur d'origine. Si le résultat est négatif, le résultat est remplacé par zéro.

  2. Le "corrected_age_value", si tous les caches le long du chemin de réponse implémentent HTTP/1.1 ou supérieur. Un cache doit (MUST) interpréter cette valeur par rapport au moment où la requête a été initiée, et non au moment où la réponse a été reçue.

apparent_age = max(0, response_time - date_value);

response_delay = response_time - request_time;
corrected_age_value = age_value + response_delay;

Le corrected_age_value peut (MAY) être utilisé comme corrected_initial_age. Dans les cas où il pourrait y avoir de très anciennes implémentations de cache qui n'insèrent pas correctement Age, le corrected_initial_age peut être calculé de manière plus conservative comme

corrected_initial_age = max(apparent_age, corrected_age_value);

Le current_age d'une réponse stockée peut ensuite être calculé en ajoutant le temps (en secondes) depuis que la réponse stockée a été validée pour la dernière fois par le serveur d'origine au corrected_initial_age.

resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;

4.2.4 Serving Stale Responses (Fourniture de réponses périmées)

Une réponse "périmée (Stale)" est une réponse qui a soit des informations d'expiration explicites, soit permet le calcul de l'expiration heuristique et n'est pas fraîche selon le calcul de la section 4.2.

Un cache ne doit pas (MUST NOT) générer une réponse périmée si elle est interdite par une directive explicite dans le protocole (par exemple, par une directive de réponse no-cache, une directive de réponse must-revalidate, ou une directive de réponse s-maxage ou proxy-revalidate applicable ; voir la section 5.2.2).

Un cache ne doit pas (MUST NOT) générer une réponse périmée à moins que le cache ne soit déconnecté ou qu'elle ne soit explicitement autorisée par le client ou le serveur d'origine (par exemple, par la directive de requête max-stale de la section 5.2.1, par une directive d'extension définie par [RFC5861], ou par configuration selon un contrat hors bande).

4.3 Validation

Lorsqu'un cache a une ou plusieurs réponses stockées pour un URI demandé mais ne peut en servir aucune (par exemple, parce qu'elles ne sont pas fraîches ou qu'une réponse appropriée ne peut être sélectionnée ; voir la section 4.1), il peut utiliser le mécanisme de requête conditionnelle (voir la section 13 de [HTTP]) dans une requête transférée pour donner au serveur entrant suivant l'opportunité de sélectionner une réponse stockée valide à utiliser, en mettant à jour les métadonnées stockées dans le processus, ou de remplacer la ou les réponses stockées par une nouvelle réponse. Ce processus est connu sous le nom de "validation (Validating)" ou "revalidation (Revalidating)" de la réponse stockée.

4.3.1 Sending a Validation Request (Envoi d'une requête de validation)

Lors de la génération d'une requête conditionnelle pour validation, un cache commence soit par une requête qu'il tente de satisfaire, soit -- s'il initie indépendamment une requête -- synthétise une requête en utilisant une réponse stockée en copiant la méthode, l'URI cible et les champs d'en-tête de requête identifiés par le champ d'en-tête Vary (section 4.1).

Il met ensuite à jour cette requête avec un ou plusieurs champs d'en-tête de précondition. Ceux-ci contiennent des métadonnées de validateur obtenues à partir de réponses stockées pour le même URI. Généralement, cela n'inclura que les réponses stockées avec la même clé de cache, bien qu'un cache soit autorisé à valider les réponses qu'il ne peut pas sélectionner en utilisant les champs d'en-tête de requête présentés (voir la section 4.1).

Le destinataire compare ensuite les champs d'en-tête de précondition pour déterminer si une réponse stockée est équivalente à une représentation actuelle de la ressource.

Un tel validateur est l'horodatage donné dans un champ d'en-tête Last-Modified (voir la section 8.8.2 de [HTTP]), qui peut être utilisé dans un champ d'en-tête If-Modified-Since pour la validation de réponse, ou dans un champ d'en-tête If-Unmodified-Since ou If-Range pour la sélection de représentation (c'est-à-dire que le client fait référence spécifiquement à une représentation précédemment obtenue avec cet horodatage).

Un autre validateur est l'entity-tag donné dans un champ ETag (voir la section 8.8.3 de [HTTP]). Un ou plusieurs entity-tags (indiquant une ou plusieurs réponses stockées) peuvent être utilisés dans un champ d'en-tête If-None-Match pour la validation de réponse ou dans un champ d'en-tête If-Match ou If-Range pour la sélection de représentation (c'est-à-dire que le client fait référence spécifiquement à une ou plusieurs représentations précédemment obtenues avec les entity-tags répertoriés).

Lors de la génération d'une requête conditionnelle pour validation, un cache :

  • Doit (MUST) envoyer l'entity-tag pertinent (en utilisant If-Match, If-None-Match ou If-Range) si un entity-tag est fourni dans la réponse stockée en cours de validation.

  • Devrait (SHOULD) envoyer la valeur Last-Modified (en utilisant If-Modified-Since) si la requête n'est pas pour une sous-plage, qu'une seule réponse stockée est en cours de validation et que cette réponse contient une valeur Last-Modified.

  • Peut (MAY) envoyer la valeur Last-Modified (en utilisant If-Unmodified-Since ou If-Range) si la requête est pour une sous-plage, qu'une seule réponse stockée est en cours de validation et que cette réponse contient uniquement une valeur Last-Modified (au lieu d'un entity-tag).

Dans la plupart des cas, les deux validateurs seront générés dans les requêtes de validation de cache, même lorsque les entity-tags sont clairement supérieurs, pour permettre aux anciens intermédiaires qui ne comprennent pas les préconditions d'entity-tag de répondre de manière appropriée.

4.3.2 Handling a Received Validation Request (Traitement d'une requête de validation reçue)

Chaque client dans une chaîne de requêtes peut avoir son propre cache, il est donc courant qu'un cache d'un intermédiaire reçoive des requêtes conditionnelles d'autres caches (sortants). De même, certains agents utilisateurs effectuent des requêtes conditionnelles pour limiter le transfert de données aux représentations récemment modifiées ou pour compléter les récupérations partielles.

Si un cache reçoit une requête qui peut être satisfaite en réutilisant une réponse 200 (OK) ou 206 (Partial Content) stockée (conformément à la section 4), le cache devrait (SHOULD) évaluer toutes les préconditions de champ d'en-tête conditionnel applicables reçues dans cette requête par rapport aux validateurs correspondants contenus dans la réponse stockée.

Un cache ne doit pas (MUST NOT) évaluer les champs d'en-tête conditionnels qui ne s'appliquent qu'à un serveur d'origine, apparaissent dans une requête dont la sémantique ne peut pas être satisfaite avec une réponse mise en cache, ou apparaissent dans une requête pour une ressource cible pour laquelle il n'a pas de réponse stockée ; ces préconditions pourraient être destinées à un autre serveur (entrant).

L'évaluation correcte d'une requête conditionnelle par un cache dépend des champs d'en-tête de précondition reçus et de leur précédence. En résumé, les champs d'en-tête conditionnels If-Match et If-Unmodified-Since ne sont pas applicables à un cache, et If-None-Match a préséance sur If-Modified-Since. Voir la section 13.2.2 de [HTTP] pour une spécification complète de la précédence des préconditions.

Une requête contenant un champ d'en-tête If-None-Match (voir la section 13.1.2 de [HTTP]) indique que le client souhaite valider une ou plusieurs de ses propres réponses stockées par rapport à la réponse stockée sélectionnée par le cache (selon la section 4).

Si un champ d'en-tête If-None-Match n'est pas présent, une requête contenant un champ d'en-tête If-Modified-Since (voir la section 13.1.3 de [HTTP]) indique que le client souhaite valider une ou plusieurs de ses propres réponses stockées par date de modification.

Si une requête contient un champ d'en-tête If-Modified-Since et qu'un champ d'en-tête Last-Modified n'est pas présent dans une réponse stockée, le cache devrait (SHOULD) utiliser la valeur du champ Date de la réponse stockée (ou le moment où la réponse stockée a été reçue, si aucun champ Date n'est présent) pour évaluer la condition.

Un cache qui implémente des réponses partielles aux requêtes de plage (comme défini dans la section 14.2 de [HTTP]) devra également évaluer un champ d'en-tête If-Range reçu (voir la section 13.1.5 de [HTTP]) par rapport à la réponse sélectionnée par le cache.

Lorsqu'un cache décide de transférer une requête pour revalider sa propre réponse stockée pour une requête contenant une liste If-None-Match d'entity-tags, le cache peut (MAY) combiner la liste reçue avec une liste d'entity-tags de son propre ensemble de réponses stockées (fraîches ou périmées) et envoyer l'union des deux listes comme valeur de champ d'en-tête If-None-Match de remplacement dans la requête transférée. Si une réponse stockée ne contient qu'un contenu partiel, le cache ne doit pas (MUST NOT) inclure son entity-tag dans l'union à moins que la requête ne soit pour une plage qui serait entièrement satisfaite par cette réponse stockée partielle. Si la réponse à la requête transférée est 304 (Not Modified) et a une valeur de champ ETag avec un entity-tag qui n'est pas dans la liste du client, le cache doit (MUST) générer une réponse 200 (OK) pour le client en réutilisant sa réponse stockée correspondante, telle que mise à jour par les métadonnées de réponse 304 (section 4.3.4).

4.3.3 Handling a Validation Response (Traitement d'une réponse de validation)

Le traitement par le cache d'une réponse à une requête conditionnelle dépend de son code d'état :

  • Un code d'état de réponse 304 (Not Modified) indique que la réponse stockée peut être mise à jour et réutilisée ; voir la section 4.3.4.

  • Une réponse complète (c'est-à-dire avec du contenu) indique qu'aucune des réponses stockées désignées dans la requête conditionnelle n'est appropriée. Au lieu de cela, le cache doit (MUST) utiliser la réponse complète pour satisfaire la requête. Le cache peut (MAY) stocker une telle réponse complète, sous réserve de ses contraintes (voir la section 3).

  • Cependant, si un cache reçoit une réponse 5xx (Server Error) lors de la tentative de validation d'une réponse, il peut soit transférer cette réponse au client demandeur, soit agir comme si le serveur n'avait pas répondu. Dans ce dernier cas, le cache peut (MAY) envoyer une réponse précédemment stockée, sous réserve de ses contraintes pour ce faire (voir la section 4.2.4), ou réessayer la requête de validation.

4.3.4 Freshening Stored Responses upon Validation (Rafraîchissement des réponses stockées lors de la validation)

Lorsqu'un cache reçoit une réponse 304 (Not Modified), il doit identifier la ou les réponses stockées appropriées pour la mise à jour avec les nouvelles informations, puis le faire.

L'ensemble initial de réponses stockées à mettre à jour est celui qui aurait pu être choisi pour cette requête -- c'est-à-dire celles qui répondent aux exigences de la section 4, à l'exception de la dernière exigence selon laquelle elle doit être fraîche, autorisée à être servie périmée ou juste validée.

L'ensemble initial de réponses stockées est ensuite filtré davantage par la première des correspondances suivantes :

  • Si la nouvelle réponse contient un ou plusieurs "validateurs forts (Strong Validators)" (voir la section 8.8.1 de [HTTP]), alors chacun de ces validateurs forts identifie une représentation sélectionnée pour mise à jour. Toutes les réponses stockées dans l'ensemble initial qui ont l'un des mêmes validateurs forts sont identifiées pour mise à jour. Si aucune dans l'ensemble initial ne contient au moins l'un des mêmes validateurs forts, le cache ne doit pas (MUST NOT) utiliser la nouvelle réponse pour mettre à jour une réponse stockée.

  • Si la nouvelle réponse ne contient pas de validateurs forts mais contient un ou plusieurs "validateurs faibles (Weak Validators)", et que ces validateurs correspondent à l'un de l'ensemble initial de réponses stockées, alors la plus récente de ces réponses stockées correspondantes est identifiée pour mise à jour.

  • Si la nouvelle réponse ne contient aucune forme de validateur (comme dans le cas où un client génère une requête If-Modified-Since à partir d'une source autre que le champ d'en-tête de réponse Last-Modified), et qu'il n'y a qu'une seule réponse stockée dans l'ensemble initial, et que cette réponse stockée manque également de validateur, alors cette réponse stockée est identifiée pour mise à jour.

Pour chaque réponse stockée identifiée, le cache doit (MUST) mettre à jour ses champs d'en-tête avec les champs d'en-tête fournis dans la réponse 304 (Not Modified), conformément à la section 3.2.

4.3.5 Freshening Responses with HEAD (Rafraîchissement des réponses avec HEAD)

Une réponse à la méthode HEAD est identique à ce que serait une requête équivalente faite avec GET, sauf qu'aucun contenu n'est envoyé. Cette propriété d'une réponse HEAD peut être utilisée pour invalider ou mettre à jour une réponse GET mise en cache si le mécanisme de requête GET conditionnelle plus efficace n'est pas disponible (en raison de l'absence de validateurs dans la réponse stockée) ou lorsque la transmission de contenu n'est pas souhaitée même s'il a été modifié.

Lorsqu'un cache effectue une requête HEAD entrante pour un URI cible et reçoit une réponse 200 (OK), le cache devrait (SHOULD) mettre à jour ou invalider chacune de ses réponses GET stockées qui auraient pu être choisies pour cette requête (voir la section 4.1).

Pour chaque réponse stockée qui aurait pu être sélectionnée, si la réponse stockée et la réponse HEAD ont des valeurs correspondantes pour tous les champs de validateur reçus (ETag et Last-Modified) et, si la réponse HEAD a un champ d'en-tête Content-Length, sa valeur correspond à celle de la réponse stockée, le cache devrait (SHOULD) mettre à jour la réponse stockée comme décrit ci-dessous ; sinon, le cache devrait (SHOULD) considérer la réponse stockée comme périmée.

Si le cache met à jour une réponse stockée avec des métadonnées d'une réponse HEAD, le cache doit (MUST) mettre à jour la réponse stockée avec les champs d'en-tête fournis dans la réponse HEAD (voir la section 3.2).

4.4 Invalidating Stored Responses (Invalidation des réponses stockées)

Étant donné que les méthodes de requête non sûres (voir la section 9.2.1 de [HTTP]) telles que PUT, POST ou DELETE ont le potentiel de changer l'état sur le serveur d'origine, les caches intervenants doivent invalider les réponses stockées pour maintenir leur contenu à jour.

Lorsqu'un cache reçoit une réponse avec un code d'état non-erreur à une méthode de requête non sûre (y compris les méthodes dont la sécurité est inconnue), le cache doit (MUST) invalider l'URI cible (voir la section 7.1 de [HTTP]).

Lorsqu'un cache reçoit une réponse avec un code d'état non-erreur à une méthode de requête non sûre (y compris les méthodes dont la sécurité est inconnue), le cache peut (MAY) invalider d'autres URI. En particulier, les URI dans les champs d'en-tête de réponse Location et Content-Location (s'ils sont présents) sont des candidats à l'invalidation ; d'autres URI pourraient être découverts par des mécanismes non spécifiés dans ce document. Cependant, un cache ne doit pas (MUST NOT) déclencher d'invalidation dans ces conditions si l'origine (voir la section 4.3.1 de [HTTP]) de l'URI à invalider diffère de celle de l'URI cible (voir la section 7.1 de [HTTP]). Cela aide à prévenir les attaques par déni de service.

"Invalider (Invalidate)" signifie que le cache supprimera soit toutes les réponses stockées dont l'URI cible correspond à l'URI donné, soit les marquera comme "invalides (Invalid)" et nécessitant une validation obligatoire avant de pouvoir être envoyées en réponse à une requête ultérieure.

Une "réponse non-erreur (Non-Error Response)" est une réponse avec un code d'état 2xx (Successful) ou 3xx (Redirection).

Notez que cela ne garantit pas l'invalidation de toutes les réponses appropriées à l'échelle mondiale ; les requêtes de changement d'état n'invalideront que les réponses dans les caches qu'elles traversent.