dynamic-etag: module NGINX pour ajouter ETag au contenu dynamique
Installation
Vous pouvez installer ce module dans toute distribution basée sur RHEL, y compris, mais sans s'y limiter :
- RedHat Enterprise Linux 7, 8, 9 et 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 et Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-dynamic-etag
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-dynamic-etag
Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :
load_module modules/ngx_http_dynamic_etag_module.so;
Ce document décrit nginx-module-dynamic-etag v0.2.3 publié le 18 septembre 2025.
Ce module NGINX donne à votre contenu dynamique un en-tête ETag automatique. Il permet aux navigateurs clients d'émettre des requêtes GET conditionnelles vers des pages dynamiques. Cela permet d'économiser de la bande passante et d'assurer de meilleures performances !
Attention d'abord !
Ce module est un véritable hack : il appelle un filtre d'en-tête depuis un filtre de corps, etc.
L'auteur original l'a abandonné, ayant déclaré :
Ça n'a jamais vraiment fonctionné.
Je l'ai largement réécrit pour corriger les défauts évidents existants, mais la partie clé avec les tampons, que moi-même étant vieux, je ne comprendrai probablement jamais, est intacte.
Pour être fiable, le module doit lire l'intégralité de la réponse et en prendre un hachage. Lire l'intégralité de la réponse va à l'encontre du design léger de NGINX. Je ne suis pas sûr que la partie tampon attende l'intégralité de la réponse.
Cela dit, les tests que j'ai ajoutés montrent que tout cela fonctionne !
Notez que les requêtes HEAD ne renverront aucun ETag, car nous n'avons pas de données à manipuler, puisque NGINX rejette à juste titre le corps pour cette méthode de requête.
Considérez cela comme une fonctionnalité ou un bug :-) Si nous supprimons cela, alors toutes les requêtes HEAD finissent par avoir le même ETag (hachage sur le vide), ce qui est définitivement pire.
Ainsi, assurez-vous de vérifier les en-têtes comme ceci :
curl -IL -X GET https://www.example.com/
Et pas comme ceci :
curl -IL https://www.example.com/
Une autre chose digne de mention est qu'il n'a que peu ou pas de sens d'appliquer un ETag dynamique sur une page qui change à chaque rechargement. Par exemple, j'ai constaté que je n'utilisais pas le ETag dynamique avec des avantages, à cause de <?= antispambot(get_option('admin_email')) ?>, dans le header.php de mon thème WordPress, puisque dans cette fonction :
la sélection est aléatoire et change chaque fois que la fonction est appelée
Pour vérifier rapidement si votre page change au rechargement, utilisez :
diff <(curl http://www.example.com") <(curl http://www.example.com")
Maintenant que nous avons terminé avec le "maintenant vous savez" yada-yada, vous pouvez procéder à l'essai de ces choses :)
Synopsis
http {
server {
location ~ \.php$ {
dynamic_etag on;
fastcgi_pass ...;
}
}
}
Directives de configuration
dynamic_etag
- syntax:
dynamic_etag on|off|$var - default:
off - context:
http,server,location
Active ou désactive l'application automatique de l'ETag.
dynamic_etag_types
- syntax:
dynamic_etag_types <mime_type> [..] - default:
text/html - context:
http,server,location
Active l'application automatique de l'ETag pour les types MIME spécifiés en plus de text/html. La valeur spéciale * correspond à tout type MIME. Les réponses avec le type MIME text/html sont toujours incluses.
dynamic_etag_strength
- syntax:
dynamic_etag_strength strong|weak|$var - default:
strong - context:
http,server,location
Contrôle si les ETags générés sont forts ou faibles. Les ETags faibles sont utiles pour le contenu dynamique où l'égalité sémantique doit être considérée même si les octets diffèrent (par exemple, les horodatages, les attributs randomisés). Lors de l'utilisation de $var, mappez aux valeurs strong ou weak.
Note : Ces directives ne sont pas valides dans le contexte if. Préférez utiliser $var avec map pour obtenir un comportement conditionnel.
Exemple avec map :
map $arg_w $etag_strength {
default strong;
1 weak;
}
location /example {
dynamic_etag on;
dynamic_etag_types text/html;
dynamic_etag_strength $etag_strength;
proxy_pass http://backend;
}
Conseils
Vous pouvez utiliser la directive map pour activer conditionnellement le ETag dynamique en fonction des URL, par exemple :
map $request_uri $dyn_etag {
default "off";
/foo "on";
/bar "on";
}
server {
...
location / {
dynamic_etag $dyn_etag;
fastcgi_pass ...
}
}
README de l'auteur original
Tentative de gestion de l'ETag / If-None-Match sur le contenu proxy.
Je prévois d'utiliser cela pour faire face à un serveur Varnish utilisant beaucoup d'ESI.
Cela fonctionne en quelque sorte, mais... soyez conscient que c'est ma première tentative de développement d'un plugin nginx, et gérer les en-têtes après avoir lu le corps n'était pas exactement dans le mode d'emploi.
Tout commentaire et/ou amélioration et/ou fork est le bienvenu.
Merci à http://github.com/kkung/nginx-static-etags/ pour... l'inspiration.
GitHub
Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-dynamic-etag.