<status>Base</status>
<sourcefile>mod_filter.c</sourcefile>
<identifier>filter_module</identifier>
-<compatibility>Version 2.1 and later</compatibility>
<summary>
<p>This module enables smart, context-sensitive configuration of
<p><module>mod_filter</module> by contrast gives server administrators a
great deal of flexibility in configuring the filter chain. In fact,
- filters can be inserted based on any Request Header, Response Header
- or Environment Variable. This generalises the limited flexibility offered
- by <directive module="core">AddOutputFilterByType</directive>, and fixes
- it to work correctly with dynamic content, regardless of the
- content generator. The ability to dispatch based on Environment
- Variables offers the full flexibility of configuration with
- <module>mod_rewrite</module> to anyone who needs it.</p>
+ filters can be inserted based on complex boolean
+ <a href="../expr.html">expressions</a> This generalises the limited
+ flexibility offered by <directive>AddOutputFilterByType</directive>.</p>
</section>
<section id="terms"><title>Filter Declarations, Providers and Chains</title>
<dl>
<dt>Declare Filters</dt>
<dd>The <directive module="mod_filter">FilterDeclare</directive> directive
- declares a filter, assigning it a name and filter type. Required
- only if the filter is not the default type AP_FTYPE_RESOURCE.</dd>
-
+ declares a new smart filter, assigning it a name and optional filter
+ type.</dd>
<dt>Register Providers</dt>
<dd>The <directive module="mod_filter">FilterProvider</directive>
directive registers a provider with a filter. The filter may have
been declared with <directive module="mod_filter"
>FilterDeclare</directive>; if not, FilterProvider will implicitly
- declare it with the default type AP_FTYPE_RESOURCE. The provider
- must have been
+ declare it. The provider must have been
registered with <code>ap_register_output_filter</code> by some module.
The final argument to <directive module="mod_filter"
>FilterProvider</directive> is an expression: the provider will be
headers, environment variables, or the Handler used by this request.
Unlike earlier versions, mod_filter now supports complex expressions
involving multiple criteria with AND / OR logic (&& / ||)
- and brackets.</dd>
+ and brackets. The details of the expression syntax are described in
+ the <a href="../expr.html">ap_expr documentation</a>.</dd>
<dt>Configure the Chain</dt>
<dd>The above directives build components of a smart filter chain,
more versatile <var>expression</var>. In general, you can convert
a match/dispatch pair to the two sides of an expression, using
something like:</p>
- <example>"dispatch = match"</example>
+ <example>"dispatch = 'match'"</example>
<p>The Request headers, Response headers and Environment variables
- are now interpreted from syntax <var>$req{foo}</var>,
- <var>$resp{foo}</var> and <var>$env{foo}</var> respectively.
- The variables <var>$handler</var> and <var>$Content-Type</var>
+ are now interpreted from syntax <var>%{req:foo}</var>,
+ <var>%{resp:foo}</var> and <var>%{env:foo}</var> respectively.
+ The variables <var>%{HANDLER}</var> and <var>%{CONTENT_TYPE}</var>
are also supported.</p>
- <p>Note that the match no longer supports integer comparisons
- or substring matches. The latter can be replaced by regular
- expression matches.</p>
+ <p>Note that the match no longer support substring matches. They can be
+ replaced by regular expression matches.</p>
</section>
<section id="examples"><title>Examples</title>
<dl>
<dt>Server side Includes (SSI)</dt>
- <dd>A simple case of using <module>mod_filter</module> in place of
- <directive module="core">AddOutputFilterByType</directive>
- <example>
- FilterDeclare SSI<br/>
- FilterProvider SSI INCLUDES "$resp{Content-Type} = /^text\/html/"<br/>
- FilterChain SSI
- </example>
+ <dd>A simple case replacing <directive>AddOutputFilterByType</directive>.
+ This example creates a new smart filter named "SSI" that conditionally leverates
+ the "INCLUDES" filter from <module>mod_include</module> as a provider.
+ <highlight language="config">
+FilterDeclare SSI
+FilterProvider SSI INCLUDES "%{CONTENT_TYPE} =~ m|^text/html|"
+FilterChain SSI
+ </highlight>
</dd>
<dt>Server side Includes (SSI)</dt>
<dd>The same as the above but dispatching on handler (classic
SSI behaviour; .shtml files get processed).
- <example>
- FilterProvider SSI INCLUDES "Handler = server-parsed"<br/>
- FilterChain SSI
- </example>
+ <highlight language="config">
+FilterProvider SSI INCLUDES "%{HANDLER} = 'server-parsed'"
+FilterChain SSI
+ </highlight>
</dd>
<dt>Emulating mod_gzip with mod_deflate</dt>
- <dd>Insert INFLATE filter only if "gzip" is NOT in the
- Accept-Encoding header. This filter runs with ftype CONTENT_SET.
- <example>
- FilterDeclare gzip CONTENT_SET<br/>
- FilterProvider gzip inflate "$req{Accept-Encoding} != /gzip/"<br/>
- FilterChain gzip
- </example>
+ <dd>This example demonstrates the dynamic properties granted to traditional
+ filters when a smart filter is constructed around them. A new smart filter
+ named "gzip" is created that dynamically inserts <module>mod_deflate</module>'s
+ INFLATE filter only if "gzip" is NOT in the Accept-Encoding header.
+ The gzip smart filter runs with type CONTENT_SET.
+ <highlight language="config">
+FilterDeclare gzip CONTENT_SET
+FilterProvider gzip INFLATE "%{req:Accept-Encoding} !~ /gzip/"
+FilterChain gzip
+ </highlight>
</dd>
<dt>Image Downsampling</dt>
- <dd>Suppose we want to downsample all web images, and have filters
- for GIF, JPEG and PNG.
- <example>
- FilterProvider unpack jpeg_unpack "$resp{Content-Type} = image/jpeg"<br/>
- FilterProvider unpack gif_unpack "$resp{Content-Type} = image/gif"<br/>
- FilterProvider unpack png_unpack "$resp{Content-Type} = image/png"<br/>
- <br />
- FilterProvider downsample downsample_filter "$resp{Content-Type} = /image\/(jpeg|gif|png)/"<br/>
- FilterProtocol downsample "change=yes"<br/>
- <br />
- FilterProvider repack jpeg_pack "$resp{Content-Type} = image/jpeg"<br/>
- FilterProvider repack gif_pack "$resp{Content-Type} = image/gif"<br/>
- FilterProvider repack png_pack "$resp{Content-Type} = image/png"<br/>
- <Location /image-filter><br/>
- <indent>
- FilterChain unpack downsample repack<br/>
- </indent>
- </Location>
- </example>
+ <dd>This example demonstrates further abstractions that the smart filtering.
+ Suppose we want to downsample all web images, and have different
+ filter providers for manipulating GIF, JPEG and PNG
+ The configuration defines smart filters "unpack" and "repack" via
+ the harness that invokes the right underlying filter providers based on
+ the content type at runtime.
+ <highlight language="config">
+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>
+ </highlight>
</dd>
</dl>
</section>
Modules using it should test it carefully.</p>
</section>
+<directivesynopsis>
+<name>AddOutputFilterByType</name>
+<description>assigns an output filter to a particular media-type</description>
+<syntax>AddOutputFilterByType <var>filter</var>[;<var>filter</var>...]
+<var>media-type</var> [<var>media-type</var>] ...</syntax>
+<contextlist><context>server config</context>
+<context>virtual host</context><context>directory</context>
+<context>.htaccess</context></contextlist>
+<override>FileInfo</override>
+<compatibility>Had severe limitations before
+being moved to <module>mod_filter</module> in version 2.3.7</compatibility>
+
+<usage>
+ <p>This directive activates a particular output <a
+ href="../filter.html">filter</a> for a request depending on the
+ response <glossary>media-type</glossary>.</p>
+
+ <p>The following example uses the <code>DEFLATE</code> filter, which
+ is provided by <module>mod_deflate</module>. It will compress all
+ output (either static or dynamic) which is labeled as
+ <code>text/html</code> or <code>text/plain</code> before it is sent
+ to the client.</p>
+
+ <highlight language="config">
+ AddOutputFilterByType DEFLATE text/html text/plain
+ </highlight>
+
+ <p>If you want the content to be processed by more than one filter, their
+ names have to be separated by semicolons. It's also possible to use one
+ <directive>AddOutputFilterByType</directive> directive for each of
+ these filters.</p>
+
+ <p>The configuration below causes all script output labeled as
+ <code>text/html</code> to be processed at first by the
+ <code>INCLUDES</code> filter and then by the <code>DEFLATE</code>
+ filter.</p>
+
+ <highlight language="config">
+<Location "/cgi-bin/">
+ Options Includes
+ AddOutputFilterByType INCLUDES;DEFLATE text/html
+</Location>
+ </highlight>
+
+</usage>
+
+<seealso><directive module="mod_mime">AddOutputFilter</directive></seealso>
+<seealso><directive module="core">SetOutputFilter</directive></seealso>
+<seealso><a href="../filter.html">filters</a></seealso>
+</directivesynopsis>
+
<directivesynopsis>
<name>FilterDeclare</name>
<description>Declare a smart filter</description>
-<syntax>FilterDeclare <var>filter-name</var> <var>[type]</var></syntax>
+<syntax>FilterDeclare <var>smart-filter-name</var> <var>[type]</var></syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context><context>.htaccess</context></contextlist>
<override>Options</override>
<usage>
<p>This directive declares an output filter together with a
header or environment variable that will determine runtime
- configuration. The first argument is a <var>filter-name</var>
+ configuration. The first argument is a <var>smart-filter-name</var>
for use in <directive module="mod_filter">FilterProvider</directive>,
<directive module="mod_filter">FilterChain</directive> and
<directive module="mod_filter">FilterProtocol</directive> directives.</p>
<directivesynopsis>
<name>FilterProvider</name>
<description>Register a content filter</description>
-<syntax>FilterProvider <var>filter-name</var> <var>provider-name</var>
+<syntax>FilterProvider <var>smart-filter-name</var> <var>provider-name</var>
<var>expression</var></syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context><context>.htaccess</context></contextlist>
<code>ap_register_output_filter</code>.
</p>
- <p><var>expression</var> can be any of the following:</p>
- <dl>
- <dt><code><var>string</var></code></dt>
- <dd>true if <var>string</var> is not empty</dd>
-
- <dt><code><var>string1</var> = <var>string2</var><br />
- <var>string1</var> == <var>string2</var><br />
- <var>string1</var> != <var>string2</var></code></dt>
-
- <dd><p>Compare <var>string1</var> with <var>string2</var>. If
- <var>string2</var> has the form <code>/<var>string2</var>/</code>
- then it is treated as a regular expression. Regular expressions are
- implemented by the <a href="http://www.pcre.org">PCRE</a> engine and
- have the same syntax as those in <a href="http://www.perl.com">perl
- 5</a>. Note that <code>==</code> is just an alias for <code>=</code>
- and behaves exactly the same way.</p>
- </dd>
-
- <dt><code><var>string1</var> < <var>string2</var><br />
- <var>string1</var> <= <var>string2</var><br />
- <var>string1</var> > <var>string2</var><br />
- <var>string1</var> >= <var>string2</var></code></dt>
-
- <dd>Compare <var>string1</var> with <var>string2</var>. Note, that
- strings are compared <em>literally</em> (using
- <code>strcmp(3)</code>). Therefore the string "100" is less than
- "20".</dd>
-
- <dt><code>( <var>expression</var> )</code></dt>
- <dd>true if <var>expression</var> is true</dd>
-
- <dt><code>! <var>expression</var></code></dt>
- <dd>true if <var>expression</var> is false</dd>
-
- <dt><code><var>expression1</var> &&
- <var>expression2</var></code></dt>
- <dd>true if both <var>expression1</var> and
- <var>expression2</var> are true</dd>
-
- <dt><code><var>expression1</var> ||
- <var>expression2</var></code></dt>
- <dd>true if either <var>expression1</var> or
- <var>expression2</var> is true</dd>
- </dl>
+ <p><var>expression</var> is an
+ <a href="../expr.html">ap_expr</a>.</p>
</usage>
+<seealso><a href="../expr.html">Expressions in Apache HTTP Server</a>,
+for a complete reference and examples.</seealso>
+<seealso><module>mod_include</module></seealso>
</directivesynopsis>
<directivesynopsis>
<name>FilterChain</name>
<description>Configure the filter chain</description>
-<syntax>FilterChain [+=-@!]<var>filter-name</var> <var>...</var></syntax>
+<syntax>FilterChain [+=-@!]<var>smart-filter-name</var> <var>...</var></syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context><context>.htaccess</context></contextlist>
<override>Options</override>
determines what to do:</p>
<dl>
- <dt><code>+<var>filter-name</var></code></dt>
+ <dt><code>+<var>smart-filter-name</var></code></dt>
<dd>Add <var>filter-name</var> to the end of the filter chain</dd>
- <dt><code>@<var>filter-name</var></code></dt>
- <dd>Insert <var>filter-name</var> at the start of the filter chain</dd>
+ <dt><code>@<var>smart-filter-name</var></code></dt>
+ <dd>Insert <var>smart-filter-name</var> at the start of the filter chain</dd>
- <dt><code>-<var>filter-name</var></code></dt>
- <dd>Remove <var>filter-name</var> from the filter chain</dd>
+ <dt><code>-<var>smart-filter-name</var></code></dt>
+ <dd>Remove <var>smart-filter-name</var> from the filter chain</dd>
- <dt><code>=<var>filter-name</var></code></dt>
- <dd>Empty the filter chain and insert <var>filter-name</var></dd>
+ <dt><code>=<var>smart-filter-name</var></code></dt>
+ <dd>Empty the filter chain and insert <var>smart-filter-name</var></dd>
<dt><code>!</code></dt>
<dd>Empty the filter chain</dd>
- <dt><code><var>filter-name</var></code></dt>
- <dd>Equivalent to <code>+<var>filter-name</var></code></dd>
+ <dt><code><var>smart-filter-name</var></code></dt>
+ <dd>Equivalent to <code>+<var>smart-filter-name</var></code></dd>
</dl>
</usage>
</directivesynopsis>
<directivesynopsis>
<name>FilterProtocol</name>
<description>Deal with correct HTTP protocol handling</description>
-<syntax>FilterProtocol <var>filter-name</var> [<var>provider-name</var>]
+<syntax>FilterProtocol <var>smart-filter-name</var> [<var>provider-name</var>]
<var>proto-flags</var></syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context><context>.htaccess</context></contextlist>
filter.</p>
<p>There are two forms of this directive. With three arguments, it
- applies specifically to a <var>filter-name</var> and a
+ applies specifically to a <var>smart-filter-name</var> and a
<var>provider-name</var> for that filter.
- With two arguments it applies to a <var>filter-name</var> whenever the
+ With two arguments it applies to a <var>smart-filter-name</var> whenever the
filter runs <em>any</em> provider.</p>
+ <p>Flags specified with this directive are merged with the flags
+ that underlying providers may have registerd with
+ <module>mod_filter</module>. For example, a filter may internally specify
+ the equivalent of <code>change=yes</code>, but a particular
+ configuration of the module can override with <code>change=no</code>.
+ </p>
+
<p><var>proto-flags</var> is one or more of</p>
<dl>
- <dt><code>change=yes</code></dt>
- <dd>The filter changes the content, including possibly the content
- length</dd>
+ <dt><code>change=yes|no</code></dt>
+ <dd>Specifies whether the filter changes the content, including possibly
+ the content length. The "no" argument is supported in 2.4.7 and later.</dd>
<dt><code>change=1:1</code></dt>
<dd>The filter changes the content, but will not change the content
<name>FilterTrace</name>
<description>Get debug/diagnostic information from
<module>mod_filter</module></description>
-<syntax>FilterTrace <var>filter-name</var> <var>level</var></syntax>
+<syntax>FilterTrace <var>smart-filter-name</var> <var>level</var></syntax>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context></contextlist>
</directivesynopsis>
</modulesynopsis>
-