Perl#

O módulo permite escrever manipuladores de localização e variável em Perl, bem como inserir chamadas Perl em SSI.

Ao compilar a partir do código-fonte, este módulo não é compilado por padrão; ele deve ser habilitado com a ‑‑with‑http_perl_module opção de compilação.

Em nossos repositórios, o módulo é compilado dinamicamente e está disponível como um pacote separado chamado angie-module-perl ou angie-pro-module-perl; ele pode ser carregado usando a diretiva load_module.

Nota

Este módulo requer Perl versão 5.6.1 ou superior. O compilador C deve ser compatível com aquele usado para compilar o Perl.

Problemas Conhecidos#

O módulo é experimental, então qualquer coisa é possível.

Para que o Perl recompile os módulos modificados durante a reconfiguração, ele deve ser compilado com os parâmetros -Dusemultiplicity=yes ou -Dusethreads=yes. Além disso, para fazer o Perl vazar menos memória em tempo de execução, ele deve ser compilado com o parâmetro -Dusemymalloc=no. Para verificar os valores desses parâmetros em um Perl já compilado (valores preferidos são especificados no exemplo), execute:

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

Note que após recompilar o Perl com os novos parâmetros -Dusemultiplicity=yes ou -Dusethreads=yes, todos os módulos Perl binários terão que ser recompilados também — eles simplesmente pararão de funcionar com o novo Perl.

Existe a possibilidade de que o processo principal e então os processos worker cresçam em tamanho após cada reconfiguração. Se o processo principal crescer para um tamanho inaceitável, o procedimento de atualização ao vivo pode ser aplicado sem alterar o arquivo executável.

Enquanto o módulo Perl está executando uma operação de longa duração, como resolver um nome de domínio, conectar a outro servidor ou consultar um banco de dados, outras requisições atribuídas ao processo worker atual não serão processadas. É portanto recomendado executar apenas operações que tenham tempo de execução previsível e curto, como acessar o sistema de arquivos local.

Exemplo de Configuração#

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;
        }
    }

O módulo 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__

Diretivas#

perl#

Sintaxe

perl módulo :: função | 'sub { ... }';

Padrão

Contexto

location, limit_except

Define um manipulador Perl para a localização especificada.

perl_modules#

Sintaxe

perl_modules caminho;

Padrão

Contexto

http

Define um caminho adicional para módulos Perl.

perl_require#

Sintaxe

perl_require módulo;

Padrão

Contexto

http

Define o nome de um módulo que será carregado durante cada reconfiguração. Várias diretivas perl_require podem estar presentes.

perl_set#

Sintaxe

perl_set $variável módulo :: função | 'sub { ... }';

Padrão

Contexto

http

Define um manipulador Perl para a variável especificada.

Chamando Perl a partir de SSI#

Um comando SSI chamando Perl tem o seguinte formato:

<!--# perl sub="módulo::função" arg="parâmetro1" arg="parâmetro2" ...
-->

Os Métodos do Objeto de Requisição $r#

$r->args#

Retorna os argumentos da requisição.

$r->filename#

Retorna um nome de arquivo correspondente ao URI da requisição.

$r->has_request_body (manipulador)#

Retorna 0 se não há corpo na requisição. Se há um corpo, o manipulador especificado é definido para a requisição e 1 é retornado. Após ler o corpo da requisição, o Angie chamará o manipulador especificado. Note que a função manipuladora deve ser passada por referência. Exemplo:

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#

Habilita o uso de intervalos de bytes ao enviar respostas.

$r->discard_request_body#

Instrui o Angie a descartar o corpo da requisição.

$r->header_in (campo)#

Retorna o valor do campo de cabeçalho da requisição do cliente especificado.

$r->header_only#

Determina se toda a resposta ou apenas seu cabeçalho deve ser enviado ao cliente.

$r->header_out (campo, valor)#

Define um valor para o campo de cabeçalho de resposta especificado.

$r->internal_redirect (uri)#

Faz um redirecionamento interno para o uri especificado. Um redirecionamento real acontece após a execução do manipulador Perl ser completada. O método aceita URIs com escape e suporta redirecionamentos para localizações nomeadas.

$r->log_error (errno, mensagem)#

Escreve a mensagem especificada no error_log. Se errno é diferente de zero, um código de erro e sua descrição serão anexados à mensagem.

$r->print (texto, ...)#

Passa dados para um cliente.

$r->request_body#

Retorna o corpo da requisição do cliente se ele não foi escrito em um arquivo temporário. Para garantir que o corpo da requisição do cliente esteja na memória, seu tamanho deve ser limitado por client_max_body_size, e um tamanho de buffer suficiente deve ser definido usando client_body_buffer_size.

$r->request_body_file#

Retorna o nome do arquivo com o corpo da requisição do cliente. Após o processamento, o arquivo deve ser removido. Para sempre escrever um corpo de requisição em um arquivo, client_body_in_file_only deve ser habilitado.

$r->request_method#

Retorna o método HTTP da requisição do cliente.

$r->remote_addr#

Retorna o endereço IP do cliente.

$r->flush#

Envia dados imediatamente para o cliente.

$r->sendfile (name [, offset [, length ]])#

Envia o conteúdo do arquivo especificado para o cliente. Parâmetros opcionais especificam o deslocamento inicial e o comprimento dos dados a serem transmitidos. A transmissão real dos dados acontece após o manipulador Perl ter sido concluído.

$r->send_http_header ([type])#

Envia o cabeçalho de resposta para o cliente. O parâmetro opcional type define o valor do campo de cabeçalho de resposta Content-Type. Se o valor for uma string vazia, o campo de cabeçalho Content-Type não será enviado.

$r->status (code)#

Define um código de resposta.

$r->sleep (milliseconds, handler)#

Define o manipulador especificado e interrompe o processamento da requisição pelo tempo especificado. Enquanto isso, o Angie continua a processar outras requisições. Após o tempo especificado ter decorrido, o Angie chamará o manipulador instalado. Note que a função manipuladora deve ser passada por referência. Para passar dados entre manipuladores, $r‑>variable() deve ser usado. Exemplo:

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 (text)#

Decodifica um texto codificado na forma "%XX".

$r->uri#

Retorna um URI de requisição.

$r->variable (name [, value ])#

Retorna ou define o valor da variável especificada. Variáveis são locais para cada requisição.