Перейти к содержанию

dynamic-etag: модуль NGINX для добавления ETag к динамическому контенту

Установка в Debian/Ubuntu

Эти документы относятся к пакету APT nginx-module-dynamic-etag, предоставляемому репозиторием GetPageSpeed Extras.

  1. Настройте репозиторий APT, как описано в настройке репозитория APT.
  2. Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-dynamic-etag
Показать дистрибутивы и архитектуры
| Дистрибутив | Версия            | Компонент  | Архитектуры     |
|-------------|-------------------|------------|------------------|
| debian      | bookworm          | main       | amd64, arm64     |
| debian      | bookworm-mainline | main       | amd64, arm64     |
| debian      | trixie            | main       | amd64, arm64     |
| debian      | trixie-mainline   | main       | amd64, arm64     |
| ubuntu      | focal             | main       | amd64, arm64     |
| ubuntu      | focal-mainline    | main       | amd64, arm64     |
| ubuntu      | jammy             | main       | amd64, arm64     |
| ubuntu      | jammy-mainline    | main       | amd64, arm64     |
| ubuntu      | noble             | main       | amd64, arm64     |
| ubuntu      | noble-mainline    | main       | amd64, arm64     |

Coverity Scan Buy Me a Coffee

Этот модуль NGINX наделяет ваш динамический контент автоматическим заголовком ETag. Он позволяет клиентским браузерам отправлять условные запросы GET к динамическим страницам. И таким образом экономит трафик и обеспечивает лучшую производительность!

Сначала об осторожностях!

Этот модуль является настоящим хаком: он вызывает фильтр заголовков из фильтра тела и т.д.

Оригинальный автор забросил его, сказав:

Он никогда на самом деле не работал.

Я значительно переписал его, чтобы устранить существующие очевидные ошибки, но ключевая часть с буферами, которую, будучи старым, я, вероятно, никогда не пойму, осталась без изменений.

Чтобы быть надежным, модуль должен был прочитать весь ответ и сделать его хеш. Чтение всего ответа противоречит легковесному дизайну NGINX. Я не уверен, ждет ли часть с буфером весь ответ.

Сказав это, тесты, которые я добавил, демонстрируют, что вся эта штука работает!

Обратите внимание, что запросы HEAD не будут возвращать никаких ETag, потому что у нас нет данных, с которыми можно было бы играть, поскольку NGINX справедливо отбрасывает тело для этого метода запроса.

Считайте это особенностью или ошибкой :-) Если мы уберем это, тогда все запросы HEAD окажутся с одинаковым ETag (хеш на пустоту), что определенно хуже.

Таким образом, убедитесь, что вы проверяете заголовки вот так:

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

А не вот так:

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

Еще одно достойное упоминания — это то, что не имеет смысла применять динамический `ETag` на странице, которая меняется при 
каждой перезагрузке. Например, я обнаружил, что не использую динамический `ETag` с пользой из-за `<?= antispambot(get_option('admin_email')) ?>`,
в `header.php` моей темы WordPress, так как в этой функции:

> выбор случайный и меняется каждый раз, когда функция вызывается 

Чтобы быстро проверить, меняется ли ваша страница при перезагрузке, используйте:

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

Теперь, когда мы закончили с "теперь вы знаете" и прочим, вы можете продолжить с пробой этого :)

Синопсис

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

Директивы конфигурации

dynamic_etag

  • синтаксис: dynamic_etag on|off|$var
  • по умолчанию: off
  • контекст: http, server, location

Включает или отключает автоматическое применение ETag.

dynamic_etag_types

  • синтаксис: dynamic_etag_types <mime_type> [..]
  • по умолчанию: text/html
  • контекст: http, server, location

Включает автоматическое применение ETag для указанных MIME типов в дополнение к text/html. Специальное значение * соответствует любому MIME типу. Ответы с MIME типом text/html всегда включаются.

dynamic_etag_strength

  • синтаксис: dynamic_etag_strength strong|weak|$var
  • по умолчанию: strong
  • контекст: http, server, location

Управляет тем, являются ли создаваемые ETag сильными или слабыми. Слабые ETag полезны для динамического контента, где семантическое равенство должно учитываться, даже если байты отличаются (например, временные метки, рандомизированные атрибуты). При использовании $var назначьте значения strong или weak.

Примечание: Эти директивы недействительны в контексте if. Предпочитайте использовать $var с map, чтобы добиться условного поведения.

Пример с 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;
}

Советы

Вы можете использовать директиву map для условного включения динамического ETag на основе URL, например:

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

README оригинального автора

Попытка обработки ETag / If-None-Match на проксируемом контенте.

Я планирую использовать это для обслуживания сервера Varnish, используя много ESI.

Это достаточно работает, но... имейте в виду, что это моя первая попытка разработать плагин для nginx, и работа с заголовками после чтения тела не была точно в инструкции.

Любой комментарий и/или улучшение и/или форк приветствуются.

Спасибо http://github.com/kkung/nginx-static-etags/ за... вдохновение.