Пункт 143. Модуль Apache mod_filter
Этот модуль обеспечивает интеллектуальную контекстно-зависимую настройку фильтров содержимого вывода. Например, apache можно настроить для обработки разных типов контента через разные фильтры, даже если тип контента заранее неизвестен (например, в прокси-сервере).
mod_filter
работает путем введения косвенности в цепочку фильтров. Вместо того, чтобы вставлять фильтры в цепочку, мы вставляем обвязку фильтров, которая, в свою очередь, условно отправляет поставщику фильтров. Любой фильтр контента может быть использован в качестве поставщика mod_filter
; никаких изменений в существующих модулях фильтров не требуется (хотя их можно упростить).
Умная фильтрация
В традиционной модели фильтрации фильтры безоговорочно вставляются с использованием AddOutputFilter
и семейства. Затем каждый фильтр должен определить, следует ли запускать его, и у администраторов серверов мало гибкости, позволяющей динамически настраивать цепочку.
mod_filter
напротив, дает администраторам серверов большую гибкость в настройке цепочки фильтров. Фактически, фильтры могут быть вставлены на основе сложных логических выражений. Это обобщает ограниченную гибкость, предлагаемую AddOutputFilterByType
.
Объявления фильтров, провайдеры и цепочки
Рисунок 1: Традиционная модель фильтра
В традиционной модели выходные фильтры представляют собой простую цепочку от генератора контента (обработчика) до клиента. Это хорошо работает при условии, что цепочка фильтров может быть правильно настроена, но создает проблемы, когда фильтры необходимо настраивать динамически на основе результатов обработчика.
mod_filter
Рисунок 2: Модель
mod_filter
работает путем введения косвенности в цепочку фильтров. Вместо того, чтобы вставлять фильтры в цепочку, мы вставляем обвязку фильтров, которая, в свою очередь, условно отправляет поставщику фильтров. Любой фильтр контента может быть использован в качестве поставщика mod_filter
; никаких изменений в существующих модулях фильтров не требуется (хотя их можно упростить). Для одного фильтра может быть несколько провайдеров, но для одного запроса будет работать не более одного провайдера.
Цепочка фильтров включает любое количество экземпляров набора фильтров, каждый из которых может иметь любое количество поставщиков. Особым случаем является один провайдер с безусловной отправкой: это эквивалентно вставке фильтра провайдера непосредственно в цепочку.
Настройка цепочки
Существует три этапа настройки цепочки фильтров с помощью
mod_filter
. Подробнее о директивах см. ниже.
- Объявить фильтры
- Директива
FilterDeclare
объявляет фильтр, присваивая ему имя и тип фильтра. Требуется, только если фильтр не является типом по умолчанию AP_FTYPE_RESOURCE.
- Регистрация провайдеров
- Директива
FilterProvider
регистрирует провайдера с фильтром. Фильтр мог быть объявлен с FilterDeclare
; если нет, FilterProvider неявно объявит его с типом по умолчанию AP_FTYPE_RESOURCE. Поставщик должен быть зарегистрирован ap_register_output_filter
каким-либо модулем. Последним аргументом FilterProvider
является выражение: провайдер будет выбран для выполнения запроса тогда и только тогда, когда выражение оценивается как истинное. Выражение может оценивать заголовки запроса или ответа HTTP, переменные среды или обработчик, используемый этим запросом. В отличие от предыдущих версий, mod_filter теперь поддерживает сложные выражения, включающие несколько критериев с логикой И/ИЛИ (&& / ||) и скобками. Подробности синтаксиса выражения описаны в документации ap_expr.
- Настроить цепочку
- Приведенные выше директивы создают компоненты цепочки интеллектуальных фильтров, но не настраивают ее для работы. Директива
FilterChain
создает цепочку фильтров из объявленных интеллектуальных фильтров, предлагая гибкость для вставки фильтров в начало или конец цепочки, удаления фильтра или очистки цепочки.
Фильтрация и статус ответа
mod_filter обычно запускает фильтры только для ответов с HTTP-статусом 200 (ОК). Если вы хотите фильтровать документы с другими статусами ответов, вы можете установить
переменную окружения filter-errordocs , и она будет работать со всеми ответами независимо от статуса. Чтобы уточнить это, вы можете использовать условия выражения с FilterProvider
.
Обновление конфигурации Apache HTTP Server 2.2
Директива FilterProvider
изменилась по сравнению с httpd 2.2: аргументы match и
dispatch заменены одним, но более универсальным выражением . В общем, вы можете преобразовать пару соответствия/отправки в две стороны выражения, используя что-то вроде:
"dispatch = 'match'"
Заголовки запросов, заголовки ответов и переменные среды теперь интерпретируются из синтаксиса %{req:foo} ,
%{resp:foo} и %{env:foo} соответственно.
Также поддерживаются переменные %{HANDLER} и %{CONTENT_TYPE} .
Обратите внимание, что совпадение больше не поддерживает совпадения подстрок. Их можно заменить совпадениями регулярных выражений.
Примеры
- Включает серверную часть (SSI)
- Простой случай замены
AddOutputFilterByType
ФильтрОбъявить SSI
FilterProvider SSI ВКЛЮЧАЕТ "%{CONTENT_TYPE} =~ m|^text/html|"
Фильтрчейн SSI
- Включает серверную часть (SSI)
- То же, что и выше, но с диспетчеризацией на обработчике (классическое поведение SSI; обрабатываются файлы .shtml).
FilterProvider SSI ВКЛЮЧАЕТ "%{HANDLER} = 'проанализировано сервером'"
Фильтрчейн SSI
- Эмуляция mod_gzip с помощью mod_deflate
- Вставляйте фильтр INFLATE, только если «gzip» НЕ указан в заголовке Accept-Encoding. Этот фильтр работает с ftype CONTENT_SET.
ФильтрОбъявить gzip CONTENT_SET
FilterProvider gzip inflate "%{req:Accept-Encoding} !~ /gzip/"
Цепочка фильтров gzip
- Понижение разрешения изображения
- Предположим, мы хотим уменьшить разрешение всех веб-изображений и использовать фильтры для GIF, JPEG и PNG.
FilterProvider распаковывает jpeg_unpack "%{CONTENT_TYPE} = 'image/jpeg'"
FilterProvider распаковать gif_unpack "%{CONTENT_TYPE} = 'image/gif'"
FilterProvider распаковать png_unpack "%{CONTENT_TYPE} = 'image/png'"
FilterProvider downsample downsample_filter "%{CONTENT_TYPE} = m|^image/(jpeg|gif|png)|"
Понизить выборку FilterProtocol "change=yes"
Переупаковка FilterProvider jpeg_pack "%{CONTENT_TYPE} = 'image/jpeg'"
Переупаковка FilterProvider gif_pack "%{CONTENT_TYPE} = 'image/gif'"
Переупаковка FilterProvider png_pack "%{CONTENT_TYPE} = 'image/png'"
<Расположение "/изображение-фильтр">
FilterChain распаковать и перепаковать
</местоположение>
Обработка протокола
Исторически сложилось так, что каждый фильтр отвечает за то, чтобы любые изменения, которые он вносит, были правильно представлены в заголовках ответа 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 |
Переопределить: | Информация о файле |
Положение дел: | База |
Модуль: | 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
.
<Расположение "/cgi-bin/">
Опции Включает
AddOutputFilterByType ВКЛЮЧАЕТ; DEFLATE text/html
</местоположение>
Смотрите также
-
AddOutputFilter
-
SetOutputFilter
- фильтры
Директива FilterChain
Описание: | Настроить цепочку фильтров |
Синтаксис: | FilterChain [+=-@!]filter-name ... |
Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
Переопределить: | Параметры |
Положение дел: | База |
Модуль: | mod_filter |
Это настраивает фактическую цепочку фильтров из объявленных фильтров.
FilterChain
принимает любое количество аргументов, каждому из которых может предшествовать односимвольный элемент управления, определяющий, что делать:
-
+filter-name
- Добавить имя фильтра в конец цепочки фильтров
-
@filter-name
- Вставьте имя-фильтра в начало цепочки фильтров.
-
-filter-name
- Удалить имя-фильтра из цепочки фильтров
-
=filter-name
- Очистите цепочку фильтров и вставьте имя-фильтра
-
!
- Очистить цепочку фильтров
-
filter-name
- Эквивалентно
+filter-name
Директива FilterDeclare
Описание: | Объявите умный фильтр |
Синтаксис: | FilterDeclare filter-name [type] |
Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
Переопределить: | Параметры |
Положение дел: | База |
Модуль: | mod_filter |
Эта директива объявляет выходной фильтр вместе с заголовком или переменной среды, которые будут определять конфигурацию среды выполнения. Первый аргумент — это имя фильтра
для использования в FilterProvider
директивах
FilterChain
и
FilterProtocol
.
Последний (необязательный) аргумент представляет собой тип фильтра и принимает значения, ap_filter_type
а именно RESOURCE
(по умолчанию), CONTENT_SET
,
PROTOCOL
,
или . TRANSCODE
CONNECTION
NETWORK
Директива протокола фильтра
Описание: | Работа с правильной обработкой протокола HTTP |
Синтаксис: | FilterProtocol filter-name [provider-name]
proto-flags |
Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
Переопределить: | Параметры |
Положение дел: | База |
Модуль: | mod_filter |
Это направлено mod_filter
на обеспечение того, чтобы фильтр не запускался, когда он не должен, и чтобы заголовки ответов HTTP были правильно установлены с учетом эффектов фильтра.
Есть две формы этой директивы. С тремя аргументами он применяется конкретно к имени фильтра и
имени поставщика для этого фильтра. С двумя аргументами он применяется к имени фильтра всякий раз, когда фильтр запускает любого поставщика.
Флаги, указанные в этой директиве, объединяются с флагами, которые могут быть зарегистрированы нижележащими поставщиками
mod_filter
. Например, фильтр может внутренне указать эквивалент change=yes
, но конкретная конфигурация модуля может переопределить change=no
.
протофлаги — это один или несколько
-
change=yes|no
- Указывает, изменяет ли фильтр содержимое, включая, возможно, длину содержимого. Аргумент «нет» поддерживается в версии 2.4.7 и более поздних.
-
change=1:1
- Фильтр изменяет содержимое, но не меняет длину содержимого.
-
byteranges=no
- Фильтр не может работать с диапазонами байтов и требует полного ввода
-
proxy=no
- Фильтр не должен работать в контексте прокси
-
proxy=transform
- Фильтр преобразует ответ способом, несовместимым с
Cache-Control: no-transform
заголовком HTTP.
-
cache=no
- Фильтр делает вывод некэшируемым (например, вводя рандомизированные изменения содержимого).
Директива поставщика фильтров
Описание: | Зарегистрируйте контент-фильтр |
Синтаксис: | FilterProvider filter-name provider-name
expression |
Контекст: | конфигурация сервера, виртуальный хост, каталог, .htaccess |
Переопределить: | Параметры |
Положение дел: | База |
Модуль: | mod_filter |
Эта директива регистрирует поставщика для интеллектуального фильтра. Поставщик будет вызываться тогда и только тогда, когда объявленное выражение
оценивается как истинное при первом вызове обвязки.
имя-провайдера должно быть зарегистрировано путем загрузки модуля, который регистрирует имя с расширением
ap_register_output_filter
.
выражение представляет собой ap_expr.
Смотрите также
- Выражения в HTTP-сервере Apache для полного справочника и примеров.
-
mod_include
Директива FilterTrace
Описание: | Получить отладочную/диагностическую информацию из
mod_filter |
Синтаксис: | FilterTrace filter-name level |
Контекст: | конфигурация сервера, виртуальный хост, каталог |
Положение дел: | База |
Модуль: | mod_filter |
Эта директива генерирует отладочную информацию из файлов
mod_filter
. Он предназначен для помощи в тестировании и отладке провайдеров (модулей фильтров), хотя может помочь и сам по mod_filter
себе.
Вывод отладки зависит от установленного уровня :
-
0
(по умолчанию)
- Отладочная информация не генерируется.
-
1
-
mod_filter
будет записывать корзины и бригады, проходящие через фильтр, в журнал ошибок до того, как провайдер их обработает. Это похоже на информацию, сгенерированную mod_diagnostics.
-
2
(еще не реализовано)
- Выгружает полные данные, проходящие через временный файл перед провайдером. Только для однопользовательской отладки ; это не будет поддерживать одновременные обращения.