1

我有一个 mod_perl 的 HTTP 请求处理程序,它需要%ENV在模块加载时从 读取环境变量。PerlSetEnv使用指令将环境变量从 Apache 配置传递到 mod_perl 。

这工作得很好,直到我们出于性能原因将 Apache 配置更改为在启动时自动加载处理程序。当模块像这样自动PerlSetEnv加载时,在模块加载时不会生效,我们需要的变量只能%ENV在处理程序方法内部的请求时获得。

有没有办法继续使用 AutoLoad,但仍然在 Apache 配置中设置一个环境变量,该变量在%ENV模块加载时在 Perl 中可用?

最小的例子:

这是一个精简的测试用例来说明问题。

启用自动加载的 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 行为的同时取回它?

4

1 回答 1

2

啊,发布此问题 30 秒后,我找到了答案。谢谢橡皮鸭

将to 移到包含指令PerlSetEnv的块之前,它再次起作用!<Location>PerlResponseHandler

即像这样:

PerlSwitches -I/home/dbarr/modperl
PerlSetEnv TEST_PERLSETENV 'Does it work?'
<Location /perl>
    SetHandler modperl
    PerlResponseHandler +ModPerl::Test
    Allow from all
</Location>
于 2013-02-08T18:38:14.600 回答