嵌入式Perl模块(Embedded Perl)


·摘要

这个模块允许nginx使用SSI调用perl或直接执行perl

在编译时安装模块

默认这个模块为不可用,如果想使用这个模块,则必须在编译时指定--with-http_perl_module。
系统必须有Perl 5.6.1以上版本。

已知的问题

这个模块并不完善,因此可能会出现一些bug如:
1、如果perl脚本执行延时操作,(如dns解析,数据库查询等。)那么运行perl脚本的工作进程将一直处于完全占用状态,因此需要perl脚本尽量简短,并且很快执行。
2、nginx在重载配置文件时可能导致内存溢出(通过'kill -HUP <pid>>')
实例:
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;
    }
  }
}
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/>");
  $r->rflush;
 
  if (-f $r->filename or -d _) {
    $r->print($r->uri, " exists!\n");
  }
 
  return OK;
}
 
1;
__END__

·指令

perl

语法:perl module::function | 'sub {...}'
默认值:no
使用字段:location
指出一个location中所要使用的perl函数。

perl_modules

语法:perl_modules path
默认值:no
使用字段:http
为perl模块增加额外的路径,0.6.7版本以后这个路径与nginx.conf所在目录有关,而不是编译时指定的perfix目录。

perl_require

语法:perl_require module
默认值:no
使用字段:http
可以指定多个perl_require指令。

perl_set

语法:perl_set module::function | 'sub {...}'
默认值:no
使用字段:http
未知。

·SSI中调用perl。

指令格式如下:
<!- # perl sub="module::function" arg="parameter1" arg="parameter2"... >
对象$r的请求方法:
·$r->args - 返回请求的参数。
·$r->discard_request_body - 告诉nginx忽略请求主体。
·$r->filename - 更具URI的请求返回文件名。
$r->has_request_body(function) - 如果没有请求主体,返回0,但是如果请求主体存在,那么建立传递的函数并返回1,在程序的最后,nginx将调用指定的处理器。例如:
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 400;
}
 
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->header_in(header) - 检索一个HTTP请求头。
·$r->header_only - 在我们只需要返回一个应答头时为真。
·$r->header_out(header, value) - 设置一个应答头。
·$r->internal_redirect(uri) - 使内部重定向到指定的URI,重定向仅在完成perl脚本后发生。
·$r->print(args, ...) - 为客户端传送数据。
·$r->request_body - 在请求主体未记录到一个临时文件时为客户返回这个请求主体。为了使客户端的请求主体保证在内存里,可以使用client_max_body_size限制它的大小并且为其使用的缓冲区指定足够的空间。
·$r->request_body_file - 返回存储客户端需求主体的文件名,这个文件必须在请求完成后被删除,以便请求主体始终能写入文件,需要指定client_body_in_file_only为on。
·$r->request_method - 返回请求的HTTP动作。
·$r->remote_addr - 返回客户端的IP地址。
·$r->rflush - 立即传送数据到客户端。
·$r->sendfile(file [, displacement [, length ] ) - 传送给客户端指定文件的内容,可选的参数表明只传送数据的偏移量与长度,精确的传递仅在perl脚本执行完毕后生效。
·$r->send_http_header(type) - 为应答增加头部,可选参数“type”在应答标题中确定Content-Type的值。
·$r->sleep(milliseconds, handler) - 设置为请求在指定的时间使用指定的处理方法和停止处理,在此期间nginx将继续处理其他的请求,超过指定的时间后,nginx将运行安装的处理方法,注意你需要为处理方法通过一个reference,在处理器间转发数据你可以使用$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->status(code) - 设置HTTP应答代码。
·$r->unescape(text) - 以%XX的形式编码text。
·$r->uri - 返回请求的URI。
·$r->variable(name[, value]) - 返回一个指定变量的值,变量为每个查询的局部变量。

·参考文档

Original Documentation
Nginx Embedded Perl Module

前进->FLV模块(FLV)