ngx_http_perl_module 模組

已知問題
範例設定
指令
     perl
     perl_modules
     perl_require
     perl_set
從 SSI 呼叫 Perl
$r 請求物件方法

ngx_http_perl_module 模組用於在 Perl 中實作位置和變數處理程式,並將 Perl 呼叫插入 SSI。

此模組預設不會建置,應使用 --with-http_perl_module 設定參數啟用。

此模組需要 5.6.1 或更高版本的 Perl。C 編譯器應與用於建置 Perl 的編譯器相容。

已知問題

此模組為實驗性模組,請使用者自行承擔風險。

為了讓 Perl 在重新設定期間重新編譯修改後的模組,應使用 -Dusemultiplicity=yes-Dusethreads=yes 參數建置。此外,為了讓 Perl 在執行階段減少記憶體洩漏,應使用 -Dusemymalloc=no 參數建置。若要檢查已建置的 Perl 中這些參數的值(範例中指定了偏好的值),請執行

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

請注意,在使用新的 -Dusemultiplicity=yes-Dusethreads=yes 參數重建 Perl 之後,所有二進位 Perl 模組也必須重建,它們將無法使用新的 Perl。

主程序,然後是工作程序,有可能在每次重新設定後大小都會增加。如果主程序增加到無法接受的大小,可以在不變更可執行檔案的情況下應用即時升級程序。

當 Perl 模組執行長時間執行的作業時,例如解析網域名稱、連線到其他伺服器或查詢資料庫,指派給目前工作程序的其他請求將不會被處理。因此,建議只執行具有可預測且執行時間短的作業,例如存取本機檔案系統。

範例設定

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

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__

指令

語法 perl 模組::函式|'sub { ... }';
預設
內容 locationlimit_except

設定給定位置的 Perl 處理程式。

語法 perl_modules 路徑;
預設
內容 http

設定 Perl 模組的其他路徑。

語法 perl_require 模組;
預設
內容 http

定義在每次重新設定期間載入的模組名稱。可以有多個 perl_require 指令。

語法 perl_set $變數 模組::函式|'sub { ... }';
預設
內容 http

為指定的變數安裝 Perl 處理程式。

從 SSI 呼叫 Perl

呼叫 Perl 的 SSI 命令具有下列格式

<!--# perl sub="module::function" arg="parameter1" arg="parameter2" ...
-->

$r 請求物件方法

$r->args
傳回請求引數。
$r->filename
傳回對應於請求 URI 的檔案名稱。
$r->has_request_body(處理程式)
如果請求中沒有主體,則傳回 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 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
啟用在傳送回應時使用位元組範圍。
$r->discard_request_body
指示 nginx 捨棄請求主體。
$r->header_in(欄位)
傳回指定的用戶端請求標頭欄位的值。
$r->header_only
判斷是否應將整個回應或僅其標頭傳送到用戶端。
$r->header_out(欄位, )
設定指定的響應標頭欄位的值。
$r->internal_redirect(uri)
對指定的 uri 進行內部重新導向。實際重新導向會在 Perl 處理程式執行完成後發生。
從 1.17.2 版開始,此方法接受逸出的 URI 並支援重新導向至具名位置。
$r->log_error(錯誤代碼, 訊息)
將指定的 訊息 寫入 error_log。如果 錯誤代碼 非零,則會在訊息後面附加錯誤碼及其描述。
$r->print(文字, ...)
將資料傳遞給用戶端。
$r->request_body
如果用戶端請求主體尚未寫入臨時檔案,則傳回該主體。為了確保用戶端請求主體在記憶體中,其大小應受 client_max_body_size 限制,並且應使用 client_body_buffer_size 設定足夠的緩衝區大小。
$r->request_body_file
傳回包含用戶端請求主體的檔案名稱。處理完畢後,應移除該檔案。若要始終將請求主體寫入檔案,應啟用 client_body_in_file_only
$r->request_method
傳回用戶端請求 HTTP 方法。
$r->remote_addr
傳回用戶端 IP 位址。
$r->flush
立即將資料傳送給用戶端。
$r->sendfile(名稱[, 偏移量[, 長度]])
將指定的檔案內容傳送給用戶端。選用的參數指定要傳輸的資料的初始偏移量和長度。實際的資料傳輸會在 Perl 處理程式完成後發生。
$r->send_http_header([類型])
將響應標頭傳送給用戶端。選用的 類型 參數設定「Content-Type」響應標頭欄位的值。如果該值為空字串,則不會傳送「Content-Type」標頭欄位。
$r->status(代碼)
設定響應碼。
$r->sleep(毫秒, 處理程式)
設定指定的處理程式,並停止請求處理指定的的時間。同時,nginx 繼續處理其他請求。指定的時間過後,nginx 將會呼叫安裝的處理程式。請注意,處理程式函式應該以參考方式傳遞。為了在處理程式之間傳遞資料,應使用 $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->unescape(文字)
解碼以「%XX」形式編碼的文字。
$r->uri
傳回請求 URI。
$r->variable(名稱[, ])
傳回或設定指定變數的值。變數是每個請求的本機變數。