HTTPQUERY
Français

ETag

Utilisation

L’en-tête ETag attribue une étiquette unique à chaque version d’une ressource. Lorsque la ressource change, la valeur de l’ETag change également. Les clients conservent l’ETag d’une réponse mise en cache et le renvoient dans l’en-tête de requête If-None-Match lors des requêtes suivantes. Si l’ETag correspond toujours, le serveur renvoie 304 Not Modified sans corps de message et le client réutilise sa copie mise en cache. Si l’ETag ne correspond plus, le serveur envoie la réponse complète mise à jour.

La validation fondée sur l’ETag est plus fiable que la validation par date avec Last-Modified. Les entity tags forts sont des chaînes opaques liées au contenu exact d’une représentation, tandis que les horodatages de modification ont une granularité d’une seconde et restent exposés aux dérives d’horloge. Lorsque ETag et Last-Modified sont tous deux présents, l’ETag est prioritaire lors de la revalidation, comme l’exige la norme HTTP.

Les ETag permettent également le contrôle de concurrence sur les méthodes non sûres. Une requête PUT accompagnée de If-Match garantit que la mise à jour ne s’applique qu’à la version attendue. Si la ressource a changé depuis la dernière récupération de l’ETag par le client, le serveur renvoie 412 Precondition Failed, ce qui évite le problème de la mise à jour perdue.

La valeur de l’ETag est générée par le serveur. Les stratégies courantes incluent le hachage du contenu, les compteurs de version et la combinaison de la date de modification du fichier avec sa taille. La valeur est encadrée par des guillemets doubles et peut être préfixée par W/ pour signaler une comparaison faible.

Remarque

Google recommande d’utiliser ETag plutôt que Last-Modified pour indiquer la préférence de mise en cache, car ETag évite les problèmes de formatage de date. Lorsque ETag et Last-Modified sont tous deux présents, les robots d’exploration de Google utilisent la valeur de l’ETag, comme l’exige la norme HTTP. Il reste recommandé de définir les deux en-têtes, car d’autres applications telles que les CMS s’appuient également sur eux. Chaque robot d’exploration et outil de récupération de Google exploite la mise en cache selon les besoins du produit auquel il est associé. Googlebot prend en charge la mise en cache lorsqu’il réexplore des URL pour Google Search.

ETag fort

Un ETag fort garantit une identité octet par octet entre deux représentations d’une ressource. Deux ressources partageant le même ETag fort sont interchangeables au niveau des octets. Les ETag forts conviennent aux requêtes de plage ainsi qu’à toutes les méthodes de comparaison.

ETag: "abc123"

ETag faible

Un ETag faible, préfixé par W/, indique une équivalence sémantique plutôt qu’une identité au niveau des octets. Deux ressources partageant le même ETag faible sont considérées comme équivalentes par leur signification, mais pas nécessairement identiques dans leur contenu. Les ETag faibles sont plus simples à générer, car ils tolèrent des différences mineures comme des changements d’espaces ou la mise à jour d’horodatages dans le corps. Les ETag faibles ne sont pas valides pour les requêtes de plage d’octets.

ETag: W/"v2.6"

Exemple

Un serveur renvoie un ETag avec la réponse. Le client conserve l’étiquette pour une revalidation ultérieure.

HTTP/1.1 200 OK
ETag: "33a64df5"
Content-Type: text/html
Cache-Control: max-age=3600

Le client revalide à l’aide de If-None-Match. Le serveur compare l’étiquette à la version actuelle de la ressource.

GET /page HTTP/1.1
If-None-Match: "33a64df5"

La ressource n’a pas changé. Le serveur renvoie 304 sans corps de message et le client réutilise son cache.

HTTP/1.1 304 Not Modified
ETag: "33a64df5"
Cache-Control: max-age=3600

Une requête PUT utilisant If-Match pour la concurrence optimiste. La mise à jour n’est effectuée que si la ressource correspond toujours à l’ETag détenu par le client.

PUT /api/document/42 HTTP/1.1
If-Match: "33a64df5"
Content-Type: application/json

Un ETag faible sur une ressource où de légères variations du corps (comme des horodatages intégrés) sont acceptables. Le préfixe W/ signale une sémantique de comparaison faible.

ETag: W/"2024-11-22-v3"

Dépannage

Les problèmes liés aux ETag se manifestent par des échecs de revalidation, des téléchargements complets inattendus ou des conflits de concurrence sur une infrastructure distribuée.

Discordance d’ETag entre serveurs répartis en charge. Différents serveurs placés derrière un répartiteur de charge génèrent des ETag différents pour la même ressource lorsque l’algorithme de génération intègre des numéros d’inode, des horodatages ou des données propres au serveur. Un client a mis en cache la réponse du serveur A, mais revalide auprès du serveur B, qui renvoie un ETag différent et force un téléchargement complet. Dans Apache, l’ETag par défaut inclut inode, size et mtime. Retirez la composante inode :

FileETag MTime Size

Dans nginx, les ETag dérivent de la date de dernière modification et de la longueur du contenu, ce qui produit des valeurs cohérentes entre serveurs partageant le même contenu de fichier. Assurez-vous que les horodatages de déploiement des fichiers concordent sur tous les nœuds.

IIS émet les ETag au format “filetime:changenumber”, par exemple “04c2528da58dc1:0”. La première moitié encode en hexadécimal le FILETIME Windows de dernière modification du fichier. Le suffixe ChangeNumber suit l’état de la configuration IIS. IIS 7 et les versions ultérieures émettent toujours :0 : la propriété de la metabase qui pilotait ce compteur a été retirée avec IIS 6, et aucun paramètre applicationHost.config ou web.config n’expose de valeur non nulle. Les nœuds placés derrière un répartiteur de charge émettent donc des ETag identiques pour un même fichier. IIS 6 et les versions antérieures incrémentent le ChangeNumber lors des modifications de la metabase et des redémarrages de service, si bien que les nœuds se désynchronisent et que la revalidation entre nœuds renvoie 200 au lieu de 304. Réinitialisez la valeur sur chaque nœud IIS 6 avec cscript adsutil.vbs set w3svc/etag_changenumber 0, ou supprimez le suffixe pour que l’ETag ne reflète que le FILETIME. Tout suffixe non nul observé en production indique un serveur d’origine IIS 6.

Un ETag faible provoque une réponse complète inattendue au lieu d’un 304. Les ETag faibles (W/”…”) signalent une équivalence sémantique mais ne prennent pas en charge les requêtes de plage d’octets. Une requête If-None-Match avec un ETag faible reste valable pour la revalidation du cache. Si le serveur renvoie une réponse 200 complète au lieu d’un 304, la logique de comparaison côté serveur est peut-être incorrecte. Vérifiez que le serveur compare les ETag faibles à l’aide de la fonction de comparaison faible, qui ignore le préfixe W/ lors de la correspondance.

If-None-Match n’est pas envoyé par le client. Le navigateur n’envoie If-None-Match que lorsqu’une réponse mise en cache contient un en-tête ETag. L’absence d’ETag dans la réponse initiale empêche toute revalidation ultérieure. Inspectez la réponse du serveur d’origine avec curl -I https://example.re/resource et confirmez la présence de l’en-tête ETag. Les serveurs de fichiers statiques comme nginx et Apache génèrent les ETag automatiquement. Les serveurs applicatifs et les frameworks d’API exigent souvent une génération explicite de l’ETag dans le code.

Un CDN supprime ou modifie les ETag. Certains CDN altèrent les valeurs d’ETag pendant leur traitement. Cloudflare convertit les ETag forts en ETag faibles lorsqu’il applique des transformations telles que la compression Brotli ou l’optimisation d’images. AWS CloudFront transmet les ETag du serveur d’origine sans modification. Vérifiez l’ETag au niveau de l’origine (curl -I https://origin.example.re) et comparez-le avec celui du nœud de bordure du CDN (curl -I https://cdn.example.re). Lorsque le CDN modifie les ETag, la revalidation à travers le CDN fonctionne toujours, car le CDN conserve la correspondance. En revanche, une revalidation directe auprès de l’origine avec un ETag modifié par le CDN échoue.

Apache et nginx génèrent les ETag différemment. Apache utilise par défaut inode-mtime-size, ce qui produit des ETag du type “1a2b3c-4d5e-6f7a8b9c”. Nginx utilise mtime-content-length en hexadécimal, ce qui produit des ETag du type “5f4dcc3b-d8”. Migrer d’un serveur à l’autre invalide tous les ETag mis en cache et déclenche un téléchargement complet pour chaque client. Prévoyez une période de préchauffage du cache après une migration de serveur. Pour les réponses d’API, générez les ETag à partir de hachages de contenu (MD5 ou SHA-256) afin d’obtenir des valeurs indépendantes du serveur.

Remarque

La génération d’ETag par défaut d’Apache inclut le numéro d’inode du fichier (FileETag INode MTime Size). Les numéros d’inode divulguent des informations sur le système de fichiers du serveur, ce qui rend possibles l’empreinte applicative et la corrélation entre serveurs. L’OWASP considère les ETag fondés sur l’inode comme un risque de divulgation d’informations. Retirez l’inode du calcul avec FileETag MTime Size dans la configuration Apache.

Remarque

Pour une assistance en SEO et en mise en cache, contactez les anciens consultants SEO de Google, Search Brothers.