13. Caching in HTTP (Mise en Cache dans HTTP)
HTTP est généralement utilisé pour des systèmes d'information distribués, où les performances peuvent être améliorées par l'utilisation de caches de réponses. Le protocole HTTP/1.1 inclut de nombreux éléments conçus pour faire fonctionner la mise en cache aussi bien que possible. Les objectifs de la mise en cache dans HTTP/1.1 sont d'éliminer le besoin d'envoyer des requêtes dans de nombreux cas, et d'éliminer le besoin d'envoyer des réponses complètes dans de nombreux autres cas. Le premier réduit le nombre d'aller-retours réseau requis pour de nombreuses opérations; nous utilisons un mécanisme "d'expiration" (expiration) à cette fin (voir section 13.2). Le second réduit les exigences de bande passante réseau; nous utilisons un mécanisme de "validation" (validation) à cette fin (voir section 13.3).
Le protocole HTTP/1.1 fournit les éléments importants suivants :
- Fonctionnalités de protocole fournissant une transparence sémantique complète lorsque toutes les parties en ont besoin
- Fonctionnalités de protocole permettant au serveur d'origine ou à l'agent utilisateur de demander et contrôler explicitement des opérations non transparentes
- Fonctionnalités de protocole permettant au cache d'attacher des avertissements aux réponses qui ne maintiennent pas l'approximation de la transparence sémantique demandée
13.1.1 Cache Correctness (Exactitude du Cache)
Un cache correct doit (MUST) répondre à une requête en utilisant la réponse la plus à jour détenue par le cache qui est applicable à la requête et satisfait l'une des conditions suivantes :
-
Elle a été vérifiée pour son équivalence avec ce que le serveur d'origine retournerait en revalidant la réponse avec le serveur d'origine (section 13.3)
-
Elle est "suffisamment fraîche" (fresh enough) (voir section 13.2). Par défaut, cela signifie qu'elle satisfait les exigences de fraîcheur les moins restrictives du client, du serveur d'origine et du cache (voir section 14.9)
-
C'est un message de réponse approprié 304 (Not Modified), 305 (Proxy Redirect), ou d'erreur (4xx ou 5xx)
Si le cache ne peut pas communiquer avec le serveur d'origine, un cache correct devrait (SHOULD) répondre comme décrit ci-dessus si la réponse peut être correctement servie depuis le cache; sinon, il doit (MUST) retourner une erreur ou un avertissement indiquant l'échec de communication.
13.1.2 Warnings (Avertissements)
Chaque fois qu'un cache renvoie une réponse qui n'est ni de première main ni "suffisamment fraîche", il doit (MUST) attacher un avertissement à cet effet en utilisant l'en-tête général Warning. Les avertissements se voient attribuer des codes d'avertissement à trois chiffres :
- 1xx - Avertissement décrivant la fraîcheur ou l'état de revalidation de la réponse, et doit donc être supprimé après une revalidation réussie
- 2xx - Avertissement décrivant un aspect du corps d'entité ou des en-têtes d'entité qui ne sera pas corrigé par la revalidation, et ne doit donc pas être supprimé après une revalidation réussie
13.1.3 Cache-control Mechanisms (Mécanismes de Contrôle du Cache)
Les mécanismes de mise en cache de base dans HTTP/1.1 (les temps d'expiration spécifiés par le serveur et les validateurs) sont des directives implicites au cache. L'en-tête Cache-Control permet au client ou au serveur de transmettre diverses directives dans une requête ou une réponse. Ces directives écrasent généralement l'algorithme de mise en cache par défaut.
13.1.4 Explicit User Agent Warnings (Avertissements Explicites de l'Agent Utilisateur)
De nombreux agents utilisateurs ont des mécanismes de liste historique, tels qu'un bouton "Retour" et une liste d'historique, qui peuvent être utilisés pour réafficher des entités récemment récupérées par l'utilisateur. Les mécanismes d'historique et les caches sont différents.
13.1.5 Exceptions to the Rules and Warnings (Exceptions aux Règles et Avertissements)
Dans certaines situations, les opérateurs choisissent de configurer les caches pour renvoyer des réponses périmées même lorsqu'elles ne sont pas conformes aux règles HTTP/1.1. Ces situations incluent, mais ne sont pas limitées à :
- Retourner des données périmées lorsque le serveur d'origine est inaccessible
- Lorsque les connexions réseau sont lentes ou non fiables
- Fournir des temps de réponse plus rapides pendant certaines périodes
13.1.6 Client-controlled Behavior (Comportement Contrôlé par le Client)
Les agents utilisateurs ont généralement des mécanismes d'historique, tels qu'un bouton de retour, qui peuvent être utilisés pour réafficher des représentations récupérées précédemment.
13.2 Expiration Model (Modèle d'Expiration)
Les caches HTTP stockent généralement les entrées de cache jusqu'au moment où elles peuvent les utiliser sans interroger le serveur d'origine. Nous utilisons le terme "sémantiquement transparent" pour décrire un cache lorsque son utilisation n'est visible ni par le client demandeur ni par le serveur d'origine.
13.2.1 Server-Specified Expiration (Expiration Spécifiée par le Serveur)
Le protocole de cache HTTP utilise des temps d'expiration explicites pour indiquer quand une réponse devient périmée. Le mécanisme d'expiration ne s'applique qu'aux réponses définies comme suit :
- Réponses aux réponses 200, 203, 206, 300, 301 ou 410
- Réponses pour lesquelles le champ d'en-tête Cache-Control autorise explicitement la mise en cache
13.2.2 Heuristic Expiration (Expiration Heuristique)
Étant donné que les serveurs d'origine ne fournissent pas toujours un temps d'expiration explicite, les caches HTTP attribuent généralement des temps d'expiration heuristiques, en utilisant des algorithmes qui utilisent d'autres valeurs d'en-tête de l'entrée de cache (telles que le temps Last-Modified).
13.2.3 Age Calculations (Calculs d'Âge)
Pour savoir si une réponse est fraîche, le cache doit connaître son âge (age). La valeur de Age est une estimation du temps écoulé depuis que la réponse a été générée ou validée avec succès.
Formule de calcul de l'âge :
age_value = now - date_value
apparent_age = max(0, response_time - date_value)
corrected_received_age = max(apparent_age, age_value)
response_delay = response_time - request_time
corrected_initial_age = corrected_received_age + response_delay
resident_time = now - response_time
current_age = corrected_initial_age + resident_time
13.2.4 Expiration Calculations (Calculs d'Expiration)
Pour déterminer si une réponse est fraîche, nous comparons son âge actuel à sa durée de vie de fraîcheur. Une réponse est fraîche lorsque son âge n'a pas dépassé sa durée de vie de fraîcheur.
Calcul de la durée de vie de fraîcheur :
freshness_lifetime = max_age_value
ou
freshness_lifetime = expires_value - date_value
ou
freshness_lifetime = (now - last_modified_value) * 0.1
13.2.5 Disambiguating Expiration Values (Désambiguïsation des Valeurs d'Expiration)
Étant donné que la comparaison entre les temps d'expiration et l'heure actuelle est sensible au décalage d'horloge, les implémentations devraient utiliser le temps d'expiration le plus conservateur.
13.2.6 Disambiguating Multiple Responses (Désambiguïsation de Multiples Réponses)
Étant donné que les clients peuvent accéder aux ressources via plusieurs chemins, les caches peuvent recevoir plusieurs réponses pour la même ressource. Les caches devraient utiliser la réponse la plus récente.
13.3 Validation Model (Modèle de Validation)
Lorsqu'un cache a une entrée de cache périmée qu'il souhaite utiliser, il doit d'abord vérifier auprès du serveur d'origine (ou via un cache ayant une entrée fraîche) si son entrée de cache est toujours utilisable. Nous appelons cela "valider" l'entrée de cache.
13.3.1 Last-Modified Dates (Dates de Dernière Modification)
La valeur du champ d'en-tête d'entité Last-Modified est souvent utilisée comme validateur de cache. Généralement, la valeur Last-Modified de l'entrée de cache est envoyée avec un en-tête de requête If-Modified-Since.
13.3.2 Entity Tag Cache Validators (Validateurs de Cache par Étiquette d'Entité)
La valeur du champ d'en-tête de réponse ETag (étiquette d'entité) fournit un validateur de cache "opaque". Cela peut permettre une validation plus fiable, en particulier lorsque :
- Les dates de modification ne peuvent pas être commodément stockées
- La résolution d'une seconde de la valeur de date HTTP de la date de modification du document n'est pas suffisante
- Les dates de modification ne sont pas cohérentes
13.3.3 Weak and Strong Validators (Validateurs Faibles et Forts)
Étant donné que les objectifs du serveur d'origine et du cache peuvent différer, les clients peuvent parfois avoir besoin seulement d'une réponse suffisamment bonne, plutôt que d'une copie absolument la plus récente.
- Validateur fort - change chaque fois que l'entité change, quel que soit l'importance du changement
- Validateur faible - peut ne pas changer pour chaque changement d'entité (préfixe "W/")
13.3.4 Rules for When to Use Entity Tags and Last-Modified Dates (Règles pour Quand Utiliser les Étiquettes d'Entité et les Dates de Dernière Modification)
Les serveurs d'origine HTTP/1.1 devraient (SHOULD) envoyer des validateurs d'étiquette d'entité autant que possible, plutôt que ou en plus des valeurs Last-Modified.
13.3.5 Non-validating Conditionals (Conditionnels Non Validants)
Les requêtes conditionnelles peuvent également être utilisées à d'autres fins, telles que l'optimisation des requêtes ou la prévention des pertes de mises à jour.
13.4 Response Cacheability (Cachabilité de la Réponse)
Sauf indication contraire, les réponses récupérées à l'aide de GET sont cachables. Les règles suivantes définissent quand une réponse est cachable :
- La méthode de requête elle-même est cachable (GET et HEAD)
- Le code d'état de la réponse est compréhensible et cachable (200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501)
- L'en-tête Cache-Control n'indique pas d'interdiction de mise en cache
- Si on utilise un cache partagé, l'en-tête Authorization n'apparaît pas, sauf si Cache-Control l'autorise explicitement
13.5 Constructing Responses From Caches (Construction de Réponses à partir des Caches)
13.5.1 End-to-end and Hop-by-hop Headers (En-têtes de Bout en Bout et Saut par Saut)
Les champs d'en-tête HTTP sont classés en en-têtes de bout en bout (end-to-end) et en-têtes saut par saut (hop-by-hop) :
- En-têtes de bout en bout - doivent être transmis au destinataire final
- En-têtes saut par saut - n'ont de signification que pour une seule connexion au niveau du transport
13.5.2 Non-modifiable Headers (En-têtes Non Modifiables)
Certaines fonctionnalités peuvent nécessiter que le cache modifie les en-têtes de certaines entrées de cache. Seuls les en-têtes de bout en bout peuvent être modifiés.
13.5.3 Combining Headers (Combinaison d'En-têtes)
Lorsqu'un cache valide une réponse à une requête et que la réponse contient certains champs d'en-tête mais pas d'autres, le cache doit combiner les nouveaux champs avec les champs de l'ancienne entrée.
13.5.4 Combining Byte Ranges (Combinaison de Plages d'Octets)
Une réponse provenant du cache peut être une réponse de contenu partiel. Dans certains cas, le cache peut combiner un ensemble de plages d'octets stockées et une nouvelle plage d'octets pour satisfaire la requête.
13.6 Caching Negotiated Responses (Mise en Cache des Réponses Négociées)
L'utilisation de la négociation de contenu pilotée par le serveur (section 12.1) peut créer différentes réponses en fonction des valeurs de champs d'en-tête particuliers de la requête. Le champ d'en-tête Vary est utilisé pour indiquer quels champs d'en-tête de requête sont utilisés dans la sélection.
13.7 Shared and Non-Shared Caches (Caches Partagés et Non Partagés)
Étant donné que le but et les limites de certains champs d'en-tête diffèrent pour différents types de caches, nous distinguons :
- Caches non partagés - cache accessible uniquement par un seul utilisateur (par exemple, cache d'agent utilisateur)
- Caches partagés - cache accessible par plusieurs utilisateurs (par exemple, cache de proxy)
13.8 Errors or Incomplete Response Cache Behavior (Comportement de Cache pour Erreurs ou Réponses Incomplètes)
Lorsqu'un cache reçoit une réponse incomplète (par exemple, moins d'octets Content-Length que spécifié), il peut (MAY) stocker la réponse incomplète. Cependant, le cache doit (MUST) la traiter comme une réponse partielle.
13.9 Side Effects of GET and HEAD (Effets Secondaires de GET et HEAD)
À moins que le serveur d'origine n'interdise explicitement la mise en cache de la réponse, l'application des méthodes GET et HEAD ne devrait (SHOULD) pas avoir d'effets secondaires.
13.10 Invalidation After Updates or Deletions (Invalidation Après Mises à Jour ou Suppressions)
L'exécution réussie d'une méthode qui changerait l'état (POST, PUT, DELETE) doit invalider toutes les entrées de cache pour la ressource identifiée par ce Request-URI.
13.11 Write-Through Mandatory (Écriture Traversante Obligatoire)
Toutes les méthodes qui entraînent une modification de ressource sur le serveur d'origine doivent (MUST) écrire jusqu'au serveur d'origine. La spécification actuelle ne définit aucun moyen de mettre en cache de telles réponses ailleurs.
13.12 Cache Replacement (Remplacement de Cache)
Si un cache reçoit une réponse qui amènerait à remplacer une entrée par une entrée plus récente, et que l'ancienne entrée contient des directives Cache-Control, le cache devrait (SHOULD) respecter ces directives.
13.13 History Lists (Listes d'Historique)
Les agents utilisateurs ont généralement des mécanismes d'historique, tels qu'un bouton "Retour" et une liste d'historique, qui peuvent être utilisés pour réafficher des représentations récupérées précédemment dans la session de l'utilisateur.
Exigences du mécanisme d'historique :
- Le mécanisme d'historique devrait (SHOULD) afficher les ressources récupérées précédemment selon les préférences de l'utilisateur
- Le mécanisme d'historique ne devrait pas (SHOULD NOT) tenter de valider les ressources
- Le mécanisme d'historique devrait (SHOULD) afficher les représentations récupérées précédemment, même si elles sont maintenant expirées
Note importante : Ce chapitre décrit en détail les mécanismes de mise en cache HTTP/1.1, y compris le modèle d'expiration, le modèle de validation, le contrôle du cache et d'autres concepts essentiels. La mise en cache est un mécanisme clé pour améliorer les performances HTTP, et la compréhension de ces concepts est essentielle pour construire des applications Web hautement performantes.