模块 ngx_stream_js_module
ngx_stream_js_module 模块用于在 njs(JavaScript 语言的一个子集)中实现处理器(handler)。
下载和安装说明可从此处获取。
配置示例
此示例从 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 |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
设置一个 njs 函数,该函数将在访问(access)阶段被调用。从 0.4.0 版本开始,可以引用模块函数。
当流会话首次到达访问(access)阶段时,该函数会被调用一次。该函数会带以下参数被调用
在此阶段,可以执行初始化操作或使用 s.on() 方法注册一个回调函数,以便处理每个传入的数据块,直到调用以下方法之一:s.allow()、s.decline()、s.done()。一旦调用了其中一个方法,流会话处理将切换到下一阶段,并且所有当前的 s.on() 回调函数将被丢弃。
| 语法 |
js_context_reuse |
|---|---|
| 默认值 |
js_context_reuse 128; |
| 上下文 |
stream, server |
此指令出现在 0.8.6 版本中。
设置 QuickJS 引擎可重用的 JS 上下文的最大数量。每个上下文用于一个流会话。完成的上下文会被放入可重用上下文池中。如果池满,则销毁该上下文。
| 语法 |
js_engine |
|---|---|
| 默认值 |
js_engine njs; |
| 上下文 |
stream, server |
此指令出现在 0.8.6 版本中。
设置用于 njs 脚本的 JavaScript 引擎。参数 njs 设置 njs 引擎,该引擎也是默认使用的。参数 qjs 设置 QuickJS 引擎。
| 语法 |
js_fetch_buffer_size |
|---|---|
| 默认值 |
js_fetch_buffer_size 16k; |
| 上下文 |
stream, server |
此指令出现在 0.7.4 版本中。
设置使用 Fetch API 进行读写时使用的缓冲区的大小。
| 语法 |
js_fetch_ciphers |
|---|---|
| 默认值 |
js_fetch_ciphers HIGH:!aNULL:!MD5; |
| 上下文 |
stream, server |
此指令出现在 0.7.0 版本中。
指定使用 Fetch API 进行 HTTPS 连接时启用的密码套件。密码套件的格式由 OpenSSL 库理解。
使用“openssl ciphers”命令可以查看完整列表。
| 语法 |
js_fetch_max_response_buffer_size |
|---|---|
| 默认值 |
js_fetch_max_response_buffer_size 1m; |
| 上下文 |
stream, server |
此指令出现在 0.7.4 版本中。
设置使用 Fetch API 接收到的响应的最大大小。
| 语法 |
js_fetch_protocols [ |
|---|---|
| 默认值 |
js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2; |
| 上下文 |
stream, server |
此指令出现在 0.7.0 版本中。
为使用 Fetch API 的 HTTPS 连接启用指定的协议。
| 语法 |
js_fetch_timeout |
|---|---|
| 默认值 |
js_fetch_timeout 60s; |
| 上下文 |
stream, server |
此指令出现在 0.7.4 版本中。
定义 Fetch API 的读写超时时间。超时时间只设置在两个连续的读写操作之间,而不是整个响应过程。如果在此时间内没有数据传输,连接将被关闭。
| 语法 |
js_fetch_trusted_certificate |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
此指令出现在 0.7.0 版本中。
指定一个包含 PEM 格式的可信 CA 证书的文件,该文件用于使用 Fetch API 来验证 HTTPS 证书。
| 语法 |
js_fetch_verify |
|---|---|
| 默认值 |
js_fetch_verify on; |
| 上下文 |
stream, server |
此指令出现在 0.7.4 版本中。
启用或禁用使用 Fetch API 对 HTTPS 服务器证书的验证。
| 语法 |
js_fetch_verify_depth |
|---|---|
| 默认值 |
js_fetch_verify_depth 100; |
| 上下文 |
stream, server |
此指令出现在 0.7.0 版本中。
设置使用 Fetch API 对 HTTPS 服务器证书链的验证深度。
| 语法 |
js_filter |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
设置一个数据过滤器。从 0.4.0 版本开始,可以引用模块函数。当流会话到达内容(content)阶段时,过滤器函数会被调用一次。
过滤器函数会带以下参数被调用
在此阶段,可以执行初始化操作或使用 s.on() 方法为每个传入的数据块注册一个回调函数。s.off() 方法可用于注销回调函数并停止过滤。
由于js_filter处理器会立即返回其结果,因此它只支持同步操作。因此,不支持ngx.fetch()或setTimeout()等异步操作。
| 语法 |
js_import |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
此指令出现在 0.4.0 版本中。
导入一个在 njs 中实现 location 和变量处理器的模块。export_name 用作访问模块函数的命名空间。如果未指定 export_name,则将使用模块名称作为命名空间。
js_import stream.js;
在这里,导入模块时,模块名称 stream 被用作命名空间。如果导入的模块导出了 foo(),则使用 stream.foo 来引用它。
可以指定多个 js_import 指令。
从 0.7.7 版本开始,可以在 server 级别指定此指令。
| 语法 |
js_include |
|---|---|
| 默认值 | — |
| 上下文 |
stream |
指定一个文件,该文件在 njs 中实现 server 和变量处理器
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 |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
此指令出现在 0.3.0 版本中。
设置 njs 模块的附加路径。
从 0.7.7 版本开始,可以在 server 级别指定此指令。
| 语法 |
js_periodic |
|---|---|
| 默认值 | — |
| 上下文 |
server |
此指令出现在 0.8.1 版本中。
指定一个内容处理器,用于定期运行。该处理器接收一个 session 对象作为其第一个参数,并且可以访问 ngx 等全局对象。
可选参数 interval 设置两次连续运行之间的间隔,默认值为 5 秒。
可选参数 jitter 设置 location 内容处理器将被随机延迟的时间,默认情况下没有延迟。
默认情况下,js_handler 在工作进程 0 上执行。可选参数 worker_affinity 允许指定应执行 location 内容处理器的特定工作进程。每个工作进程集由允许的工作进程的位掩码表示。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.ac.cn/en/docs/njs/');
let body = await reply.text();
ngx.log(ngx.INFO, body);
}
| 语法 |
js_preload_object |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
此指令出现在 0.7.8 版本中。
在配置时预加载一个不可变对象。name 用作全局变量的名称,通过该名称可以在 njs 代码中访问该对象。如果未指定 name,则将使用文件名代替。
js_preload_object map.json;
在这里,访问预加载对象时使用 map 作为名称。
可以指定多个 js_preload_object 指令。
| 语法 |
js_preread |
|---|---|
| 默认值 | — |
| 上下文 |
stream, server |
设置一个 njs 函数,该函数将在预读(preread)阶段被调用。从 0.4.0 版本开始,可以引用模块函数。
当流会话首次到达预读(preread)阶段时,该函数会被调用一次。该函数会带以下参数被调用
在此阶段,可以执行初始化操作或使用 s.on() 方法为每个传入的数据块注册一个回调函数,直到调用以下方法之一:s.allow()、s.decline()、s.done()。当调用其中一个方法时,流会话将切换到下一阶段,并且所有当前的 s.on() 回调函数将被丢弃。
由于js_preread处理器会立即返回其结果,因此它只支持同步回调。因此,不支持ngx.fetch()或setTimeout()等异步回调。然而,在预读(preread)阶段的s.on()回调函数中支持异步操作。有关更多信息,请参阅此示例。
| 语法 |
js_set |
|---|---|
| 默认值 | — |
| 上下文 |
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 |
|---|---|
| 默认值 | — |
| 上下文 |
stream |
此指令出现在 0.8.0 版本中。
设置共享内存区域的名称和大小,该区域用于保存工作进程之间共享的键值字典。
默认情况下,共享字典使用字符串作为键和值。可选参数 type 允许将值类型重新定义为 number。
可选参数 timeout 设置所有共享字典条目从区域中移除之前的时间,以毫秒为单位。如果某些条目需要不同的移除时间,可以使用 add、incr 和 set 方法的 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 级别指定此指令。
会话对象属性
每个流 njs 处理器接收一个参数,即流会话对象。