Nginx

ngx_http_perl_module

ngx_http_perl_module模块

  • 已知的问题

  • 示例配置

  • 指令

  • perl

  • perl_modules

  • perl_require

  • perl_set

  • 从SSI调用Perl

  • $ r请求对象方法

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

该模块不是默认生成的,它应该使用--with-http_perl_module配置参数启用。

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

已知的问题

该模块是实验性的,适用于注意事项。

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

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

请注意,在使用new -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 module :: function |'sub {...}';
默认:
语境:位置,limit_except

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

句法:perl_modules路径;
默认:
语境:HTTP

为Perl模块设置额外的路径。

句法:perl_require模块;
默认:
语境:HTTP

定义每次重新配置期间将要加载的模块的名称。有几个perl_require指令可以存在。

句法: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相对应的文件名。如果请求中没有主体,则返回0。如果存在主体,则为请求设置指定的处理程序,并返回1。读取请求体后,nginx将调用指定的处理程序。请注意,处理函数应该通过引用传递。例:$r->has_request_body(handler)

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指示nginx放弃请求主体。 $ r-> header_in(field)返回指定的客户端请求头字段的值。 $ r-> header_only决定整个响应还是只有它的头部应该被发送到客户端。 $ r-> header_out(field,value)为指定的响应头字段设置一个值。 $ r-> internal_redirect(uri)执行内部重定向到指定的uri。 在Perl处理程序执行完成后发生实际的重定向。

目前不支持重定向到指定位置。

$ 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->状态(代码)设置响应代码。 $ r-> sleep(毫秒,处理程序)设置指定的处理程序并停止指定时间的请求处理。与此同时,nginx继续处理其他请求。经过指定的时间后,nginx将调用已安装的处理程序。请注意,处理函数应该通过引用传递。为了在处理程序之间传递数据,应该使用$ 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(文本)解码以“%XX”格式编码的文本。 $ r-> uri返回一个请求URI。 $ r-> variable(name [,value])返回或设置指定变量的值。 每个请求的变量都是本地的。