一 ngx.arg
arg api
只包含一个接口 ngx.arg
,ngx.arg
可以在两个阶段使用:set_by_lua
和 body_filter_by_lua
。
1. 在 set_by_lua
中使用
在 set_by_lua
阶段 ngx.arg
是一个只读表,保存指令的输入参数。
1 | location /foo { |
这是 lua-nginx-module
中的一段示例,在 set_by_lua
指令中通过 ngx.arg[1]
获得 $a
变量,ngx.arg[2]
获得 $b
变量,ngx.arg[3]
获得 $c
变量。
2. 在 body_filter_by_lua
中使用
当在 body_filter_by_lua
阶段使用 ngx.arg
表时,ngx.arg[1]
持有调用 lua-nginx
模块 body_filter
函数传入的数据块,ngx.arg[2]
用来标记整个输出流是否结束(布尔类型)。在 body_filter_by_lua
阶段,ngx.arg
是可以修改的,ngx.arg[1]
设置为 nil
或者 ""
后续的 body_filter
将不会收的数据块。同时还可以修改 ngx.arg[2]
控制下游 body_filter
是否已经发送完毕。在 body_filter_by_lua
中只能使用 1
和 2
两个索引。
二 实现
ngx.arg
是 table
类型数据,在 lua-nginx
中通过设置其 __index
和 __newindex
方法来实现获得参数、包体、设置包体和 eof
状态的功能。注册 ngx.arg
函数:
1 | static void |
__index
方法同时支持 set_by_lua
和 body_filter_by_lua
功能,用来获取参数、应答包体、应答包体 eof
状态。__newindex
方法仅支持 body_filter_by_lua
阶段,用来设置应答包体、应答包体 eof
状态。
1. set_by_lua
参数获取
在 set_by_lua
中参数的获取最终实现函数是 ngx_http_lua_setby_param_get
。在使用 ngx.arg[idx]
进行获取参数时所有参数以及保存在数组中,通过 ngx_http_lua_args_key
伪索引获得数组。因为在 C
中索引从 0
开始,因此传入的索引 idx
需要进行减一操作。
1 | int |
2. body_filter_by_lua
获取数据
在 body_filter_by_lua
中获取应答包体、应答 eof
状态的实现函数是 ngx_http_lua_body_filter_param_get
。函数仅允许使用 1
或 2
作为索引,当索引为 2
时仅需要判断输出链 ngx_chain_t
类型数据是否为空即可返还布尔类型应答值以标识应答是否结束;当索引为 1
时需要遍历输出链,计算长度,并将其拷贝到缓冲区进行返回。
1 | // body filter 阶段获取待输出数据 |
3. body_filter_by_lua
设置数据
在 body_filter_by_lua
中设置应答包体、应答 eof
状态的实现函数是 ngx_http_lua_body_filter_param_set
。
1 | int |
在 body_filter_by_lua
中通过 ngx.arg[1]
设置应答包体时可以使用 table
作为值,但是 table
必须是数组类型,非哈希表。