简单理解mod_perl中的配置指令
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 配置的一些指令