Apache2+mod_perl环境下的HTTP处理模型
本文参考了 mod_perl 的官方文档之一, 但并不是原文档的翻译。
一个HTTP请求是按照如下流程被处理的。这里借用一下官方文档的插图。
可见,从 Wait 状态开始,HTTP处理的生命周期由以下12个部分组成:
- PerlPostReadRequestHandler (PerlInitHandler)
- PerlTransHandler
- PerlMapToStorageHandler
- PerlHeaderParserHandler (PerlInitHandler)
- PerlAccessHandler
- PerlAuthenHandler
- PerlAuthzHandler
- PerlTypeHandler
- PerlFixupHandler
- PerlResponseHandler
- PerlLogHandler
- PerlCleanupHandler
通常,上述步骤会按照顺序逐一执行,但如果中间任何一步出现错误, 处理将直接跳到 PerlLogHandler。
你可以写一段 Perl 程序,并利用相应的命令将其安装到上述 12 个步骤中的任何一步, 以控制 Apache2 处理 HTTP请求的方式。这种 Perl 程序的框架如下:
package MyApache2::MyHandlerName;
# load modules that are going to be used
use ...;
# compile (or import) constants
use Apache2::Const -compile => qw(OK);
sub handler {
my $r = shift;
# handler code comes here
return Apache2::Const::OK; # or another status constant
}
1;
handler 函数使用不同的返回值控制 Apache2 的处理行为。 若 handler 返回 Apache2::Const::OK,则表示该步骤的处理已经完全结束, Apache2 会直接进入下一个步骤,而不去执行 Apache2 默认的处理程序; 若 handler 返回 Apache2::Const::DECLINED,则表明该处理程序正常结束, 但 Apache2 会继续执行该步骤其余的处理程序(包括 Apache2 的默认处理); 若 handler 返回 Apache2::Const::DONE 或者其他结果,则 Apache2 会认为 出现了错误,从而终止处理过程,直接跳转到最后的 PerlLogHandler 和 PerlCleanupHandler。
PerlCleanupHandlerPerlPost
该步骤为 HTTP 请求到达后的第一个步骤。通常,该步骤中可以执行那些对任何请求都必须执行的动作。 例如,可以在该步骤执行 Apache2::Reload 以检查服务器中的Perl模块是否被更新。
在该步骤中,Apache2 还不知道 HTTP 请求是针对服务器上哪个文件或目录的,
因此该步骤的处理程序只能配置在 httpd.conf 的全局部分或者
PerlTransHandler
该步骤通常用于翻译 HTTP 请求的 URI。Apache2的默认动作包括 Alias 指令、mod_rewrite 等。 你可以用 Perl 书写自己的 URI Rewrite 处理程序并安装在这里。
在该步骤中,Apache2 还不知道 HTTP 请求是针对服务器上哪个文件或目录的,
因此该步骤的处理程序只能配置在 httpd.conf 的全局部分或者
PerlMapToStorageHandler
在本步骤中,Apache2 将确定 URI 对应服务器上的哪个目录或文件。
在该步骤中,Apache2 还不知道 HTTP 请求是针对服务器上哪个文件或目录的,
因此该步骤的处理程序只能配置在 httpd.conf 的全局部分或者
PerlHeaderParserHandler
从本步骤起,HTTP请求对应的服务器资源的位置已经确定,因此本步骤之后的所有处理程序
都可以使用在
这个步骤是 HTTP请求确定位置之后执行的第一个步骤,其功能与 PerlPostReadRequestHandler 十分相似。 PerlPostReadRequestHandler 中能够使用的程序可以原样安装到这个步骤。 甚至你可以通过检查请求的 HEADER 来扩充 HTTP 协议。
PerlAccessHandler
本步骤主要用于访问控制。Apache2 的默认动作是检查请求者的 IP 地址, 若不满足条件则拒绝访问。
PerlAuthenHandler
本步骤用于用户认证,即检查访问者的用户名和密码。
PerlAuthzHandler
与 PerlAuthenHandler 相似。
PerlTypeHandler
本步骤用于决定请求的 MIME 类型。
PerlFixupHandler
这是生成请求前的最后一个步骤,你可以在这里进行最后一些处理,例如设置环境变量等。
PerlResponseHandler
该步骤用于生成应答。
PerlLogHandler
该步骤用于记录日志。
PerlCleanupHandler
Apache2 默认处理中没有这一步骤,该步骤是 mod_perl 特有的。你可以在此进行一些收尾工作, 例如删除临时文件等。