Модуль Apache mod_filter
| Описание: | Модуль интеллектуальной контекстно-зависимой настройки фильтров |
|---|---|
| Статус: | Базовый |
| Идентификатор модуля: | filter_module |
| Исходный файл: | mod_filter.c |
| Совместимость: | Версия 2.1 и более поздние |
Краткое описание
Этот модуль позволяет настраивать выходные фильтры содержимого с учетом контекста. Например, 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}.
Обратите внимание, что сопоставление больше не поддерживает поиск подстрок. Вместо него можно использовать сопоставление с регулярными выражениями.
Примеры
- Серверные включения (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 только в том случае, если в заголовке Accept-Encoding НЕТ значения "gzip". Этот фильтр работает с 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
| Описание: | назначает выходной фильтр для определенного типа медиа |
|---|---|
| Синтаксис: | AddOutputFilterByType filter[;filter...] media-type [media-type] ... |
| Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | FileInfo |
| Статус: | Базовый |
| Модуль: | mod_filter |
| Совместимость: | До переноса в 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
| Описание: | настраивает цепочку фильтров |
|---|---|
| Синтаксис: | FilterChain [+=-@!]filter-name ... |
| Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
| Переопределение: | Options |
| Статус: | Базовый |
| Модуль: | 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 |
Эта директива объявляет выходной фильтр вместе с заголовком или переменной окружения, определяющими конфигурацию во время выполнения. Первый аргумент — это filter-name, используемый в директивах 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-ответа с учетом воздействия фильтра.
Эта директива имеет две формы. Если указаны три аргумента, она применяется к конкретному filter-name и provider-name этого фильтра. Если указаны два аргумента, она применяется к filter-name при запуске любого поставщика фильтра.
Флаги, заданные этой директивой, объединяются с флагами, зарегистрированными нижележащими поставщиками с помощью 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 |
Эта директива регистрирует поставщика интеллектуального фильтра. Поставщик будет вызван тогда и только тогда, когда объявленное expression при первом вызове управляющего фильтра вернет true.
provider-name должен быть зарегистрирован путем загрузки модуля, который регистрирует это имя с помощью ap_register_output_filter.
expression — это выражение ap_expr.
См. также
- Выражения в Apache HTTP Server — полный справочник и примеры.
mod_include
Директива FilterTrace
| Описание: | получает отладочную/диагностическую информацию из mod_filter
|
|---|---|
| Синтаксис: | FilterTrace filter-name level |
| Контекст: | конфигурация сервера, виртуальный хост, каталог |
| Статус: | Базовый |
| Модуль: | mod_filter |
Эта директива создает отладочную информацию из mod_filter. Она предназначена для тестирования и отладки поставщиков (модулей фильтров), но также может помочь в отладке самого mod_filter.
Состав отладочных данных зависит от заданного level:
-
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