|
| 1 | +# ngx_http_perl_module |
| 2 | + |
| 3 | +- [指令](#directives) |
| 4 | +- [已知问题](#issues) |
| 5 | + - [perl](#perl) |
| 6 | + - [perl_modules](#perl_modules) |
| 7 | + - [perl_require](#perl_require) |
| 8 | + - [perl_set](#perl_set) |
| 9 | +- [从 SSI 调用 Perl](#ssi) |
| 10 | +- [$r 请求对象方法](#methods) |
| 11 | + |
| 12 | +`ngx_http_perl_module` 模块用于在 Perl 中实现 location 和变量处理器,并将 Perl 调用插入到 SSI中。 |
| 13 | + |
| 14 | +此模块不是默认构建,可以在构建时使用 `--with-http_perl_module` 配置参数启用。 |
| 15 | + |
| 16 | +> 该模块需要 [Perl](https://www.perl.org/get.html) 5.6.1 或更高版本。C 编译器应该与用于构建Perl 的编译器兼容。 |
| 17 | +
|
| 18 | +<a id="issues"></a> |
| 19 | + |
| 20 | +## 已知的问题 |
| 21 | + |
| 22 | +该模块还处于实验阶段,以下是一些注意事项。 |
| 23 | + |
| 24 | +为了让 Perl 能在重新配置过程中重新编译已修改的模块,应使用 `-Dusemultiplicity=yes` 或 `-Dusethreads=yes` 参数来构建它。另外,为了让 Perl 在运行时泄漏更少的内存,应使用 `-Dusemymalloc=no` 参数来构建它。要检查已构建的 Perl 中这些参数值(在示例中已指定首选值),请运行: |
| 25 | + |
| 26 | +```nginx |
| 27 | +$ perl -V:usemultiplicity -V:usemymalloc |
| 28 | +usemultiplicity='define'; |
| 29 | +usemymalloc='n'; |
| 30 | +``` |
| 31 | + |
| 32 | +请注意,在使用新的 `-Dusemultiplicity=yes` 或 `-Dusethreads=yes` 参数重新构建 Perl 之后,所有二进制 Perl 模块也必须重新构建 — 否则它们将停止使用新的 Perl。 |
| 33 | + |
| 34 | +在每次重新配置后,master 进程和 worker 进程都有可能增加。如果 master 进程增加到不可接受的大小,则可以使用[实时升级](../../介绍/控制nginx.md#upgrade)流程而无需更改可执行文件。 |
| 35 | + |
| 36 | +当 Perl 模块执行长时间运行的操作时,例如解析域名、连接到另一台服务器或查询数据库时,将不会处理分配给当前 worker 进程的其他请求。因此,建议仅执行可预测且执行时间短的操作,例如访问本地文件系统。 |
| 37 | + |
| 38 | +<a id="example_configuration"></a> |
| 39 | + |
| 40 | +## 示例配置 |
| 41 | + |
| 42 | +```nginx |
| 43 | +http { |
| 44 | +
|
| 45 | + perl_modules perl/lib; |
| 46 | + perl_require hello.pm; |
| 47 | +
|
| 48 | + perl_set $msie6 ' |
| 49 | +
|
| 50 | + sub { |
| 51 | + my $r = shift; |
| 52 | + my $ua = $r->header_in("User-Agent"); |
| 53 | +
|
| 54 | + return "" if $ua =~ /Opera/; |
| 55 | + return "1" if $ua =~ / MSIE [6-9]\.\d+/; |
| 56 | + return ""; |
| 57 | + } |
| 58 | +
|
| 59 | + '; |
| 60 | +
|
| 61 | + server { |
| 62 | + location / { |
| 63 | + perl hello::handler; |
| 64 | + } |
| 65 | + } |
| 66 | +``` |
| 67 | + |
| 68 | +The perl/lib/hello.pm module: |
| 69 | + |
| 70 | +```pm |
| 71 | +package hello; |
| 72 | + |
| 73 | +use nginx; |
| 74 | + |
| 75 | +sub handler { |
| 76 | + my $r = shift; |
| 77 | + |
| 78 | + $r->send_http_header("text/html"); |
| 79 | + return OK if $r->header_only; |
| 80 | + |
| 81 | + $r->print("hello!\n<br/>"); |
| 82 | + |
| 83 | + if (-f $r->filename or -d _) { |
| 84 | + $r->print($r->uri, " exists!\n"); |
| 85 | + } |
| 86 | + |
| 87 | + return OK; |
| 88 | +} |
| 89 | + |
| 90 | +1; |
| 91 | +__END__ |
| 92 | +``` |
| 93 | +
|
| 94 | +
|
| 95 | +<a id="directives"></a> |
| 96 | +
|
| 97 | +## 指令 |
| 98 | +
|
| 99 | +### perl |
| 100 | +
|
| 101 | +|\-|说明| |
| 102 | +|------:|------| |
| 103 | +|**语法**|**perl** `module::function`|`'sub { ... }'`;| |
| 104 | +|**默认**|——| |
| 105 | +|**上下文**|location、limit_except| |
| 106 | +
|
| 107 | +给指定的 location 设置一个 Perl 处理程序。 |
| 108 | +
|
| 109 | +### perl_modules |
| 110 | +
|
| 111 | +|\-|说明| |
| 112 | +|------:|------| |
| 113 | +|**语法**|**perl_modules** `path`;| |
| 114 | +|**默认**|——| |
| 115 | +|**上下文**|http| |
| 116 | +
|
| 117 | +为 Perl 模块设置额外的路径。 |
| 118 | +
|
| 119 | +### perl_require |
| 120 | +
|
| 121 | +|\-|说明| |
| 122 | +|------:|------| |
| 123 | +|**语法**|**perl_require** `module`;| |
| 124 | +|**默认**|——| |
| 125 | +|**上下文**|http| |
| 126 | +
|
| 127 | +定义每次重新配置期间将要加载的模块的名称。可存在多个 `perl_require` 指令。 |
| 128 | +
|
| 129 | +### perl_set |
| 130 | +
|
| 131 | +|\-|说明| |
| 132 | +|------:|------| |
| 133 | +|**语法**|**perl_set** `$variable module::function`|`'sub { ... }'`;| |
| 134 | +|**默认**|——| |
| 135 | +|**上下文**|http| |
| 136 | +
|
| 137 | +为指定的变量安装一个 Perl 处理程序。 |
| 138 | +
|
| 139 | +<a id="ssi"></a> |
| 140 | +
|
| 141 | +## 从 SSI 调用 Perl |
| 142 | +
|
| 143 | +使用 SSI 命令调用 Perl 的格式如下: |
| 144 | +
|
| 145 | +``` |
| 146 | +<!--# perl sub="module::function" arg="parameter1" arg="parameter2" ... |
| 147 | +--> |
| 148 | +``` |
| 149 | +
|
| 150 | +<a id="methods"></a> |
| 151 | +
|
| 152 | +## $r 请求对象方法 |
| 153 | +
|
| 154 | +- `$r->args` |
| 155 | + |
| 156 | + 返回请求参数。 |
| 157 | +
|
| 158 | +- `$r->filename` |
| 159 | +
|
| 160 | + 返回与请求 URI 相对应的文件名。 |
| 161 | +
|
| 162 | +- `$r->has_request_body(handler)` |
| 163 | +
|
| 164 | + 如果请求中没有请求体,则返回 0。如果存在,则为请求设置指定的处理程序,并返回 1。在读取请求体后,nginx 将调用指定的处理程序。请注意,处理函数应该通过引用传递。例: |
| 165 | +
|
| 166 | + ```pm |
| 167 | + package hello; |
| 168 | +
|
| 169 | + use nginx; |
| 170 | +
|
| 171 | + sub handler { |
| 172 | + my $r = shift; |
| 173 | +
|
| 174 | + if ($r->request_method ne "POST") { |
| 175 | + return DECLINED; |
| 176 | + } |
| 177 | +
|
| 178 | + if ($r->has_request_body(\&post)) { |
| 179 | + return OK; |
| 180 | + } |
| 181 | +
|
| 182 | + return HTTP_BAD_REQUEST; |
| 183 | + } |
| 184 | +
|
| 185 | + sub post { |
| 186 | + my $r = shift; |
| 187 | +
|
| 188 | + $r->send_http_header; |
| 189 | +
|
| 190 | + $r->print("request_body: \"", $r->request_body, "\"<br/>"); |
| 191 | + $r->print("request_body_file: \"", $r->request_body_file, "\"<br/>\n"); |
| 192 | +
|
| 193 | + return OK; |
| 194 | + } |
| 195 | +
|
| 196 | + 1; |
| 197 | +
|
| 198 | + __END__ |
| 199 | + ``` |
| 200 | +
|
| 201 | +- `$r->allow_ranges` |
| 202 | +
|
| 203 | + 在发送响应时启用字节范围。 |
| 204 | +
|
| 205 | +- `$r->discard_request_body` |
| 206 | +
|
| 207 | + 指示 nginx 放弃请求体。 |
| 208 | +
|
| 209 | +- `$r->header_in(field)` |
| 210 | +
|
| 211 | + 返回指定的客户端请求头字段的值。 |
| 212 | +
|
| 213 | +- `$r->header_only` |
| 214 | +
|
| 215 | +确定整个响应还是仅将头部发送给客户端。 |
| 216 | +
|
| 217 | +- `$r->header_out(field, value)` |
| 218 | +
|
| 219 | + 为指定的响应头字段设置一个值。 |
| 220 | +
|
| 221 | +- `$r->internal_redirect(uri)` |
| 222 | +
|
| 223 | + 做一个内部重定向到指定的 uri。在 Perl 处理程序执行完成后重定向。 |
| 224 | + |
| 225 | + > 目前不支持重定向到具名 location。 |
| 226 | +
|
| 227 | +- `$r->log_error(errno, message)` |
| 228 | +
|
| 229 | + 将指定的消息写入 [error_log](ngx_core_module.md#error_log)。如果 `errno` 不为零,则错误码及其描述将被附加到消息中。 |
| 230 | +
|
| 231 | +- `$r->print(text, ...)` |
| 232 | + |
| 233 | + 将数据传递给客户端。 |
| 234 | +
|
| 235 | +- `$r->request_body` |
| 236 | +
|
| 237 | + 如果尚未将请求体写入临时文件中,则返回客户端请求体。为了确保客户端请求体在内存中,其大小应该由 [client_max_body_size](ngx_http_core_module.md#client_max_body_size) 来限制,并且应该使用 [client_body_buffer_size](ngx_http_core_module.md#client_body_buffer_size) 来设置足够的缓冲区大小。 |
| 238 | +
|
| 239 | +- `$r->request_body_file` |
| 240 | +
|
| 241 | + 客户端请求体返回文件的名称。处理完成后,该文件将被删除。要始终将请求体写入文件,应启用 [client_body_in_file_only](ngx_http_core_module.md#client_body_in_file_only)。 |
| 242 | +
|
| 243 | +- `$r->request_method` |
| 244 | +
|
| 245 | + 返回客户端请求的 HTTP 方法。 |
| 246 | +
|
| 247 | +- `$r->remote_addr` |
| 248 | +
|
| 249 | + 返回客户端 IP 地址。 |
| 250 | +
|
| 251 | +- `$r->flush` |
| 252 | +
|
| 253 | + 立即向客户端发送数据。 |
| 254 | +
|
| 255 | +- `$r->sendfile(name[, offset[, length]])` |
| 256 | + 将指定的文件内容发送到客户端。可选参数指定要传输的数据的初始偏移量(`offset`)和长度(`length`)。数据在 Perl 处理程序完成之后开始传输。 |
| 257 | +
|
| 258 | +- `$r->send_http_header([type])` |
| 259 | +
|
| 260 | + 将响应头发送给客户端。可选的 `type` 参数用于设置 **Content-Type** 响应头字段的值。如果该值为空字符串,则不会发送 **Content-Type** 头字段。 |
| 261 | +
|
| 262 | +- `$r->status(code)` |
| 263 | +
|
| 264 | + 设置响应状态码。 |
| 265 | +
|
| 266 | +- `$r->sleep(milliseconds, handler)` |
| 267 | +
|
| 268 | + 设置指定的处理程序(`handler`)和指定停止请求处理的时间(`milliseconds`)。在此期间,nginx 继续处理其他请求。在经过指定的时间后,nginx 将调用已安装的处理程序。请注意,处理函数应该通过引用传递。为了在处理程序之间传递数据,应使用 `$r->variable()`。例: |
| 269 | +
|
| 270 | + ```pm |
| 271 | + package hello; |
| 272 | +
|
| 273 | + use nginx; |
| 274 | +
|
| 275 | + sub handler { |
| 276 | + my $r = shift; |
| 277 | +
|
| 278 | + $r->discard_request_body; |
| 279 | + $r->variable("var", "OK"); |
| 280 | + $r->sleep(1000, \&next); |
| 281 | +
|
| 282 | + return OK; |
| 283 | + } |
| 284 | +
|
| 285 | + sub next { |
| 286 | + my $r = shift; |
| 287 | +
|
| 288 | + $r->send_http_header; |
| 289 | + $r->print($r->variable("var")); |
| 290 | +
|
| 291 | + return OK; |
| 292 | + } |
| 293 | +
|
| 294 | + 1; |
| 295 | +
|
| 296 | + __END__ |
| 297 | + ``` |
| 298 | +
|
| 299 | +- `$r->unescape(text)` |
| 300 | +
|
| 301 | + 解码 **%XX** 格式编码的文本。 |
| 302 | +
|
| 303 | +- `$r->uri` |
| 304 | +
|
| 305 | + 返回请求 URI。 |
| 306 | +
|
| 307 | +- `$r->variable(name[, value])` |
| 308 | +
|
| 309 | + 返回或设置指定变量的值。对于每个请求来说这些变量都是本地变量。 |
| 310 | +
|
| 311 | +## 原文档 |
| 312 | +
|
| 313 | +[http://nginx.org/en/docs/http/ngx_http_perl_module.html](http://nginx.org/en/docs/http/ngx_http_perl_module.html) |
0 commit comments