ngx_stream_js_module 模組

範例設定
指令
     js_access
     js_context_reuse
     js_engine
     js_fetch_buffer_size
     js_fetch_ciphers
     js_fetch_max_response_buffer_size
     js_fetch_protocols
     js_fetch_timeout
     js_fetch_trusted_certificate
     js_fetch_verify
     js_fetch_verify_depth
     js_filter
     js_import
     js_include
     js_path
     js_periodic
     js_preload_object
     js_preread
     js_set
     js_shared_dict_zone
     js_var
Session 物件屬性

ngx_stream_js_module 模組用於在 njs 中實作處理常式,njs 是 JavaScript 語言的子集。

下載與安裝說明請參考這裡

範例設定

此範例自 0.4.0 起適用。

stream {
    js_import stream.js;

    js_set $bar stream.bar;
    js_set $req_line stream.req_line;

    server {
        listen 12345;

        js_preread stream.preread;
        return     $req_line;
    }

    server {
        listen 12346;

        js_access  stream.access;
        proxy_pass 127.0.0.1:8000;
        js_filter  stream.header_inject;
    }
}

http {
    server {
        listen 8000;
        location / {
            return 200 $http_foo\n;
        }
    }
}

stream.js 檔案

var line = '';

function bar(s) {
    var v = s.variables;
    s.log("hello from bar() handler!");
    return "bar-var" + v.remote_port + "; pid=" + v.pid;
}

function preread(s) {
    s.on('upload', function (data, flags) {
        var n = data.indexOf('\n');
        if (n != -1) {
            line = data.substr(0, n);
            s.done();
        }
    });
}

function req_line(s) {
    return line;
}

// Read HTTP request line.
// Collect bytes in 'req' until
// request line is read.
// Injects HTTP header into a client's request

var my_header =  'Foo: foo';
function header_inject(s) {
    var req = '';
    s.on('upload', function(data, flags) {
        req += data;
        var n = req.search('\n');
        if (n != -1) {
            var rest = req.substr(n + 1);
            req = req.substr(0, n + 1);
            s.send(req + my_header + '\r\n' + rest, flags);
            s.off('upload');
        }
    });
}

function access(s) {
    if (s.remoteAddress.match('^192.*')) {
        s.deny();
        return;
    }

    s.allow();
}

export default {bar, preread, req_line, header_inject, access};

指令

語法 js_access function | module.function;
預設值
內容 stream, server

設定一個 njs 函式,該函式將在存取階段被呼叫。自 0.4.0 起,可以引用模組函式。

此函式會在串流工作階段首次到達存取階段時被呼叫一次。此函式會被呼叫並帶有以下引數

s
串流工作階段物件

在此階段,可以執行初始化,或使用 s.on() 方法為每個傳入的資料區塊註冊回呼,直到下列其中一個方法被呼叫:s.allow()s.decline()s.done()。一旦呼叫其中一個方法,串流工作階段處理就會切換到下一個階段,並且所有目前的 s.on() 回呼都會被捨棄。

語法 js_context_reuse number;
預設值
js_context_reuse 128;
內容 stream, server

此指令於 0.8.6 版中出現。

設定要重複用於 QuickJS 引擎的 JS 內容的最大數量。每個內容都用於單個串流工作階段。完成的內容會被放入可重複使用內容的集區。如果集區已滿,則內容會被銷毀。

語法 js_engine njs | qjs;
預設值
js_engine njs;
內容 stream, server

此指令於 0.8.6 版中出現。

設定要用於 njs 指令碼的 JavaScript 引擎njs 參數設定 njs 引擎,也為預設值。qjs 參數設定 QuickJS 引擎。

語法 js_fetch_buffer_size size;
預設值
js_fetch_buffer_size 16k;
內容 stream, server

此指令於 0.7.4 版中出現。

設定使用 Fetch API 進行讀寫的緩衝區大小

語法 js_fetch_ciphers ciphers;
預設值
js_fetch_ciphers HIGH:!aNULL:!MD5;
內容 stream, server

此指令於 0.7.0 版中出現。

使用 Fetch API 指定 HTTPS 連線的已啟用密碼。密碼的指定格式為 OpenSSL 程式庫所理解的格式。

可以使用「openssl ciphers」指令檢視完整清單。

語法 js_fetch_max_response_buffer_size size;
預設值
js_fetch_max_response_buffer_size 1m;
內容 stream, server

此指令於 0.7.4 版中出現。

設定使用 Fetch API 收到的最大回應大小

語法 js_fetch_protocols [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
預設值
js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2;
內容 stream, server

此指令於 0.7.0 版中出現。

使用 Fetch API 為 HTTPS 連線啟用指定的通訊協定。

語法 js_fetch_timeout time;
預設值
js_fetch_timeout 60s;
內容 stream, server

此指令於 0.7.4 版中出現。

定義使用 Fetch API 進行讀寫的逾時。逾時僅在兩個連續的讀取/寫入操作之間設定,而不是針對整個回應。如果在此時間內未傳輸任何資料,則會關閉連線。

語法 js_fetch_trusted_certificate file;
預設值
內容 stream, server

此指令於 0.7.0 版中出現。

指定使用 Fetch API驗證 HTTPS 憑證時,使用的受信任 CA 憑證 檔案(PEM 格式)。

語法 js_fetch_verify on | off;
預設值
js_fetch_verify on;
內容 stream, server

此指令於 0.7.4 版中出現。

使用 Fetch API 啟用或停用 HTTPS 伺服器憑證的驗證。

語法 js_fetch_verify_depth number;
預設值
js_fetch_verify_depth 100;
內容 stream, server

此指令於 0.7.0 版中出現。

使用 Fetch API 設定 HTTPS 伺服器憑證鏈中的驗證深度。

語法 js_filter function | module.function;
預設值
內容 stream, server

設定資料篩選器。自 0.4.0 起,可以引用模組函式。篩選器函式會在串流工作階段到達內容階段時被呼叫一次。

篩選器函式會被呼叫並帶有以下引數

s
串流工作階段物件

在此階段,可以執行初始化,或使用 s.on() 方法為每個傳入的資料區塊註冊回呼。s.off() 方法可以用來取消註冊回呼,並停止篩選。

由於 js_filter 處理常式會立即傳回其結果,因此它僅支援同步操作。因此,不支援非同步操作,例如 ngx.fetch()setTimeout()

語法 js_import module.js | export_name from module.js;
預設值
內容 stream, server

此指令於 0.4.0 版中出現。

匯入一個在 njs 中實作位置和變數處理常式的模組。export_name 會被當成存取模組函式的命名空間。如果未指定 export_name,則會將模組名稱當成命名空間。

js_import stream.js;

在這裡,模組名稱 stream 會被當成存取匯出的命名空間。如果匯入的模組匯出 foo(),則會使用 stream.foo 來參考它。

可以指定數個 js_import 指令。

0.7.7 起,可以在 server 層級指定該指令。

語法 js_include file;
預設值
內容 stream

指定一個在 njs 中實作伺服器和變數處理常式的檔案

nginx.conf:
js_include stream.js;
js_set     $js_addr address;
server {
    listen 127.0.0.1:12345;
    return $js_addr;
}

stream.js:
function address(s) {
    return s.remoteAddress;
}

此指令在 0.4.0 版中已過時,並在 0.7.1 版中移除。應改為使用 js_import 指令。

語法 js_path path;
預設值
內容 stream, server

此指令於 0.3.0 版中出現。

設定 njs 模組的額外路徑。

0.7.7 起,可以在 server 層級指定該指令。

語法 js_periodic function | module.function [interval=time] [jitter=number] [worker_affinity=mask];
預設值
內容 server

此指令於 0.8.1 版中出現。

指定一個內容處理常式,使其以規律的間隔執行。此處理常式會收到一個 工作階段物件作為其第一個引數,它也可以存取全域物件,例如 ngx

選用的 interval 參數設定兩個連續執行之間的間隔,預設值為 5 秒。

選用的 jitter 參數設定位置內容處理常式會被隨機延遲的時間,預設情況下沒有延遲。

預設情況下,js_handler 會在工作程序 0 上執行。選用的 worker_affinity 參數允許指定應該執行位置內容處理常式的特定工作程序。每個工作程序集都由允許的工作程序位元遮罩表示。all 遮罩允許在所有工作程序中執行處理常式。

範例

example.conf:

location @periodics {
    # to be run at 1 minute intervals in worker process 0
    js_periodic main.handler interval=60s;

    # to be run at 1 minute intervals in all worker processes
    js_periodic main.handler interval=60s worker_affinity=all;

    # to be run at 1 minute intervals in worker processes 1 and 3
    js_periodic main.handler interval=60s worker_affinity=0101;

    resolver 10.0.0.1;
    js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}

example.js:

async function handler(s) {
    let reply = await ngx.fetch('https://nginx.dev.org.tw/en/docs/njs/');
    let body = await reply.text();

    ngx.log(ngx.INFO, body);
}

語法 js_preload_object name.json | name from file.json;
預設值
內容 stream, server

此指令於 0.7.8 版中出現。

在設定時預先載入一個不可變物件name 會被當成全域變數的名稱,透過該變數,該物件可以在 njs 程式碼中使用。如果未指定 name,則會改為使用檔案名稱。

js_preload_object map.json;

在這裡,map 會被當成存取預先載入物件的名稱。

可以指定數個 js_preload_object 指令。

語法 js_preread function | module.function;
預設值
內容 stream, server

設定一個 njs 函式,該函式將在預讀階段被呼叫。自 0.4.0 起,可以引用模組函式。

此函式會在串流工作階段首次到達預讀階段時被呼叫一次。此函式會被呼叫並帶有以下引數

s
串流工作階段物件

在此階段,可以執行初始化,或使用 s.on() 方法為每個傳入的資料區塊註冊回呼,直到下列其中一個方法被呼叫:s.allow()s.decline()s.done()。當呼叫其中一個方法時,串流工作階段會切換到下一個階段,並且所有目前的 s.on() 回呼都會被捨棄。

由於 js_preread 處理常式會立即傳回其結果,因此它僅支援同步回呼。因此,不支援非同步回呼,例如 ngx.fetch()setTimeout()。不過,在 預讀階段的 s.on() 回呼中支援非同步操作。如需詳細資訊,請參閱 此範例

語法 js_set $variable function | module.function [nocache];
預設值
內容 stream, server

為指定的 variable 設定一個 njs function。自 0.4.0 起,可以引用模組函式。

當第一次針對給定的請求參考變數時,會呼叫此函式。確切的時機取決於參考變數時所在的階段。這可以用來執行一些與變數評估無關的邏輯。例如,如果變數僅在 log_format 指令中參考,則其處理常式在記錄階段之前不會執行。此處理常式可用於在釋放請求之前執行一些清理。

0.8.6 起,當提供選用引數 nocache 時,每次參考處理常式時都會呼叫它。由於 rewrite 模組目前的限制,當 set 指令參考 nocache 變數時,其處理常式應始終傳回固定長度的值。

由於 js_set 處理常式會立即傳回其結果,因此它僅支援同步回呼。因此,不支援非同步回呼,例如 ngx.fetch()setTimeout()

0.7.7 起,可以在 server 層級指定該指令。

語法 js_shared_dict_zone zone=名稱:大小 [timeout=時間] [type=string|number] [evict];
預設值
內容 stream

此指令出現於 0.8.0 版本。

設定在工作進程之間共享的鍵值字典所使用的共享記憶體區的名稱大小

預設情況下,共享字典使用字串作為鍵和值。 可選的 type 參數允許將值的類型重新定義為數字。

可選的 timeout 參數設定時間(以毫秒為單位),在此時間之後,所有共享字典條目將從該區中移除。 如果某些條目需要不同的移除時間,可以使用 addincrset 方法的 timeout 參數設定 (0.8.5)。

當區的儲存空間耗盡時,可選的 evict 參數會移除最舊的鍵值對。

範例

example.conf:
    # Creates a 1Mb dictionary with string values,
    # removes key-value pairs after 60 seconds of inactivity:
    js_shared_dict_zone zone=foo:1M timeout=60s;

    # Creates a 512Kb dictionary with string values,
    # forcibly removes oldest key-value pairs when the zone is exhausted:
    js_shared_dict_zone zone=bar:512K timeout=30s evict;

    # Creates a 32Kb permanent dictionary with number values:
    js_shared_dict_zone zone=num:32k type=number;

example.js:
    function get(r) {
        r.return(200, ngx.shared.foo.get(r.args.key));
    }

    function set(r) {
        r.return(200, ngx.shared.foo.set(r.args.key, r.args.value));
    }

    function del(r) {
        r.return(200, ngx.shared.bar.delete(r.args.key));
    }

    function increment(r) {
        r.return(200, ngx.shared.num.incr(r.args.key, 2));
    }

語法 js_var $變數 [];
預設值
內容 stream, server

此指令出現於 0.5.3 版本。

宣告一個可寫入的變數。該值可以包含文字、變數及其組合。

0.7.7 起,可以在 server 層級指定該指令。

Session 物件屬性

每個 stream njs 處理器都會收到一個參數,即一個 stream session 物件