【发布时间】:2013-01-24 14:20:11
【问题描述】:
我有一个 mod_perl 的 HTTP 请求处理程序,它需要在模块加载时从 %ENV 读取一个环境变量。使用 PerlSetEnv 指令将环境变量从 Apache 配置传递到 mod_perl。
这工作正常,直到出于性能原因,我们在启动时将 Apache 配置更改为 AutoLoad 处理程序。像这样AutoLoaded模块时,PerlSetEnv在模块加载时不生效,我们需要的变量只能在handler方法内部请求时从%ENV获得。
有没有办法继续使用 AutoLoad,但仍然在 Apache 配置中设置一个环境变量,该变量在模块加载时在 Perl 的%ENV 中可用?
小例子:
这里有一个简化的测试用例来说明问题。
Apache 配置没有自动加载启用:
PerlSwitches -I/home/day/modperl
<Location /perl>
SetHandler modperl
PerlSetEnv TEST_PERLSETENV 'Does it work?'
PerlResponseHandler ModPerl::Test
Allow from all
</Location>
/home/day/modperl/ModPerl/Test.pm 的内容:
package ModPerl::Test;
use strict;
use warnings;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const qw(OK);
my %ENV_AT_MODULE_LOAD = %ENV; # Take a copy
sub handler {
my $r = shift;
$r->content_type('text/plain');
$r->print("ENV:\n");
foreach my $key (sort keys %ENV) {
$r->print(" $key: $ENV{$key}\n");
}
$r->print("ENV_AT_MODULE_LOAD:\n");
foreach my $key (sort keys %ENV_AT_MODULE_LOAD) {
$r->print(" $key: $ENV_AT_MODULE_LOAD{$key}\n");
}
return OK;
}
1;
当在浏览器中查看 localhost/perl 时,我看到了这个:
ENV:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TEST_PERLSETENV: Does it work?
ENV_AT_MODULE_LOAD:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TEST_PERLSETENV: Does it work?
万岁! TEST_PERLSETENV 在模块加载时可用,如我们所愿。
但是当我们更改 Apache 配置以启用 Autoload 时(通过像这样在 PerlResponseHandler 中使用 +):
PerlResponseHandler +ModPerl::Test
我得到以下输出:
ENV:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TEST_PERLSETENV: Does it work?
ENV_AT_MODULE_LOAD:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
嘘! TEST_PERLSETENV 在模块加载时不再可用 :( 如何在保持 AutoLoad 行为的同时取回它?
【问题讨论】: