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

headers-more: Динамический модуль заголовков NGINX

Установка

Вы можете установить этот модуль в любой дистрибутив на базе RHEL, включая, но не ограничиваясь:

  • RedHat Enterprise Linux 7, 8, 9 и 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-headers-more
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-headers-more

Активируйте модуль, добавив следующее в верхнюю часть файла /etc/nginx/nginx.conf:

load_module modules/ngx_http_headers_more_filter_module.so;

Этот документ описывает nginx-module-headers-more v0.33, выпущенный 28 июня 2022 года.


 # установить заголовок Server
 more_set_headers 'Server: my-server';

 # установить и очистить выходные заголовки
 location /bar {
     more_set_headers 'X-MyHeader: blah' 'X-MyHeader2: foo';
     more_set_headers -t 'text/plain text/css' 'Content-Type: text/foo';
     more_set_headers -s '400 404 500 503' -s 413 'Foo: Bar';
     more_clear_headers 'Content-Type';

     # ваша конфигурация proxy_pass/memcached_pass или любая другая здесь...
 }

 # установить выходные заголовки
 location /type {
     more_set_headers 'Content-Type: text/plain';
     # ...
 }

 # установить входные заголовки
 location /foo {
     set $my_host 'my dog';
     more_set_input_headers 'Host: $my_host';
     more_set_input_headers -t 'text/plain' 'X-Foo: bah';

     # теперь $host и $http_host имеют свои новые значения...
     # ...
 }

 # заменить входной заголовок X-Foo *только* если он уже существует
 more_set_input_headers -r 'X-Foo: howdy';

Описание

Этот модуль позволяет вам добавлять, устанавливать или очищать любые выходные или входные заголовки, которые вы укажете.

Это улучшенная версия стандартного headers модуля, так как она предоставляет больше утилит, таких как сброс или очистка "встроенных заголовков", таких как Content-Type, Content-Length и Server.

Он также позволяет вам указывать необязательные критерии кода состояния HTTP с помощью опции -s и необязательные критерии типа контента с помощью опции -t, изменяя выходные заголовки с помощью директив more_set_headers и more_clear_headers. Например,

 more_set_headers -s 404 -t 'text/html' 'X-Foo: Bar';

Вы также можете указать несколько MIME-типов для фильтрации в одной опции -t. Например,

more_set_headers -t 'text/html text/plain' 'X-Foo: Bar';

Никогда не используйте другие параметры, такие как charset=utf-8, в значениях опции -t; они не будут работать так, как вы ожидаете.

Входные заголовки также могут быть изменены. Например

 location /foo {
     more_set_input_headers 'Host: foo' 'User-Agent: faked';
     # теперь $host, $http_host, $user_agent и
     #   $http_user_agent все имеют свои новые значения.
 }

Опция -t также доступна в директивах more_set_input_headers и more_clear_input_headers (для фильтрации заголовков запроса), в то время как опция -s не допускается.

В отличие от стандартного headers модуля, директивы этого модуля по умолчанию будут применяться ко всем кодам состояния, включая 4xx и 5xx.

Директивы

more_set_headers

синтаксис: more_set_headers [-t <список content-type>]... [-s <список кодов состояния>]... <новый-заголовок>...

по умолчанию: нет

контекст: http, server, location, location if

фаза: output-header-filter

Заменяет (если есть) или добавляет (если нет) указанные выходные заголовки, когда код состояния ответа соответствует кодам, указанным в опции -s И тип контента ответа соответствует типам, указанным в опции -t.

Если ни -s, ни -t не указаны или имеют пустое значение, то совпадение не требуется. Таким образом, следующая директива устанавливает выходной заголовок Server на пользовательское значение для любого кода состояния и любого типа контента:

   more_set_headers    "Server: my_server";

Существующие заголовки ответа с тем же именем всегда переопределяются. Если вы хотите добавлять заголовки поэтапно, используйте стандартную директиву add_header.

Одна директива может устанавливать/добавлять несколько выходных заголовков. Например

   more_set_headers 'Foo: bar' 'Baz: bah';

Несколько вхождений опций допускаются в одной директиве. Их значения будут объединены. Например

   more_set_headers -s 404 -s '500 503' 'Foo: bar';

эквивалентно

   more_set_headers -s '404 500 503' 'Foo: bar';

Новый заголовок должен быть одной из форм:

  1. Name: Value
  2. Name:
  3. Name

Последние два фактически очищают значение заголовка Name.

Переменные Nginx допускаются в значениях заголовков. Например:

    set $my_var "dog";
    more_set_headers "Server: $my_var";

Но переменные не будут работать в ключах заголовков из-за соображений производительности.

Несколько директив установки/очистки заголовков допускаются в одном location, и они выполняются последовательно.

Директивы, унаследованные от верхнего уровня (например, блока http или серверных блоков), выполняются перед директивами в блоке location.

Обратите внимание, что хотя more_set_headers разрешен в location if блоках, он не разрешен в server if блоках, как в

   ?  # Это НЕ разрешено!
   ?  server {
   ?      if ($args ~ 'download') {
   ?          more_set_headers 'Foo: Bar';
   ?      }
   ?      ...
   ?  }

За кулисами использование этой директивы и ее друга more_clear_headers будет (лениво) регистрировать фильтр выходных заголовков, который изменяет r->headers_out так, как вы укажете.

more_clear_headers

синтаксис: more_clear_headers [-t <список content-type>]... [-s <список кодов состояния>]... <новый-заголовок>...

по умолчанию: нет

контекст: http, server, location, location if

фаза: output-header-filter

Очищает указанные выходные заголовки.

На самом деле,

    more_clear_headers -s 404 -t 'text/plain' Foo Baz;

точно эквивалентно

    more_set_headers -s 404 -t 'text/plain' "Foo: " "Baz: ";

или

    more_set_headers -s 404 -t 'text/plain' Foo Baz

Смотрите more_set_headers для получения дополнительных сведений.

Символ подстановки * также может использоваться в конце имени заголовка для указания шаблона. Например, следующая директива эффективно очищает любые выходные заголовки, начинающиеся с "X-Hidden-":

 more_clear_headers 'X-Hidden-*';

Поддержка символа подстановки * была впервые введена в v0.09.

more_set_input_headers

синтаксис: more_set_input_headers [-r] [-t <список content-type>]... <новый-заголовок>...

по умолчанию: нет

контекст: http, server, location, location if

фаза: rewrite tail

Очень похоже на more_set_headers, за исключением того, что он работает с входными заголовками (или заголовками запроса) и поддерживает только опцию -t.

Обратите внимание, что использование опции -t в этой директиве означает фильтрацию по заголовку Content-Type запроса, а не заголовку ответа.

За кулисами использование этой директивы и ее друга more_clear_input_headers будет (лениво) регистрировать обработчик rewrite phase, который изменяет r->headers_in так, как вы укажете. Обратите внимание, что он всегда выполняется в конце фазы rewrite, чтобы он выполнялся после стандартного rewrite module и работал в подзапросах.

Если указана опция -r, то заголовки будут заменены на новые значения только если они уже существуют.

more_clear_input_headers

синтаксис: more_clear_input_headers [-t <список content-type>]... <новый-заголовок>...

по умолчанию: нет

контекст: http, server, location, location if

фаза: rewrite tail

Очищает указанные входные заголовки.

На самом деле,

    more_clear_input_headers -t 'text/plain' Foo Baz;

точно эквивалентно

    more_set_input_headers -t 'text/plain' "Foo: " "Baz: ";

или

    more_set_input_headers -t 'text/plain' Foo Baz

Чтобы удалить заголовки запроса "Foo" и "Baz" для всех входящих запросов независимо от типа контента, мы можем написать

    more_clear_input_headers "Foo" "Baz";

Смотрите more_set_input_headers для получения дополнительных сведений.

Символ подстановки * также может использоваться в конце имени заголовка для указания шаблона. Например, следующая директива эффективно очищает любые входные заголовки, начинающиеся с "X-Hidden-":

     more_clear_input_headers 'X-Hidden-*';

Ограничения

  • В отличие от стандартного headers модуля, этот модуль не заботится автоматически о взаимосвязи между заголовками Expires, Cache-Control и Last-Modified. Вам нужно правильно настроить их самостоятельно или использовать модуль headers вместе с этим модулем.
  • Вы не можете удалить заголовок ответа Connection с помощью этого модуля, потому что заголовок ответа Connection генерируется стандартным ngx_http_header_filter_module в ядре Nginx, фильтр выходных заголовков которого всегда выполняется после фильтра этого модуля. Единственный способ фактически удалить заголовок Connection — это патчить ядро Nginx, то есть редактировать функцию C ngx_http_header_filter в файле src/http/ngx_http_header_filter_module.c.

Изменения

Изменения каждой версии этого модуля можно получить из журналов изменений пакета OpenResty:

http://openresty.org/#Changes

Набор тестов

Этот модуль поставляется с набором тестов на Perl. Тестовые случаи также декларативны. Спасибо модулю Test::Nginx в мире Perl.

Чтобы запустить его у себя:

 $ PATH=/path/to/your/nginx-with-headers-more-module:$PATH prove -r t

Чтобы запустить набор тестов с использованием memcheck от valgrind, используйте следующие команды:

 $ export PATH=/path/to/your/nginx-with-headers-more-module:$PATH
 $ TEST_NGINX_USE_VALGRIND=1 prove -r t

Вам нужно завершить любые процессы Nginx перед запуском набора тестов, если вы изменили бинарный файл сервера Nginx.

Поскольку один сервер nginx (по умолчанию, localhost:1984) используется во всех тестовых скриптах (.t файлы), бессмысленно запускать набор тестов параллельно, указывая -jN при вызове утилиты prove.

Некоторые части набора тестов требуют, чтобы модули proxy, rewrite и echo также были включены при сборке Nginx.

Смотрите также

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-headers-more.