Модуль Apache mod_headers
| Описание: | Настройка заголовков HTTP-запросов и ответов |
|---|---|
| Статус: | Расширение |
| Идентификатор модуля: | headers_module |
| Исходный файл: | mod_headers.c |
Краткое описание
Этот модуль предоставляет директивы для управления заголовками HTTP-запросов и ответов и их изменения. Заголовки можно объединять, заменять или удалять.
Порядок обработки
Директивы, предоставляемые mod_headers, могут располагаться практически в любом месте конфигурации сервера, а их область действия можно ограничить, заключив их в секции конфигурации.
Порядок обработки важен и зависит как от порядка директив в файле конфигурации, так и от их расположения в секциях конфигурации. Эти две директивы дают разный эффект, если поменять их местами:
RequestHeader append MirrorID "mirror 12" RequestHeader unset MirrorID
В таком порядке заголовок MirrorID не устанавливается. Если поменять директивы местами, заголовок MirrorID будет иметь значение "mirror 12".
Ранняя и поздняя обработка
mod_headers можно применять как на раннем, так и на позднем этапе обработки запроса. Обычно используется поздний режим: заголовки запроса устанавливаются непосредственно перед запуском генератора содержимого, а заголовки ответа — непосредственно перед отправкой ответа по сети. На работающем сервере всегда используйте поздний режим.
Ранний режим предназначен для разработчиков и служит средством тестирования и отладки. Директивы, определенные с помощью ключевого слова early, применяются в самом начале обработки запроса. Это позволяет имитировать различные запросы и настраивать тестовые сценарии, но также означает, что другие модули могут изменить заголовки в любой момент до генерации ответа.
Поскольку ранние директивы обрабатываются до обхода конфигурации пути запроса, ранние заголовки можно устанавливать только в контексте основного сервера или виртуального хоста. Ранние директивы не могут зависеть от пути запроса, поэтому они не будут работать в таких контекстах, как <Directory> или <Location>.
Примеры
- Скопировать все заголовки запроса, начинающиеся с "TS", в заголовки ответа:
Header echo ^TS
- Добавить в ответ заголовок
MyHeaderс отметкой времени получения запроса и временем, прошедшим до начала его обработки. Клиент может использовать этот заголовок для оценки загрузки сервера или выявления узких мест между клиентом и сервером.Header set MyHeader "%D %t"
в результате к ответу добавляется следующий заголовок:
MyHeader: D=3775428 t=991424704447256
- Поздороваться с Джо
Header set MyHeader "Hello Joe. It took %D microseconds for Apache to serve this request."
в результате к ответу добавляется следующий заголовок:
MyHeader: Hello Joe. It took D=3775428 microseconds for Apache to serve this request.
- Отправлять
MyHeaderв ответе только в том случае, если в запросе присутствует заголовокMyRequestHeader. Это полезно для формирования заголовков в ответ на некоторые действия клиента. Обратите внимание, что для этого примера требуется модульmod_setenvif.SetEnvIf MyRequestHeader myvalue HAVE_MyRequestHeader Header set MyHeader "%D %t mytext" env=HAVE_MyRequestHeader
Если в HTTP-запросе присутствует заголовок
MyRequestHeader: myvalue, ответ будет содержать следующий заголовок:MyHeader: D=3775428 t=991424704447256 mytext
- Обеспечить работу DAV при использовании Apache для передачи HTTP через аппаратное SSL-устройство (описание проблемы), заменив https: на http: в заголовке Destination:
RequestHeader edit Destination ^https: http: early
- Установить одинаковое значение заголовка при нескольких невзаимоисключающих условиях, не дублируя значение в итоговом заголовке. Если для запроса выполняются все следующие условия (то есть для запроса заданы все переменные окружения
CGI,NO_CACHEиNO_STORE):Header merge Cache-Control no-cache env=CGI Header merge Cache-Control no-cache env=NO_CACHE Header merge Cache-Control no-store env=NO_STORE
то ответ будет содержать следующий заголовок:
Cache-Control: no-cache, no-store
Если вместо
mergeиспользоватьappend, ответ будет содержать следующий заголовок:Cache-Control: no-cache, no-cache, no-store
- Установить тестовый файл cookie только в том случае, если клиент не отправил нам файл cookie
Header set Set-Cookie testcookie "expr=-z %{req:Cookie}" - Добавить заголовок Caching для ответов с кодом состояния HTTP 200
Header append Cache-Control s-maxage=600 "expr=%{REQUEST_STATUS} == 200"
Директива Header
| Описание: | Настройка заголовков HTTP-ответа |
|---|---|
| Синтаксис: | Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] |
| Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | FileInfo |
| Статус: | Расширение |
| Модуль: | mod_headers |
| Совместимость: | SetIfEmpty доступен в версии 2.4.7 и более поздних, expr=value — в версии 2.4.10 и более поздних |
Эта директива может заменять, объединять или удалять заголовки HTTP-ответа. Заголовок изменяется сразу после запуска обработчика содержимого и выходных фильтров, что позволяет изменять исходящие заголовки.
Необязательный аргумент condition определяет, с какой внутренней таблицей заголовков ответов будет работать эта директива: onsuccess (по умолчанию, можно не указывать) или always. Разница между этими списками заключается в том, что заголовки из второго списка добавляются в ответ даже в случае ошибки и сохраняются при внутренних перенаправлениях (например, при использовании обработчиков ErrorDocument). Обратите также внимание, что в некоторых ситуациях имеет смысл повторить эту директиву с обоими условиями, поскольку always не является надмножеством onsuccess в отношении уже существующих заголовков:
- Вы добавляете заголовок в локально сформированный ответ с кодом, отличным от успешного (не 2xx), например перенаправление. В этом случае в окончательном ответе используется только таблица, соответствующая
always. - Вы изменяете или удаляете заголовок, созданный CGI-скриптом или
mod_proxy_fcgi. В этом случае заголовки CGI-скриптов находятся в таблице, соответствующейalways, а не в таблице по умолчанию. - Вы изменяете или удаляете заголовок, созданный каким-либо компонентом сервера, но этот заголовок не обнаруживается условием
onsuccessпо умолчанию.
Различие между onsuccess и always — следствие того, как httpd хранит заголовки HTTP-ответа внутри системы: он не предоставляет единого «нормализованного» списка заголовков. Если не учитывать это при написании конфигурации, некоторые HTTP-ответы могут содержать дублирующиеся заголовки, что может сбить с толку пользователей, а иногда и HTTP-клиентов. Например, предположим, что у вас есть простая конфигурация PHP-прокси с mod_proxy_fcgi, а ваши серверные PHP-скрипты добавляют заголовок X-Foo: bar в каждый HTTP-ответ. Как описано выше, mod_proxy_fcgi использует таблицу always для хранения заголовков, поэтому следующая конфигурация приводит к неверному результату: заголовок дублируется с обоими значениями:
# X-Foo's value is set in the 'onsuccess' headers table Header set X-Foo: baz
Чтобы обойти это ограничение, можно использовать несколько известных шаблонов конфигурации, например следующий:
# 'onsuccess' can be omitted since it is the default Header onsuccess unset X-Foo Header always set X-Foo "baz"
Независимо от параметра condition, описанного выше, действие можно ограничить кодами состояния HTTP, например для проксированных запросов или запросов CGI. См. приведенный выше пример с использованием %{REQUEST_STATUS}.
Выполняемое действие определяется первым аргументом (вторым аргументом, если задан condition). Возможны следующие значения:
Предупреждение
Прежде чем читать список действий, ознакомьтесь с приведенным выше описанием различий между списками заголовков always и onsuccess, поскольку это важное понятие применимо и здесь. Каждое действие работает именно так, как описано, но только с целевым списком заголовков.
add- Заголовок ответа добавляется к существующему набору заголовков, даже если такой заголовок уже существует. В результате может появиться два или более заголовка с одинаковым именем. Это может привести к непредвиденным последствиям; обычно вместо этого следует использовать
set,appendилиmerge. append- Заголовок ответа добавляется к любому существующему заголовку с таким же именем. Новое значение объединяется с существующим заголовком через запятую. Это стандартный способ HTTP передать несколько значений одного заголовка.
echo- Заголовки запроса с таким именем копируются в заголовки ответа. header может быть регулярным выражением. Аргумент value указывать не нужно.
editedit*- Если этот заголовок ответа существует, его значение преобразуется с помощью поиска и замены по регулярному выражению. Аргумент value — это регулярное выражение, а replacement — строка замены, которая может содержать обратные ссылки или спецификаторы формата. Форма
editвыполняет поиск и замену ровно один раз в значении заголовка, тогда как формаedit*заменяет каждое вхождение шаблона поиска, если он встречается несколько раз. merge- Заголовок ответа добавляется к любому существующему заголовку с таким же именем, если добавляемое значение еще не присутствует в списке значений заголовка, разделенных запятыми. Новое значение объединяется с существующим заголовком через запятую. Это стандартный способ HTTP передать несколько значений одного заголовка. Значения сравниваются с учетом регистра после обработки всех спецификаторов формата. Значения в двойных кавычках считаются отличными от таких же значений без кавычек.
set- Заголовок ответа устанавливается, заменяя любой ранее существовавший заголовок с таким именем. value может быть строкой формата.
setifempty- Заголовок запроса устанавливается, только если заголовка с таким именем еще нет. Особый случай — заголовок Content-Type: его значение может быть уже определено, но сам заголовок еще может отсутствовать в ответе на момент вычисления
setifempty. В этом случае безопаснее использоватьset, как в следующем примере:Header set Content-Type "text/plain" "expr=-z %{CONTENT_TYPE}" unset- Заголовок ответа с таким именем удаляется, если он существует. Если заголовков с таким именем несколько, удаляются все. Аргумент value указывать не нужно.
note- Значение указанного заголовка ответа header копируется во внутреннюю заметку, имя которой задается аргументом value. Это полезно, если заголовок, отправленный CGI-скриптом или проксируемым ресурсом, необходимо удалить, но при этом сохранить в журнале.
Доступно в версии 2.4.7 и более поздних.
После этого аргумента указывается имя заголовка header. Двоеточие в конце можно указать, но это необязательно. Регистр символов игнорируется для set, append, merge, add, unset и edit. Имя заголовка header для echo чувствительно к регистру и может быть регулярным выражением.
Для set, append, merge и add следующим аргументом задается value. Если value содержит пробелы, его следует заключить в двойные кавычки. value может быть строкой символов, строкой, содержащей специфичные для mod_headers спецификаторы формата (и символьные литералы), или выражением ap_expr с префиксом expr=
В value поддерживаются следующие спецификаторы формата:
| Формат | Описание |
|---|---|
%% | Знак процента |
%t | Время получения запроса в микросекундах по всемирному координированному времени, отсчитываемое от начала эпохи (1 января 1970 года). Перед значением указывается t=. |
%D | Время от получения запроса до отправки заголовков по сети. Это показатель длительности обработки запроса. Перед значением указывается D=. Значение измеряется в микросекундах. |
%l | Текущие средние значения нагрузки самого сервера. Этот параметр предназначен для отображения значений, получаемых с помощью getloadavg(), и представляет текущую среднюю нагрузку, а также средние значения за 5 и 15 минут. Перед значением указывается l=, а отдельные средние значения разделяются символом /.Доступно в версии 2.4.4 и более поздних. |
%i | Текущий процент времени простоя httpd (от 0 до 100) на основе доступных процессов и потоков. Перед значением указывается i=.Доступно в версии 2.4.4 и более поздних. |
%b | Текущий процент занятости httpd (от 0 до 100) на основе доступных процессов и потоков. Перед значением указывается b=.Доступно в версии 2.4.4 и более поздних. |
%{VARNAME}e | Содержимое переменной окружения VARNAME. |
%{VARNAME}s | Содержимое переменной окружения SSL VARNAME, если включен mod_ssl. |
Примечание
Спецификатор формата %s доступен только в Apache 2.1 и более поздних версиях; его можно использовать вместо %e, чтобы избежать накладных расходов на включение SSLOptions +StdEnvVars. Если SSLOptions +StdEnvVars в любом случае необходимо включить по другой причине, %e будет эффективнее, чем %s.
Примечание о значениях выражений
Если для параметра value используется парсер ap_expr, синтаксис некоторых выражений будет отличаться от примеров, в которых вычисляются логические выражения, например <If>:
- Начальным элементом грамматики является 'string', а не 'expr'.
- Вызовы функций используют синтаксис %{funcname:arg}, а не funcname(arg).
- Функции с несколькими аргументами пока недоступны из этой начальной точки.
- Заключайте весь параметр в кавычки, например
Header set foo-checksum "expr=%{md5:foo}"
Для edit задаются аргумент value, представляющий собой регулярное выражение, и дополнительная строка replacement. Начиная с версии 2.4.7 строка замены также может содержать спецификаторы формата.
После директивы Header может указываться дополнительный аргумент одного из следующих видов:
early- Указывает на раннюю обработку.
env=[!]varname- Директива применяется только в том случае, если существует переменная окружения
varname. Символ!передvarnameинвертирует проверку, поэтому директива применяется, только еслиvarnameне задана. expr=expression- Директива применяется только в том случае, если expression имеет значение true. Сведения о синтаксисе и вычислении выражений приведены в документации по ap_expr.
# This delays the evaluation of the condition clause compared to <If> Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path.php$#"
За исключением раннего режима, директивы Header обрабатываются непосредственно перед отправкой ответа по сети. Это позволяет устанавливать и/или переопределять большинство заголовков, кроме некоторых заголовков, добавляемых фильтром HTTP-заголовков. До версии 2.2.12 эта директива не позволяла изменять заголовок Content-Type.
Директива RequestHeader
| Описание: | Настройка заголовков HTTP-запроса |
|---|---|
| Синтаксис: | RequestHeader add|append|edit|edit*|merge|set|setifempty|unset header [[expr=]value [replacement] [early|env=[!]varname|expr=expression]] |
| Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | FileInfo |
| Статус: | Расширение |
| Модуль: | mod_headers |
| Совместимость: | SetIfEmpty доступен в версии 2.4.7 и более поздних, expr=value — в версии 2.4.10 и более поздних |
Эта директива может заменять, объединять, изменять или удалять заголовки HTTP-запроса. Заголовок изменяется непосредственно перед запуском обработчика содержимого, что позволяет изменять входящие заголовки. Выполняемое действие определяется первым аргументом. Возможны следующие значения:
add- Заголовок запроса добавляется к существующему набору заголовков, даже если такой заголовок уже существует. В результате может появиться два или более заголовка с одинаковым именем. Это может привести к непредвиденным последствиям; обычно вместо этого следует использовать
set,appendилиmerge. append- Заголовок запроса добавляется к любому существующему заголовку с таким же именем. Новое значение объединяется с существующим заголовком через запятую. Это стандартный способ HTTP передать несколько значений одного заголовка.
editedit*- Если этот заголовок запроса существует, его значение преобразуется с помощью поиска и замены по регулярному выражению. Аргумент value — это регулярное выражение, а replacement — строка замены, которая может содержать обратные ссылки или спецификаторы формата. Форма
editвыполняет поиск и замену ровно один раз в значении заголовка, тогда как формаedit*заменяет каждое вхождение шаблона поиска, если он встречается несколько раз. merge- Заголовок запроса добавляется к любому существующему заголовку с таким же именем, если добавляемое значение еще не присутствует в существующем списке значений заголовка, разделенных запятыми. Новое значение объединяется с существующим заголовком через запятую. Это стандартный способ HTTP передать несколько значений одного заголовка. Значения сравниваются с учетом регистра после обработки всех спецификаторов формата. Значения в двойных кавычках считаются отличными от таких же значений без кавычек.
set- Заголовок запроса устанавливается, заменяя любой ранее существовавший заголовок с таким именем.
setifempty- Заголовок запроса устанавливается, только если заголовка с таким именем еще нет.
Доступно в версии 2.4.7 и более поздних. unset- Заголовок запроса с таким именем удаляется, если он существует. Если заголовков с таким именем несколько, удаляются все. Аргумент value указывать не нужно.
После этого аргумента указывается имя заголовка. Двоеточие в конце можно указать, но это необязательно. Регистр символов игнорируется. Для set, append, merge и add в качестве третьего аргумента задается value. Если value содержит пробелы, его следует заключить в двойные кавычки. Для unset указывать value не нужно. value может быть строкой символов, строкой со спецификаторами формата или их комбинацией. Поддерживаемые спецификаторы формата совпадают со спецификаторами для Header; подробное описание см. там. Для edit требуются аргументы value и replacement, которые должны быть регулярным выражением и строкой замены соответственно.
После директивы RequestHeader может указываться дополнительный аргумент одного из следующих видов:
early- Указывает на раннюю обработку.
env=[!]varname- Директива применяется только в том случае, если существует переменная окружения
varname. Символ!передvarnameинвертирует проверку, поэтому директива применяется, только еслиvarnameне задана. expr=expression- Директива применяется только в том случае, если expression имеет значение true. Сведения о синтаксисе и вычислении выражений приведены в документации по ap_expr.
За исключением раннего режима, директива RequestHeader обрабатывается непосредственно перед тем, как обработчик запустит обработку запроса на этапе fixup. Это позволяет переопределять или изменять заголовки, сформированные браузером или входными фильтрами Apache.
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/mod/mod_headers.html