Apache HTTP 服务器版本 2.4
描述 | 上下文敏感的智能过滤器配置模块 |
---|---|
状态 | 基础 |
模块标识符 | 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
的最后一个参数是一个表达式:当且仅当表达式计算结果为真时,提供程序才会被选中以针对请求运行。表达式可以计算 HTTP 请求或响应标头、环境变量或此请求使用的处理程序。与早期版本不同,mod_filter 现在支持包含使用 AND / OR 逻辑(&& / ||)和括号的多个条件的复杂表达式。表达式语法的详细信息在 ap_expr 文档 中描述。FilterChain
指令从声明的智能过滤器构建过滤器链,提供在链的开头或结尾插入过滤器、删除过滤器或清除链的灵活性。mod_filter 通常只对 HTTP 状态为 200(OK)的响应运行过滤器。如果你想过滤具有其他响应状态的文档,你可以设置 filter-errordocs 环境变量,它将对所有响应(无论状态如何)起作用。为了进一步细化这一点,你可以使用 FilterProvider
的表达式条件。
FilterProvider
指令已从 httpd 2.2 中更改:match 和 dispatch 参数被单个但更通用的 expression 替换。通常,你可以将匹配/分派对转换为表达式的两侧,使用类似于以下内容:
"dispatch = 'match'"
请求标头、响应标头和环境变量现在分别从语法 %{req:foo}、%{resp:foo} 和 %{env:foo} 中解释。变量 %{HANDLER} 和 %{CONTENT_TYPE} 也受支持。
请注意,匹配不再支持子字符串匹配。它们可以用正则表达式匹配替换。
AddOutputFilterByType
的一个简单案例FilterDeclare SSI FilterProvider SSI INCLUDES "%{CONTENT_TYPE} =~ m|^text/html|" FilterChain SSI
FilterProvider SSI INCLUDES "%{HANDLER} = 'server-parsed'" FilterChain SSI
FilterDeclare gzip CONTENT_SET FilterProvider gzip inflate "%{req:Accept-Encoding} !~ /gzip/" FilterChain gzip
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 及更高版本,ap_register_output_filter_protocol
和 ap_filter_protocol
API 使过滤器模块能够声明自己的行为。
同时,mod_filter
不应干扰想要处理所有协议方面的过滤器。默认情况下(即在没有任何 FilterProtocol
指令的情况下),mod_filter
将保持标头不变。
在撰写本文时,此功能在很大程度上未经测试,因为常用模块被设计为与 2.0 一起使用。使用它的模块应该仔细测试它。
描述 | 将输出过滤器分配给特定媒体类型 |
---|---|
语法 | AddOutputFilterByType filter[;filter...] media-type [media-type] ... |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | FileInfo |
状态 | 基础 |
模块 | mod_filter |
兼容性 | 在版本 2.3.7 中移至 mod_filter 之前存在严重限制 |
此指令根据响应 媒体类型 激活特定输出 过滤器 以用于请求。
以下示例使用 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 [+=-@!]filter-name ... |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 选项 |
状态 | 基础 |
模块 | mod_filter |
这将配置一个实际的过滤器链,来自已声明的过滤器。FilterChain
接受任意数量的参数,每个参数可以选择性地以一个单字符控制符开头,该控制符决定要执行的操作
+filter-name
@filter-name
-filter-name
=filter-name
!
filter-name
+filter-name
描述 | 声明一个智能过滤器 |
---|---|
语法 | FilterDeclare filter-name [type] |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 选项 |
状态 | 基础 |
模块 | mod_filter |
此指令声明一个输出过滤器,以及一个将决定运行时配置的标头或环境变量。第一个参数是 filter-name,用于在 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 响应标头在考虑到过滤器的影响的情况下被正确设置。
此指令有两种形式。使用三个参数时,它专门应用于 filter-name 和该过滤器的 provider-name。使用两个参数时,它在过滤器运行任何提供程序时应用于 filter-name。
使用此指令指定的标志将与底层提供程序可能已向 mod_filter
注册的标志合并。例如,过滤器可以在内部指定等效于 change=yes
的内容,但模块的特定配置可以使用 change=no
覆盖。
proto-flags 是以下一项或多项
change=yes|no
change=1:1
byteranges=no
proxy=no
proxy=transform
Cache-Control: no-transform
标头不兼容的方式转换响应。cache=no
描述 | 注册一个内容过滤器 |
---|---|
语法 | FilterProvider filter-name provider-name expression |
上下文 | 服务器配置、虚拟主机、目录、.htaccess |
覆盖 | 选项 |
状态 | 基础 |
模块 | mod_filter |
此指令为智能过滤器注册一个提供程序。当首次调用该程序时,只有当声明的 expression 评估为真时,才会调用该提供程序。
provider-name 必须通过加载一个使用 ap_register_output_filter
注册该名称的模块来注册。
expression 是一个 ap_expr。
mod_include
描述 | 从 mod_filter 获取调试/诊断信息 |
---|---|
语法 | FilterTrace filter-name level |
上下文 | 服务器配置、虚拟主机、目录 |
状态 | 基础 |
模块 | mod_filter |
此指令从 mod_filter
生成调试信息。它旨在帮助测试和调试提供程序(过滤器模块),尽管它也可能有助于 mod_filter
本身。
调试输出取决于设置的 level
0
(默认值)1
mod_filter
将在提供程序处理它们之前,将通过过滤器的桶和旅记录到错误日志中。这类似于 mod_diagnostics 生成的信息。2
(尚未实现)