Perl#

该模块用于在 Perl 中实现位置和变量处理器,并将 Perl 调用插入到 SSI 中。

从源代码构建 时, 该模块默认不构建; 应通过 ‑‑with‑http_perl_module 构建选项 启用。

在我们的代码库中,该模块是 动态构建 并作为一个名为 angie-module-perlangie-pro-module-perl 的单独软件包提供。

重要

此模块需要 Perl 版本 5.6.1 或更高版本。C 编译器应与用于构建 Perl 的编译器兼容。

已知问题#

该模块是实验性的,使用者需自担风险。

为了让 Perl 在重新配置期间重新编译修改过的模块, 应使用 -Dusemultiplicity=yes-Dusethreads=yes 参数构建。此外,为了减少 Perl 在运行时的内存泄漏,应使用 -Dusemymalloc=no 参数进行构建。要检查已构建 Perl 的这些参数的值(示例中指定了首选值),请运行:

$ perl -V:usemultiplicity -V:usemymalloc |br|
usemultiplicity='define'; |br|
usemymalloc='n';

请注意,在使用新的 -Dusemultiplicity=yes-Dusethreads=yes 参数重新构建 Perl 后,所有二进制 Perl 模块也必须重新构建——它们将不再与新的 Perl 兼容。

主进程和工作进程的大小在每次重新配置后可能会增长。如果主进程增长到不可接受的大小,可以在不更改可执行文件的情况下应用 实时升级 程序。

当 Perl 模块执行长时间运行的操作时,例如解析域名、连接到其他服务器或查询数据库,分配给当前工作进程的其他请求将不会被处理。因此,建议仅执行具有可预测且短执行时间的操作,例如访问本地文件系统。

配置示例#

http {

    perl_modules perl/lib;
    perl_require hello.pm;

    perl_set $msie6 '

        sub {
            my $r = shift;
            my $ua = $r->header_in("User-Agent");

            return "" if $ua =~ /Opera/;
            return "1" if $ua =~ / MSIE [6-9]\.\d+/;
            return "";
        }

    ';

    server {
        location / {
            perl hello::handler;
        }
    }

perl/lib/hello.pm 模块:

package hello;

use nginx;

sub handler {
    my $r = shift;

    $r->send_http_header("text/html");
    return OK if $r->header_only;

    $r->print("hello!\n<br/>");

    if (-f $r->filename or -d _) {
        $r->print($r->uri, " exists!\n");
    }

    return OK;
}

1;
__END__

指令#

perl#

语法

perl module :: function | 'sub { ... }';

默认

上下文

location, limit_except

为给定位置设置一个 Perl 处理器。

perl_modules#

语法

perl_modules path;

默认

上下文

http

为 Perl 模块设置额外路径。

perl_require#

语法

perl_require module;

默认

上下文

http

定义将在每次重新配置时加载的模块名称。可以存在多个 perl_require 指令。

perl_set#

语法

perl_set $variable module :: function | 'sub { ... }';

默认

上下文

http

为指定变量安装一个 Perl 处理器。

从 SSI 调用 Perl#

调用 Perl 的 SSI 命令具有以下格式:

<!--# perl sub="module::function" arg="parameter1" arg="parameter2" ...
-->

$r 请求对象方法#

$r->args#

返回请求参数。

$r->filename#

返回与请求 URI 对应的文件名。

$r->has_request_body (handler)#

如果请求中没有主体,则返回 0。如果有主体,则为请求设置指定的处理器并返回 1。在读取请求主体后,Angie 将调用指定的处理器。请注意,处理器函数应以引用方式传递。示例:

package hello;

use nginx;

sub handler {
    my $r = shift;

    if ($r->request_method ne "POST") {
        return DECLINED;
    }

    if ($r->has_request_body(\&post)) {
        return OK;
    }

    return HTTP_BAD_REQUEST;
}

sub post {
    my $r = shift;

    $r->send_http_header;

    $r->print("request_body: \"", $r->request_body, "\"<br/>");
    $r->print("request_body_file: \"", $r->request_body_file, "\"<br/>\n");

    return OK;
}

1;

__END__

$r->allow_ranges#

启用在发送响应时使用字节范围。

$r->discard_request_body#

指示 Angie 丢弃请求主体。

$r->header_in (field)#

返回指定客户端请求头字段的值。

$r->header_only#

确定是否应将整个响应或仅其头部发送到客户端。

$r->header_out (field, value)#

为指定响应头字段设置一个值。

$r->internal_redirect (uri)#

对指定的 uri 进行内部重定向。实际重定向在 Perl 处理器执行完成后发生。该方法接受转义的 URI,并支持重定向到 命名位置

$r->log_error (errno, message)#

将指定消息写入 error_log。如果 errno 非零,错误代码及其描述将附加到消息中。

$r->print (text, ...)#

将数据传递给客户端。

$r->request_body#

如果客户端请求主体尚未写入临时文件,则返回客户端请求主体。为了确保客户端请求主体在内存中,其大小应通过 client_max_body_size 限制,并使用 client_body_buffer_size 设置足够的缓冲区大小。

$r->request_body_file#

返回包含客户端请求主体的文件名称。处理后,应删除该文件。要始终将请求主体写入文件,应启用 client_body_in_file_only

$r->request_method#

返回客户端请求的 HTTP 方法。

$r->remote_addr#

返回客户端 IP 地址。

$r->flush#

立即将数据发送给客户端。

$r->sendfile (name [, offset [, length ]])#

将指定文件内容发送给客户端。可选参数指定数据传输的初始偏移量和长度。实际数据传输在 Perl 处理器完成后发生。

$r->send_http_header ([type])#

将响应头发送给客户端。可选的类型参数设置 "Content-Type" 响应头字段的值。如果值为空字符串,则将不发送 "Content-Type" 头字段。

$r->status (code)#

设置响应代码。

$r->sleep (milliseconds, handler)#

设置指定的处理器,并在指定时间内停止请求处理。在此期间,Angie 继续处理其他请求。在指定时间经过后,Angie 将调用安装的处理器。请注意,处理器函数应以引用方式传递。为了在处理器之间传递数据,应使用 $r‑>variable()。示例:

package hello;

use nginx;

sub handler {
    my $r = shift;

    $r->discard_request_body;
    $r->variable("var", "OK");
    $r->sleep(1000, \&next);

    return OK;
}

sub next {
    my $r = shift;

    $r->send_http_header;
    $r->print($r->variable("var"));

    return OK;
}

1;

__END__

$r->unescape (text)#

解码以 "%XX" 形式编码的文本。

$r->uri#

返回请求 URI。

$r->variable (name [, value ])#

返回或设置指定变量的值。变量对每个请求都是本地的。