Mercurial > hg > nginx-site
view xml/ru/docs/http/ngx_http_perl_module.xml @ 589:764fbac1b8b4
Added document revision.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Tue, 17 Jul 2012 05:02:15 +0000 |
parents | be54c443235a |
children | f0e3d07c66d8 |
line wrap: on
line source
<?xml version="1.0"?> <!-- Copyright (C) Igor Sysoev Copyright (C) Nginx, Inc. --> <!DOCTYPE module SYSTEM "../../../../dtd/module.dtd"> <module name="Модуль ngx_http_perl_module" link="/ru/docs/http/ngx_http_perl_module.html" lang="ru" rev="1"> <section id="summary"> <para> Модуль <literal>ngx_http_perl_module</literal> позволяет писать обработчики location и переменных на Perl, а также вставлять вызовы Perl в SSI. </para> <para> По умолчанию этот модуль не собирается, его сборку необходимо разрешить с помощью конфигурационного параметра <literal>--with-http_perl_module</literal>. <note> Для сборки этого модуля необходим Perl версии 5.6.1 и выше. Компилятор C должен быть совместим с тем, которым был собран Perl. </note> </para> </section> <section id="bugs" name="Известные проблемы"> <para> Модуль экспериментальный, поэтому возможно всё. </para> <para> Для того, чтобы во время переконфигурации Perl перекомпилировал изменённые модули, его нужно собрать с параметрами <literal>-Dusemultiplicity=yes</literal> или <literal>-Dusethreads=yes</literal>. Кроме того, чтобы во время работы Perl меньше терял память, его нужно собрать с параметром <literal>-Dusemymalloc=no</literal>. Узнать значения этих параметров у уже собранного Perl можно так (в примере приведены желаемые значения параметров): <example> $ perl -V:usemultiplicity -V:usemymalloc usemultiplicity='define'; usemymalloc='n'; </example> </para> <para> Необходимо учитывать, что после пересборки Perl с новыми параметрами <literal>-Dusemultiplicity=yes</literal> или <literal>-Dusethreads=yes</literal> придётся также пересобрать и все бинарные модули Perl — они просто перестанут работать с новым Perl. </para> <para> Возможно, основной процесс, а вслед за ним и рабочие процессы, будут увеличиваться в размерах при каждой переконфигурации. Когда основной процесс вырастет до неприемлемых размеров, можно воспользоваться процедурой <link doc="../control.xml" id="upgrade">обновления сервера на лету</link>, не меняя при этом сам исполняемый файл. </para> <para> Если модуль Perl выполняет длительную операцию, например, определяет адрес по имени, соединяется с другим сервером, делает запрос к базе данных, то на это время все остальные запросы, обслуживаемые данным рабочим процессом, не будут обрабатываться. Поэтому рекомендуется ограничиться операциями, время исполнения которых короткое и предсказуемое, например, обращение к локальной файловой системе. </para> <para> Нижеописанные проблемы относятся только к версиям nginx до 0.6.22. <note> Данные, возвращаемые методами объекта запроса <literal>$r</literal>, имеют только текстовое значение, причём само значение хранится в памяти, выделяемой не Perl, а nginx из собственных пулов. Это позволяет уменьшить число операций копирования в большинстве случаев, однако в некоторых ситуациях это приводит к ошибке, например, при попытке использования таких значений в численном контексте рабочий процесс выходит с ошибкой (FreeBSD): <example> nginx in realloc(): warning: pointer to wrong page Out of memory! Callback called exit. </example> или (Linux): <example> *** glibc detected *** realloc(): invalid pointer: ... *** Out of memory! Callback called exit. </example> Обход такой ситуации простой — нужно присвоить значение метода переменной, например, такой код <example> my $i = $r->variable('counter') + 1; </example> нужно заменить на <example> my $i = $r->variable('counter'); $i++; </example> </note> <note> Так как строки внутри nginx в большинстве случаев хранятся без завершающего нуля, то они в таком же виде возвращаются методами объекта запроса <literal>$r</literal> (исключения составляют методы <literal>$r->filename</literal> и <literal>$r->request_body_file</literal>). Поэтому такие значения нельзя использовать в качестве имени файла и тому подобном. Обход такой же, как и предыдущей ситуации — присвоение значения переменной (при этом происходит копирование данных и добавление необходимого нуля) или же использование в выражении, например: <example> open FILE, '/path/' . $r->variable('name'); </example> </note> </para> </section> <section id="example" name="Пример конфигурации"> <para> <example> 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; } } </example> </para> <para> Модуль <path>perl/lib/hello.pm</path>: <example> 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__ </example> </para> </section> <section id="directives" name="Директивы"> <directive name="perl"> <syntax><value>модуль</value>::<value>функция</value>|'sub { ... }'</syntax> <default/> <context>location</context> <context>limit_except</context> <para> Устанавливает обработчик Perl для данного location. </para> </directive> <directive name="perl_modules"> <syntax><value>путь</value></syntax> <default/> <context>http</context> <para> Задаёт дополнительный путь для модулей Perl. </para> </directive> <directive name="perl_require"> <syntax><value>модуль</value></syntax> <default/> <context>http</context> <para> Задаёт имя модуля, который будет подгружаться при каждой переконфигурации. Директив <literal>perl_require</literal> может быть несколько. </para> </directive> <directive name="perl_set"> <syntax> <value>$переменная</value> <value>модуль</value>::<value>функция</value>|'sub { ... }'</syntax> <default/> <context>http</context> <para> Устанавливает обработчик Perl для указанной переменной. </para> </directive> </section> <section id="ssi" name="Вызов Perl из SSI"> <para> Формат команды SSI с вызовом Perl следующий: <example> <!--# perl sub="<value>модуль</value>::<value>функция</value>" arg="<value>параметр1</value>" arg="<value>параметр2</value>" ... --> </example> </para> </section> <section id="methods" name="Методы объекта запроса $r"> <para> <list type="tag"> <tag-name><literal>$r->args</literal></tag-name> <tag-desc> возвращает аргументы запроса. </tag-desc> <tag-name><literal>$r->filename</literal></tag-name> <tag-desc> возвращает имя файла, соответствующее URI запроса. </tag-desc> <tag-name> <literal>$r->has_request_body(<value>обработчик</value>)</literal> </tag-name> <tag-desc> возвращает 0, если в запросе нет тела. Если же тело запроса есть, то устанавливается указанный обработчик и возвращается 1. По окончании чтения тела запроса nginx вызовет установленный обработчик. Обратите внимание, что нужно передавать ссылку на функцию обработчика. Пример: <example> package hello; use nginx; sub handler { my $r = shift; if ($r->request_method ne "POST") { return DECLINED; } if ($r->has_request_body(<emphasis>\&post</emphasis>)) { return OK; } return HTTP_BAD_REQUEST; } sub <emphasis>post</emphasis> { 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__ </example> </tag-desc> <tag-name><literal>$r->allow_ranges</literal></tag-name> <tag-desc> разрешает использовать диапазоны байт (byte ranges) при передаче ответа. </tag-desc> <tag-name><literal>$r->discard_request_body</literal></tag-name> <tag-desc> указывает nginx игнорировать тело запроса. </tag-desc> <tag-name><literal>$r->header_in(<value>поле</value>)</literal></tag-name> <tag-desc> возвращает значение заданного поля в заголовке запроса клиента. </tag-desc> <tag-name><literal>$r->header_only</literal></tag-name> <tag-desc> определяет, нужно ли передавать клиенту только заголовок ответа или весь ответ. </tag-desc> <tag-name> <literal>$r->header_out(<value>поле</value>, <value>значение</value>)</literal> </tag-name> <tag-desc> устанавливает значение для заданного поля в заголовке ответа. </tag-desc> <tag-name> <literal>$r->internal_redirect(<value>uri</value>)</literal> </tag-name> <tag-desc> делает внутреннее перенаправление на указанный <value>uri</value>. Перенаправление происходит уже после завершения обработчика Perl. </tag-desc> <tag-name><literal>$r->print(<value>текст</value>, ...)</literal></tag-name> <tag-desc> метод передаёт клиенту данные. </tag-desc> <tag-name><literal>$r->request_body</literal></tag-name> <tag-desc> возвращает тело запроса клиента при условии, что тело не записано во временный файл. Для того, чтобы тело запроса клиента гарантированно находилось в памяти, нужно ограничить его размер с помощью <link doc="ngx_http_core_module.xml" id="client_max_body_size"/> и задать достаточной размер для буфера <link doc="ngx_http_core_module.xml" id="client_body_buffer_size"/>. </tag-desc> <tag-name><literal>$r->request_body_file</literal></tag-name> <tag-desc> возвращает имя файла, в котором хранится тело запроса клиента. По завершению обработки файл необходимо удалить. Для того, чтобы тело запроса клиента всегда записывалось в файл, следует включить <link doc="ngx_http_core_module.xml" id="client_body_in_file_only"/>. </tag-desc> <tag-name><literal>$r->request_method</literal></tag-name> <tag-desc> возвращает HTTP-метод запроса клиента. </tag-desc> <tag-name><literal>$r->remote_addr</literal></tag-name> <tag-desc> возвращает IP-адрес клиента. </tag-desc> <tag-name><literal>$r->flush</literal></tag-name> <tag-desc> немедленно передаёт данные клиенту. </tag-desc> <tag-name> <literal>$r->sendfile(<value>имя</value>[, <value>смещение</value>[, <value>длина</value>]])</literal> </tag-name> <tag-desc> передаёт клиенту содержимое указанного файла. Необязательные параметры задают начальное смещение и длину передаваемых данных. Непосредственно передача данных происходит уже после завершения обработчика Perl. Необходимо учитывать, что при использовании этого метода в подзапросе и включённой директиве <link doc="ngx_http_core_module.xml" id="sendfile"/> содержимое файла не будет проходить через <link doc="ngx_http_gzip_module.xml">gzip</link>, <link doc="ngx_http_ssi_module.xml">SSI</link> и <link doc="ngx_http_charset_module.xml">charset</link> фильтры. </tag-desc> <tag-name> <literal>$r->send_http_header([<value>тип</value>])</literal> </tag-name> <tag-desc> передаёт клиенту заголовок ответа. Необязательный параметр <value>тип</value> устанавливает значение поля <header>Content-Type</header> в заголовке ответа. Пустая строка в качестве типа запрещает передачу поля <header>Content-Type</header>. </tag-desc> <tag-name><literal>$r->status(<value>код</value>)</literal></tag-name> <tag-desc> устанавливает код ответа. </tag-desc> <tag-name> <literal>$r->sleep(<value>миллисекунды</value>, <value>обработчик</value>)</literal> </tag-name> <tag-desc> устанавливает указанный обработчик и останавливает обработку запроса на заданное время. nginx в это время продолжает обрабатывать другие запросы. По истечении указанного времени nginx вызовет установленный обработчик. Обратите внимание, что нужно передавать ссылку на функцию обработчика. Для передачи данных между обработчиками следует использовать <literal>$r->variable()</literal>. Пример: <example> package hello; use nginx; sub handler { my $r = shift; $r->discard_request_body; $r->variable("var", "OK"); $r->sleep(1000, <emphasis>\&next</emphasis>); return OK; } sub <emphasis>next</emphasis> { my $r = shift; $r->send_http_header; $r->print($r->variable("var")); return OK; } 1; __END__ </example> </tag-desc> <tag-name><literal>$r->unescape(<value>текст</value>)</literal></tag-name> <tag-desc> декодирует текст, заданный в виде “%XX”. </tag-desc> <tag-name><literal>$r->uri</literal></tag-name> <tag-desc> возвращает URI запроса. </tag-desc> <tag-name> <literal>$r->variable(<value>имя</value>[, <value>значение</value>])</literal> </tag-name> <tag-desc> возвращает или устанавливает значение указанной переменной. Переменные локальны для каждого запроса. </tag-desc> </list> </para> </section> </module>