Mercurial > hg > nginx-site
view xml/ru/docs/http/ngx_http_perl_module.xml @ 343:46e75d7ae0e7
replace apt-key example with a simpler one
author | Sergey Budnevitch <sb@waeme.net> |
---|---|
date | Mon, 23 Jan 2012 14:49:31 +0000 |
parents | 3824ca9f1f72 |
children | c640e00858ed |
line wrap: on
line source
<?xml version="1.0"?> <!DOCTYPE module SYSTEM "../../../../dtd/module.dtd"> <module name="Директивы модуля ngx_http_perl_module" link="/ru/docs/http/ngx_http_perl_module.html" lang="ru"> <section id="summary"> <para> Модуль ngx_http_perl_module позволяет работать со встроенным в nginx perl'ом: делать обработчики location и переменной и вставлять вызовы perl'а в SSI. По умолчанию модуль не собирается, нужно разрешить его сборку при конфигурировании параметром <literal>--with-http_perl_module</literal>. Для сборки необходим perl версии 5.6.1 и выше, и компилятор C, совместимый с тем, которым был собран perl. </para> </section> <section name="Известные проблемы" id="bugs"> <para> Модуль экспериментальный, поэтому возможно всё. </para> <para> Для того, чтобы во время переконфигурации perl перекомпилировал изменённые модули, его нужно собрать с параметрами -Dusemultiplicity=yes или -Dusethreads=yes. Кроме того, чтобы во время работы perl меньше терял память, его нужно собрать с параметром -Dusemymalloc=no. Узнать значения этих параметров у уже собранного perl'а можно так (в примерах приведены желаемые значения параметров): <example> $perl -V:usemultiplicity usemultiplicity='define'; $perl -V:usemymalloc usemymalloc='n'; </example> </para> <para> Необходимо учитывать, что после пересборки perl'а с новыми параметрами -Dusemultiplicity=yes или -Dusethreads=yes придётся также переустановить и все бинарные perl'овые модули — они просто перестанут работать с новым perl'ом. </para> <para> Возможно, основной процесс, а вслед за ним и рабочие процессы, будет увеличиваться в размерах при каждой переконфигурации. Когда основной процесс вырастет до неприемлемых размеров, можно воспользоваться процедурой <link doc="../control.html" id="upgrade">обновления сервера на лету</link>, не меняя при этом сам исполняемый файл. </para> <para> Если perl'овый модуль выполняет длительную операцию, например, определяет адрес по имени, соединяется с другим сервером, делает запрос к базе данных, то на это время все остальные запросы данного рабочего процесса не будут обрабатываться. Поэтому рекомендуется ограничиться операциями, время исполнения которых короткое и предсказуемое, например, обращение к локальной файловой системе. </para> <para> <note> <para> Нижеописанные проблемы относятся только к версиям nignx'а до 0.6.22. </para> <para> Данные, возвращаемые методами объекта запроса $r, имеют только текстовое значение, причём само значение хранится в памяти, выделяемой не 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> </para> <para> Так как строки внутри nginx'а в большинстве случаев хранятся без завершающего нуля, то они в таком же виде возвращаются методами объекта запроса $r (исключения составляют методы $r->filename и $r->request_body_file). Поэтому такие значения нельзя использовать в качестве имени файла и тому подобном. Обход такой же, как и предыдущей ситуации — присвоение значения переменной (при этом происходит копирование данных и добавление необходимого нуля) или же использование в выражении, например: <example> open FILE, '/path/' . $r->variable('name'); </example> </para> </note> </para> </section> <section name="Пример конфигурации" id="example"> <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> модуль perl/lib/hello.pm: <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 name="Директивы" id="directives"> <directive name="perl"> <syntax><value>модуль::функция|'sub { ... }'</value></syntax> <default/> <context>location, limit_except</context> <para> Директива устанавливает обработчик для данного 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> Директива задаёт имя модуля, который будет подгружаться при каждой переконфигурации. Директив может быть несколько. </para> </directive> <directive name="perl_set"> <syntax><value>$переменная</value> <value>модуль::функция|'sub { ... }'</value> </syntax> <default/> <context>http</context> <para> Директива устанавливает обработчик переменной. </para> </directive> </section> <section name="Вызов perl'а из SSI" id="ssi"> <para> Формат команды следующий: <example> <!--# perl sub="модуль::функция" arg="параметр1" arg="параметр2" ... --> </example> </para> </section> <section name="Методы объекта запроса $r" id="methods"> <para> <list type="bullet"> <listitem> <emphasis>$r->args</emphasis> — метод возвращает аргументы запроса. </listitem> <listitem> <emphasis>$r->filename</emphasis> — метод возвращает имя файла, соответствующее URI запроса. </listitem> <listitem> <emphasis>$r->has_request_body(обработчик)</emphasis> — метод возвращает 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> </listitem> <listitem> <emphasis>$r->allow_ranges</emphasis> — метод разрешает использовать byte ranges при передаче ответа. </listitem> <listitem> <emphasis>$r->discard_request_body</emphasis> — метод указывает nginx'у игнорировать тело запроса. </listitem> <listitem> <emphasis>$r->header_in(строка)</emphasis> — метод возвращает значение заданной строки в заголовке запроса клиента. </listitem> <listitem> <emphasis>$r->header_only</emphasis> — метод определяет, нужно ли передавать клиенту только заголовок ответа или весь ответ. </listitem> <listitem> <emphasis>$r->header_out(строка, значение)</emphasis> — метод устанавливает значение для заданной строки в заголовке ответа. </listitem> <listitem> <emphasis>$r->internal_redirect(uri)</emphasis> — метод делает внутреннее перенаправление на указанный uri. Перенаправление происходит уже после завершения perl'ового обработчика. </listitem> <listitem> <emphasis>$r->print(текст, ...)</emphasis> — метод передаёт клиенту данные. </listitem> <listitem> <emphasis>$r->request_body</emphasis> — метод возвращает тело запроса клиента при условии, что тело не записано во временный файл. Для того, чтобы тело запроса клиента гарантировано находилось в памяти, нужно ограничить его размер с помощью <link doc="ngx_http_core_module.xml" id="client_max_body_size"/> и задать достаточной размер для буфера <link doc="ngx_http_core_module.xml" id="client_body_buffer_size"/>. </listitem> <listitem> <emphasis>$r->request_body_file</emphasis> — метод возвращает имя файла, в котором хранится тело запроса клиента. По завершению работы файл необходимо удалить. Для того, чтобы тело запроса клиента всегда записывалось в файл, нужно указать <link doc="ngx_http_core_module.xml" id="client_body_in_file_only">client_body_in_file_only on</link>. </listitem> <listitem> <emphasis>$r->request_method</emphasis> — метод возвращает HTTP метод запроса клиента. </listitem> <listitem> <emphasis>$r->remote_addr</emphasis> — метод возвращает IP-адрес клиента. </listitem> <listitem> <emphasis>$r->flush</emphasis> — метод немедленно передаёт данные клиенту. </listitem> <listitem> <emphasis>$r->sendfile(имя [, смещение [, длина]])</emphasis> — метод передаёт клиенту содержимое указанного файла. Необязательные параметры указывают начальное смещение и длину передаваемых данных. Собственно передача данных происходит уже после завершения perl'ового обработчика. Необходимо учитывать, что при использовании этого метода в подзапросе и директиве <link doc="ngx_http_core_module.xml" id="sendfile">sendfile on</link> содержимое файла не будет проходить через <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> фильтры. </listitem> <listitem> <emphasis>$r->send_http_header(<value>тип</value>)</emphasis> — метод передаёт клиенту заголовок ответа. Необязательный параметр "тип" устанавливает значение строки "Content-Type" в заголовке ответа. Пустая строка в качестве типа запрещает строку "Content-Type". </listitem> <listitem> <emphasis>$r->status(код)</emphasis> — метод устанавливает код ответа. </listitem> <listitem> <emphasis>$r->sleep(миллисекунды, обработчик)</emphasis> — метод устанавливает указанный обработчик и останавливает обработку запроса на заданное время. nginx в это время продолжает обрабатывать другие запросы. По истечении указанного времени nginx вызовет установленный обработчик. Обратите внимание, что нужно передавать ссылку на функцию обработчика. Для передачи данных между обработчиками следует использовать $r->variable(). Пример использования: <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> </listitem> <listitem> <emphasis>$r->unescape(текст)</emphasis> — метод декодирует текст, заданный в виде %XX. </listitem> <listitem> <emphasis>$r->uri</emphasis> — метод возвращает URI запроса. </listitem> <listitem> <emphasis>$r->variable(имя [, значение])</emphasis> — метод возвращает или устанавливает значение указанной переменной. Переменные локальны для каждого запроса. </listitem> </list> </para> </section> </module>