Pular para conteúdo

dynamic-etag: módulo NGINX para adicionar ETag ao conteúdo dinâmico

Instalação

Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:

  • RedHat Enterprise Linux 7, 8, 9 e 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 e 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

Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:

load_module modules/ngx_http_dynamic_etag_module.so;

Este documento descreve o nginx-module-dynamic-etag v0.2.3 lançado em 18 de setembro de 2025.


Coverity Scan Buy Me a Coffee

Este módulo NGINX capacita seu conteúdo dinâmico com o cabeçalho automático ETag. Ele permite que os navegadores dos clientes emitam solicitações GET condicionais para páginas dinâmicas. E assim economiza largura de banda e garante melhor desempenho!

Avisos primeiro!

Este módulo é uma verdadeira gambiarra: ele chama um filtro de cabeçalho a partir de um filtro de corpo, etc.

O autor original o abandonou, tendo que dizer:

Nunca funcionou realmente.

Eu reescrevi em grande parte para lidar com falhas óbvias existentes, mas a parte chave com buffers, que, sendo eu um pouco mais velho, provavelmente nunca entenderei, permanece intocada.

Para ser confiável, o módulo precisa ler toda a resposta e fazer um hash dela. Ler toda a resposta vai contra o design leve do NGINX. Não tenho certeza se a parte do buffer espera pela resposta completa.

Dito isso, os testes que adicionei mostram que toda essa coisa funciona!

Observe que as solicitações HEAD não terão nenhum ETag retornado, pois não temos dados para trabalhar, já que o NGINX descarta corretamente o corpo para este método de solicitação.

Considere isso como uma funcionalidade ou um bug :-) Se removermos isso, todas as solicitações HEAD acabarão tendo o mesmo ETag (hash sobre a ausência), o que é definitivamente pior.

Portanto, certifique-se de verificar os cabeçalhos assim:

curl -IL -X GET https://www.example.com/

E não assim:

```bash curl -IL https://www.example.com/

Outra coisa digna de nota é que não faz muito sentido aplicar `ETag` dinâmico em uma página que muda a cada recarregamento. Por exemplo, descobri que não estava usando o `ETag` dinâmico com benefícios, por causa de `<?= antispambot(get_option('admin_email')) ?>`,
no `header.php` do meu tema WordPress, já que nesta função:

> a seleção é aleatória e muda toda vez que a função é chamada 

Para verificar rapidamente se sua página está mudando ao recarregar, use:

```bash
diff <(curl http://www.example.com") <(curl http://www.example.com")

Agora que terminamos com o "agora você sabe" yada-yada, você pode prosseguir com a experimentação :)

Sinopse

http {
    server {
        location ~ \.php$ {
            dynamic_etag on;
            fastcgi_pass ...;
        }
    }
}

Diretrizes de configuração

dynamic_etag

  • sintaxe: dynamic_etag on|off|$var
  • padrão: off
  • contexto: http, server, location

Habilita ou desabilita a aplicação automática de ETag.

dynamic_etag_types

  • sintaxe: dynamic_etag_types <mime_type> [..]
  • padrão: text/html
  • contexto: http, server, location

Habilita a aplicação automática de ETag para os tipos MIME especificados além de text/html. O valor especial * corresponde a qualquer tipo MIME. Respostas com o tipo MIME text/html estão sempre incluídas.

dynamic_etag_strength

  • sintaxe: dynamic_etag_strength strong|weak|$var
  • padrão: strong
  • contexto: http, server, location

Controla se os ETags gerados são fortes ou fracos. ETags fracos são úteis para conteúdo dinâmico onde a igualdade semântica deve ser considerada mesmo que os bytes diferem (por exemplo, timestamps, atributos aleatórios). Ao usar $var, mapeie para os valores strong ou weak.

Nota: Essas diretrizes não são válidas no contexto if. Prefira usar $var com map para alcançar um comportamento condicional.

Exemplo com 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;
}

Dicas

Você pode usar a diretiva map para habilitar condicionalmente o ETag dinâmico com base nas URLs, por exemplo:

map $request_uri $dyn_etag {
    default "off";
    /foo "on";
    /bar "on";
}
server { 
   ...
   location / {
       dynamic_etag $dyn_etag;
       fastcgi_pass ...
   }
}       

README do autor original

Tentativa de lidar com ETag / If-None-Match em conteúdo proxy.

Planejo usar isso para frentear um servidor Varnish usando muitos ESI.

Funciona de certa forma, mas... esteja ciente, esta é minha primeira tentativa de desenvolver um plugin nginx, e lidar com cabeçalhos após ter lido o corpo não estava exatamente no manual.

Qualquer comentário e/ou melhoria e/ou fork é bem-vindo.

Agradecimentos a http://github.com/kkung/nginx-static-etags/ pela... inspiração.

GitHub

Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-dynamic-etag.