Apache Module mod_filter
| Description: | Модуль конфигурации фильтров вывода, чувствительный к контексту |
|---|---|
| Status: | Base |
| Module Identifier: | filter_module |
| Source File: | mod_filter.c |
| Compatibility: | Версия 2.1 и более поздние |
Summary
Этот модуль позволяет выполнять интеллектуальную, контекстно-зависимую настройку фильтров содержимого вывода. Например, можно настроить Apache на обработку различных типов содержимого с помощью различных фильтров, даже если тип содержимого неизвестен заранее (например, при использовании прокси).
mod_filter работает, вводя косвенность в цепочку фильтров. Вместо вставки фильтров в цепочку, мы вставляем механизм фильтрации, который в свою очередь условно перенаправляет запрос к поставщику фильтра. Любой фильтр содержимого может использоваться в качестве поставщика для mod_filter; изменения в существующих модулях фильтров не требуются (хотя их можно упростить).
Интеллектуальная фильтрация
В традиционной модели фильтрации фильтры вставляются безусловно с помощью AddOutputFilter и аналогичных команд. Каждый фильтр затем должен определить, нужно ли его запускать, и для администраторов сервера доступно мало гибкости для динамической конфигурации цепочки.
mod_filter в отличие от этого даёт администраторам сервера большую гибкость в конфигурации цепочки фильтров. На самом деле, фильтры могут быть вставлены на основе сложных булевых выражений. Это обобщает ограниченную гибкость, предлагаемую AddOutputFilterByType.
Объявления фильтров, поставщики и цепочки
Рисунок 1: Традиционная модель фильтрации
В традиционной модели фильтры вывода представляют собой простую цепочку от генератора содержимого (обработчика) до клиента. Это работает хорошо, если цепочка фильтров правильно настроена, но создаёт проблемы, когда фильтры нужно настраивать динамически на основе результатов работы обработчика.
Рисунок 2: Модель mod_filter
mod_filter работает, вводя косвенность в цепочку фильтров. Вместо вставки фильтров в цепочку, мы вставляем механизм фильтрации, который в свою очередь условно перенаправляет запрос к поставщику фильтра. Любой фильтр содержимого может использоваться в качестве поставщика для mod_filter; изменения в существующих модулях фильтров не требуются (хотя их можно упростить). Может быть несколько поставщиков для одного фильтра, но для каждого запроса будет выполняться не более одного поставщика.
Цепочка фильтров состоит из любого количества экземпляров механизма фильтрации, каждый из которых может иметь любое количество поставщиков. Частным случаем является один поставщик с безусловным перенаправлением: это эквивалентно прямой вставке фильтра-поставщика в цепочку.
Настройка цепочки
Для настройки цепочки фильтров с помощью mod_filter есть три этапа. Подробности директив см. ниже.
- Объявить фильтры
- Директива
FilterDeclareобъявляет фильтр, присваивая ему имя и тип фильтра. Требуется только если фильтр не имеет типа по умолчанию AP_FTYPE_RESOURCE. - Зарегистрировать поставщиков
- Директива
FilterProviderрегистрирует поставщика для фильтра. Фильтр может быть объявлен с помощьюFilterDeclare; в противном случае FilterProvider неявно объявит его с типом по умолчанию AP_FTYPE_RESOURCE. Поставщик должен быть зарегистрирован с помощьюap_register_output_filterкаким-либо модулем. Последний аргументFilterProvider— это выражение: поставщик будет выбран для выполнения запроса только в том случае, если выражение приведёт к значению true. Выражение может оценивать заголовки HTTP-запроса или ответа, переменные среды или обработчик, используемый этим запросом. В отличие от предыдущих версий, mod_filter теперь поддерживает сложные выражения, включающие несколько критериев с логикой И/ИЛИ (&& / ||) и скобками. Подробности синтаксиса выражений описаны в документации ap_expr. - Настроить цепочку
- Вышеперечисленные директивы создают компоненты интеллектуальной цепочки фильтров, но не настраивают её для запуска. Директива
FilterChainсоздаёт цепочку фильтров из объявленных интеллектуальных фильтров, предоставляя гибкость для вставки фильтров в начало или конец цепочки, удаления фильтра или очистки цепочки.
Фильтрация и код состояния ответа
mod_filter обычно выполняет фильтры только для ответов со статусом HTTP 200 (OK). Если вы хотите отфильтровать документы с другими кодами состояния ответа, можно установить переменную среды filter-errordocs, и она будет работать со всеми ответами независимо от статуса. Для дальнейшего уточнения можно использовать условия выражений с FilterProvider.
Обновление конфигурации Apache HTTP Server 2.2
Директива FilterProvider изменилась с httpd 2.2: аргументы match и dispatch заменены единственным, но более универсальным аргументом expression. В общем случае вы можете преобразовать пару match/dispatch в два операнда выражения, используя что-то вроде:
"dispatch = 'match'"
Заголовки запроса, заголовки ответа и переменные среды теперь интерпретируются в соответствии с синтаксисом %{req:foo}, %{resp:foo} и %{env:foo} соответственно. Также поддерживаются переменные %{HANDLER} и %{CONTENT_TYPE}.
Обратите внимание, что match больше не поддерживает совпадение по подстрокам. Их можно заменить совпадениями по регулярным выражениям.
Примеры
- Включения на стороне сервера (SSI)
- Простой пример замены
AddOutputFilterByTypeFilterDeclare SSI FilterProvider SSI INCLUDES "%{CONTENT_TYPE} =~ m|^text/html|" FilterChain SSI - Включения на стороне сервера (SSI)
- То же самое, что и выше, но перенаправление по обработчику (классическое поведение SSI; файлы .shtml обрабатываются).
FilterProvider SSI INCLUDES "%{HANDLER} = 'server-parsed'" FilterChain SSI - Эмуляция mod_gzip с помощью mod_deflate
- Вставить фильтр INFLATE только в том случае, если "gzip" НЕ содержится в заголовке Accept-Encoding. Этот фильтр запускается с типом ftype CONTENT_SET.
FilterDeclare gzip CONTENT_SET FilterProvider gzip inflate "%{req:Accept-Encoding} !~ /gzip/" FilterChain gzip - Изменение размера изображения
- Предположим, мы хотим уменьшить размер всех веб-изображений и имеем фильтры для GIF, JPEG и PNG.
FilterProvider unpack jpeg_unpack "%{CONTENT_TYPE} = 'image/jpeg'" FilterProvider unpack gif_unpack "%{CONTENT_TYPE} = 'image/gif'" FilterProvider unpack png_unpack "%{CONTENT_TYPE} = 'image/png'" FilterProvider downsample downsample_filter "%{CONTENT_TYPE} = m|^image/(jpeg|gif|png)|" FilterProtocol downsample "change=yes" FilterProvider repack jpeg_pack "%{CONTENT_TYPE} = 'image/jpeg'" FilterProvider repack gif_pack "%{CONTENT_TYPE} = 'image/gif'" FilterProvider repack png_pack "%{CONTENT_TYPE} = 'image/png'" <Location "/image-filter"> FilterChain unpack downsample repack </Location>
Обработка протокола
Исторически каждый фильтр отвечает за то, чтобы любые изменения, которые он вносит, корректно отражались в заголовках HTTP-ответа и чтобы он не запускался, если это приведёт к незаконному изменению. Это возлагает на авторов фильтров задачу повторной реализации некоторых общих функций в каждом фильтре:
- Многие фильтры изменяют содержимое, делая недействительными существующие теги содержимого, контрольные суммы, хеши и длины.
- Фильтры, которые требуют полного, непрерывного ответа на входе, должны гарантировать, что они не получат фрагменты байтов от бэкэнда.
- Фильтры, которые преобразуют вывод в фильтре, должны гарантировать, что они не нарушают заголовок
Cache-Control: no-transformот бэкэнда. - Фильтры могут сделать ответы некэшируемыми.
mod_filter призван предложить общую обработку этих деталей реализации фильтров, уменьшая сложность, необходимую модулям фильтров содержимого. Эта функция находится в стадии разработки; FilterProtocol реализует некоторые из этих функций для обеспечения обратной совместимости с модулями Apache 2.0. Для httpd 2.1 и более поздних версий, API ap_register_output_filter_protocol и ap_filter_protocol позволяют модулям фильтров объявлять своё поведение.
В то же время mod_filter не должен мешать фильтру, который хочет обрабатывать все аспекты протокола. По умолчанию (то есть при отсутствии каких-либо директив FilterProtocol) mod_filter оставит заголовки без изменений.
На момент написания этой функции в значительной степени не тестировалось, так как модули, которые обычно используются, предназначены для работы с версией 2.0. Модули, использующие эту функцию, должны тщательно её протестировать.
Директива AddOutputFilterByType
| Description: | присваивает фильтр вывода определённому типу медиа |
|---|---|
| Syntax: | AddOutputFilterByType filter[;filter...] media-type [media-type] ... |
| Context: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
| Override: | FileInfo |
| Status: | Base |
| Module: | mod_filter |
| Compatibility: | Имел серьёзные ограничения до переноса в mod_filter в версии 2.3.7 |
Эта директива активирует конкретный фильтр вывода для запроса в зависимости от типа медиа ответа.
Следующий пример использует фильтр DEFLATE, который предоставляется mod_deflate. Он будет сжимать весь вывод (статический или динамический), который помечен как text/html или text/plain перед отправкой клиенту.
AddOutputFilterByType DEFLATE text/html text/plain
Если вы хотите, чтобы содержимое обрабатывалось более чем одним фильтром, их имена должны быть разделены точкой с запятой. Также можно использовать по одной директиве AddOutputFilterByType для каждого из этих фильтров.
Нижеприведённая конфигурация вызывает обработку всего скриптового вывода, помеченного как text/html, вначале фильтром INCLUDES , а затем фильтром DEFLATE.
<Location "/cgi-bin/">
Options Includes
AddOutputFilterByType INCLUDES;DEFLATE text/html
</Location> См. также
Директива FilterChain
| Description: | Настройка цепочки фильтров |
|---|---|
| Syntax: | FilterChain [+=-@!]filter-name ... |
| Context: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
| Override: | Options |
| Status: | Base |
| Module: | mod_filter |
Эта директива настраивает фактическую цепочку фильтров из объявленных фильтров. FilterChain принимает любое количество аргументов, каждый из которых необязательно предваряется символом управления, определяющим выполняемое действие:
+filter-name- Добавить filter-name в конец цепочки фильтров
@filter-name- Вставить filter-name в начало цепочки фильтров
-filter-name- Удалить filter-name из цепочки фильтров
=filter-name- Очистить цепочку фильтров и вставить filter-name
!- Очистить цепочку фильтров
filter-name- Эквивалентно
+filter-name
Директива FilterDeclare
| Описание: | Объявить интеллектуальный фильтр |
|---|---|
| Синтаксис: | FilterDeclare filter-name [type] |
| Контекст: | настройки сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | Options |
| Статус: | Базовый |
| Модуль: | mod_filter |
Эта директива объявляет выходной фильтр вместе с заголовком или переменной среды, которые будут определять конфигурацию во время выполнения. Первый аргумент — имя-фильтра для использования в директивах FilterProvider, FilterChain и FilterProtocol.
Последний (необязательный) аргумент — тип фильтра, принимающий значения ap_filter_type — а именно RESOURCE (по умолчанию), CONTENT_SET, PROTOCOL, TRANSCODE, CONNECTION или NETWORK.
Директива FilterProtocol
| Описание: | Обработка корректного протокола HTTP |
|---|---|
| Синтаксис: | FilterProtocol filter-name [provider-name] proto-flags |
| Контекст: | настройки сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | Options |
| Статус: | Базовый |
| Модуль: | mod_filter |
Эта директива направляет mod_filter на обеспечение того, чтобы фильтр не выполнялся, когда это не нужно, и что заголовки HTTP-ответа правильно устанавливаются с учетом влияния фильтра.
Существует две формы этой директивы. С тремя аргументами она применяется конкретно к имени-фильтра и имени-поставщика для этого фильтра. С двумя аргументами она применяется к имени-фильтра всякий раз, когда фильтр запускает любой поставщик.
Флаги, указанные в этой директиве, объединяются с флагами, которые могут быть зарегистрированы базовыми поставщиками с mod_filter. Например, фильтр может внутренне указать эквивалент change=yes, но конкретная конфигурация модуля может переопределить его с помощью change=no.
proto-flags может включать один или несколько из:
change=yes|no- Указывает, изменяет ли фильтр содержимое, включая, возможно, длину содержимого. Аргумент «no» поддерживается в 2.4.7 и более поздних версиях.
change=1:1- Фильтр изменяет содержимое, но не изменяет длину содержимого.
byteranges=no- Фильтр не может работать с диапазонами байтов и требует полного ввода.
proxy=no- Фильтр не должен выполняться в контексте прокси.
proxy=transform- Фильтр преобразует ответ таким образом, что он несовместим с заголовком HTTP
Cache-Control: no-transform. cache=no- Фильтр делает вывод некэшируемым (например, внося случайные изменения в содержимое).
Директива FilterProvider
| Описание: | Зарегистрировать фильтр содержимого |
|---|---|
| Синтаксис: | FilterProvider filter-name provider-name expression |
| Контекст: | настройки сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | Options |
| Статус: | Базовый |
| Модуль: | mod_filter |
Эта директива регистрирует поставщика для интеллектуального фильтра. Поставщик будет вызван только в том случае, если объявленное выражение выражение при первом вызове харизмы оценивается как истинное.
имя-поставщика должно быть зарегистрировано при загрузке модуля, который регистрирует это имя с помощью ap_register_output_filter.
выражение — это ap_expr.
См. также
- Выражения в Apache HTTP Server для полной справки и примеров.
mod_include
Директива FilterTrace
| Описание: | Получение диагностической информации из mod_filter
|
|---|---|
| Синтаксис: | FilterTrace filter-name level |
| Контекст: | настройки сервера, виртуальный хост, каталог |
| Статус: | Базовый |
| Модуль: | mod_filter |
Эта директива генерирует диагностическую информацию из mod_filter. Она предназначена для тестирования и отладки поставщиков (модулей фильтра), хотя она также может помочь с mod_filter.
Вывод отладки зависит от установленного значения уровень:
-
0(по умолчанию) - Диагностическая информация не генерируется.
1-
mod_filterзапишет в лог ошибок ведра и бригады, проходящие через фильтр, прежде чем поставщик обработает их. Это аналогично информации, генерируемой модулем mod_diagnostics. -
2(ещё не реализовано) - Выведет все данные, проходящие через временный файл, перед поставщиком. Только для отладки одного пользователя; это не будет поддерживать одновременные запросы.
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/mod/mod_filter.html