简单理解mod_perl中的配置指令
2013-08-04 21:32:48 阿炯

本站赞助商链接,请多关照。 mod_perl与Perl提供给Apache内部解析perl代码的api接口,它提供了一套使用perl管理控制apache的应用接口,与perl的web代码不同,它可以辅助以提供更高级的特性,比如修改http头信息、应用层上的数据验证等。

mod_perl是个Apache模块,它巧妙的将Perl程序语言封装在Apache web服务器内。在mod_perl下,CGI脚本比平常运行快50倍。另外,可将数据库与web服务器集成在一起,用Perl编写Apache模块,在Apache的配置文件里插入Perl代码,甚至以server-side include方式使用Perl。在mod_perl下,Apache不仅是一个web服务器,而变成了一个功能完善的程序平台。

下面简单介绍一些它的关键配置语句

PerlModule

PerlModule Foo::Bar 就等同于 Perl 的 require Foo::Bar;
有点不同的可能是可以接受多个参数:PerlModule Apache::DBI CGI DBD::Mysql
如果你需要传递 qw/foo bar/ 给 Foo::Bar 的话,一般将它写入一个 pl 文件里,然后用 PerlRequire 载入它。如 startup.pl:
use Apache2::Const -compile => ':common';
use APR::Const -compile => ':common';
...

PerlRequire

在 1.0 中在这是常用句,用于载入一个 Perl 文件。由于它不能控制代码的运行时间,所以在 2.0 中被 PerlConfigRequire 和 PerlPostConfigRequire 所细分。

PerlConfigRequire 是碰到该语句立即运行该参数文件,而 PerlPostConfigRequire 是在服务器运行的最后阶段才运行。
一般而言,PerlPostConfigRequire 才是我们所要的。
PerlRequire "C:/Apache2/conf/startup.pl"

SetHandler

有两种类型,一种是 modperl, 另一种是 perl-script

perl-script
这是更为常见的类型的。它的默认配置为:

如果没有 PerlOptions -GlobalRequest 的话,PerlOptions +GlobalRequest 将在 PerlResponseHandler 阶段起作用。
如果没有 PerlOptions -SetupEnv 的话,默认将是 PerlOptions +SetupEnv
将 STDIN 和 STDOUT 与 $r 绑定,这样就能使用 CORE::print() 来输出到 STDOUT 或从 STDIN 中读取。而 modperl 类型必须使用 $r->puts() 这样的函数来输出。
%ENV, @INC, $/, STDOUT 的 $| 和 END 块这种特殊变量将在调用 response handler 之前保存而在之后将恢复。
任何加到 %ENV 的变量将传递给 subprocess_env 表,而后我们可以在接下来的 PerlLogHandler 和 PerlCleanupHandler 阶段中通过 r->subprocess_env 来获取。

modperl
这种类型下你只能调用 Perl*Handler 里的函数。如果你不需要以上 perl-script 的用途的话,使用 modperl 会带来更好的性能。
当配置成 PerlOptions +SetupEnv 时, modperl 类型只配置如下环境变量:$ENV{MOD_PERL}(总是存在) $ENV{PATH} 和 $ENV{TZ} (如果你在命令行/shell 或 httpd.conf 里设置了它们)。这时候你如果想传递一些配置变量的话一定要使用 PerlSetVar 和 PerlAddVar 而不是 PerlSetEnv 和 PerlPassEnv. 举一个例子:
 #httpd.conf
<Location /print_env2>
   SetHandler modperl
   PerlResponseHandler Apache2::VarTest
   PerlSetVar VarTest VarTestValue
</Location>
接下来在 Apache2::VarTest::handler() 里你可以通过
$r->dir_config('VarTest');

它们之间的不同点:
perl-script 可以用 print, 而 modperl 只能用 $r->print
perl-script 默认就用 PerlOptions +SetupEnv, 而 modperl 下一定要显性调用 $r->subprocess_env; 或开启 PerlOptions +SetupEnv

PerlOption

提供 mod_perl 的编译选项。
如果在运行时需要确定某些选项是否已经启用,可使用 $r->is_perl_option_enabled($option) 或 $s->is_perl_option_enabled($option) 来判断。
一般允许用 +, 禁止用 -

AutoLoad

大致是自动加载的意思。比如开启 PerlOptions +Autoload 后,当使用 PerlResponseHandler Apache::Magick 时前面就不需要先明显的加载 PerlModule Apache::Magick 模块。而是碰到后会自动加载。

ParseHeaders

它与 mod_perl 1.0 中的 PerlSendHeader On 功能一样。
如果你在代码中使用 print "Content-type: text/html\n\n"; 的话将这个 PerlOption 开起来。它会将这句话自动转为调用 send_http_header
这一般在 ModPerl::Registry 中用得比较多。因为 ModPerl::Registry 使用的旧代码都是这么输出的。
<Location /perl>
  SetHandler perl-script
  PerlResponseHandler ModPerl::Registry
  Options +ExecCGI
  PerlOptions +ParseHeaders
  PerlOptions +SetupEnv
</Location>

PerlSwitches

Switch 的意思是开关。如我们在命令行时会使用 perl -e 这里的 -e 就是一个 switch.
一般而言它最大的用途就是修改 @INC, (我们也可以在 startup.pl 里修改,然后 PerlRequire)用 PerlSwitches 的好处就是黏合力更强一些。如:
PerlSwitches -I/var/www/MyApp/lib
它的作用还类似于这么写:
<Perl>
    use lib qw(/var/www/MyApp/lib);
</Perl>
这三种办法都是可以的。

PerlResponseHandler

这个阶段是用于创建回复的。这毫无疑问是 mod_perl 中最最重要的阶段。
而且这个指令是 mod_perl 中必须的两个指令之一。
<Location /hello>
  SetHandler perl-script
  PerlResponseHandler Apache2::Hello
</Location>
哪个指令都能少,就这两个是必须的。它指出了在 ResponseHandler 阶段所委托的模块。

配置示例
 </Directory>
 <Directory /var/www/pridns.freeoa.net/>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride None
  <Files ~ "\.(pl|psp)$">
   SetHandler perl-script
   PerlResponseHandler ModPerl::PerlRun
   Options +ExecCGI
   PerlSendHeader On
   PerlSetupEnv On
   PerlOptions +GlobalRequest
   PerlOptions +ParseHeaders
  </Files>
  Order allow,deny
  allow from all
 </Directory>

在<Files>段,其实只要有两个指令即可,其它都不是必要的。
 SetHandler perl-script[modperl]
 PerlResponseHandler ModPerl::PerlRun[ModPerl::Registry]

推荐使用中括号中的配置写法,因为它们的处理效率更高。

文档参考
mod_perl Introducing
mod_perl 编程指南 第6章
mod_perl 配置的一些指令