dynamic-etag: módulo NGINX para agregar ETag a contenido dinámico
Instalación
Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:
- RedHat Enterprise Linux 7, 8, 9 y 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 y 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
Habilita el módulo agregando lo siguiente en la parte superior de /etc/nginx/nginx.conf:
load_module modules/ngx_http_dynamic_etag_module.so;
Este documento describe nginx-module-dynamic-etag v0.2.3 lanzado el 18 de septiembre de 2025.
Este módulo NGINX potencia tu contenido dinámico con el encabezado automático ETag.
Permite a los navegadores de los clientes emitir solicitudes GET condicionales a
páginas dinámicas. ¡Y así ahorra ancho de banda y asegura un mejor rendimiento!
¡Advertencias primero!
Este módulo es un verdadero hack: llama a un filtro de encabezado desde un filtro de cuerpo, etc.
El autor original lo abandonó, teniendo que decir:
Nunca funcionó realmente.
Lo reescribí en gran medida para abordar fallos evidentes existentes, pero la parte clave con los buffers, que, siendo yo viejo, probablemente nunca entenderé, permanece intacta.
Para ser confiable, el módulo tiene que leer toda la respuesta y tomar un hash de ella. Leer toda la respuesta va en contra del diseño ligero de NGINX. No estoy seguro de si la parte del buffer espera toda la respuesta.
Dicho esto, las pruebas que agregué muestran que todo esto funciona.
Ten en cuenta que las solicitudes HEAD no tendrán ningún ETag devuelto, porque no tenemos datos con los que jugar,
ya que NGINX correctamente descarta el cuerpo para este método de solicitud.
Considera esto como una característica o un error :-) Si eliminamos esto, entonces todas las solicitudes HEAD terminan teniendo el mismo ETag (hash en vacío),
lo cual es definitivamente peor.
Por lo tanto, asegúrate de verificar los encabezados de esta manera:
curl -IL -X GET https://www.example.com/
Y no de esta manera:
curl -IL https://www.example.com/
Otra cosa digna de mención es que tiene poco o ningún sentido aplicar ETag dinámico en una página que cambia en
cada recarga. Por ejemplo, descubrí que no estaba utilizando el ETag dinámico con beneficios, debido a <?= antispambot(get_option('admin_email')) ?>,
en el header.php de mi tema de WordPress, ya que en esta función:
la selección es aleatoria y cambia cada vez que se llama a la función
Para verificar rápidamente si tu página está cambiando en la recarga, usa:
diff <(curl http://www.example.com") <(curl http://www.example.com")
Ahora que hemos terminado con el "ahora ya sabes" yada-yada, puedes proceder a probar esto :)
Sinopsis
http {
server {
location ~ \.php$ {
dynamic_etag on;
fastcgi_pass ...;
}
}
}
Directivas de configuración
dynamic_etag
- sintaxis:
dynamic_etag on|off|$var - predeterminado:
off - contexto:
http,server,location
Habilita o deshabilita la aplicación automática de ETag.
dynamic_etag_types
- sintaxis:
dynamic_etag_types <mime_type> [..] - predeterminado:
text/html - contexto:
http,server,location
Habilita la aplicación automática de ETag para los tipos MIME especificados
además de text/html. El valor especial * coincide con cualquier tipo MIME.
Las respuestas con el tipo MIME text/html siempre están incluidas.
dynamic_etag_strength
- sintaxis:
dynamic_etag_strength strong|weak|$var - predeterminado:
strong - contexto:
http,server,location
Controla si los ETags generados son fuertes o débiles. Los ETags débiles son útiles para
contenido dinámico donde la igualdad semántica debe considerarse incluso si los
bytes difieren (por ejemplo, marcas de tiempo, atributos aleatorios). Al usar $var, mapea
a los valores strong o weak.
Nota: Estas directivas no son válidas en el contexto if. Prefiere usar $var
con map para lograr un comportamiento condicional.
Ejemplo con 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;
}
Consejos
Puedes usar la directiva map para habilitar condicionalmente ETag dinámico basado en URLs, por ejemplo:
map $request_uri $dyn_etag {
default "off";
/foo "on";
/bar "on";
}
server {
...
location / {
dynamic_etag $dyn_etag;
fastcgi_pass ...
}
}
README del autor original
Intento de manejar ETag / If-None-Match en contenido proxied.
Planeo usar esto para poner delante de un servidor Varnish que usa mucho ESI.
Funciona de alguna manera, pero... ten en cuenta que este es mi primer intento de desarrollar un complemento de nginx, y lidiar con encabezados después de haber leído el cuerpo no fue exactamente parte del cómo hacerlo.
Cualquier comentario y/o mejora y/o bifurcación es bienvenida.
Gracias a http://github.com/kkung/nginx-static-etags/ por... la inspiración.
GitHub
Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-dynamic-etag.