lua-nginx 使用自定义变量时需要说明的一点
在 Nginx 中,有两种方式添加自定义的变量:
- 在配置文件中用 set 指定添加
- 在自己编写的 C 模块中,调用
ngx_http_add_variable
接口来添加变量
第一种方法较简单,第二种方法有一处需要说明一下。
当调用 ngx_http_add_variable
接口时,如果传入的 flag 参数中 NGX_HTTP_VAR_NOHASH
位被设置了,那么在 lua 代码中使用 ngx.var.XXX 是不能访问到该变量的,得到的值是 nil
。
在这种情况下,如果现在配置文件中通过set指定一个中间变量,则在lua代码中可以访问到。
例如,某个 C 模块中用带有 NGX_HTTP_VAR_NOHASH
位的 flag 参数调用了 ngx_http_add_variable
,创建了变量 A,则如果在 lua 代码中通过 ngx.var.A
只能得到一个 nil
值。
而如果在配置文件中,先调用 set 命令:set $B $A;
,那么在 lua 代码中,通过代码 local A2 = ngx.var.B
则可以间接访问到该变量。
翻了一下邮件列表,发现该问题 agentzh 早有解答:
逆雪寒: 通过
ngx.var.fastcgi_script_name
是nil
。 但set $fsn $fastcgi_script_name
然后ngx.var.fsn
就能正常获取了。bug ? 还是我理解问题?
agenzh:
这是 Nginx 标准的
ngx_fastcgi
模块的一个限制。$fastcgi_script_name
这个内建变量是这个ngx_fastcgi
模块定义的,而且在定义时设置了NGX_HTTP_VAR_NOHASH
这个标志位,从而阻止了 Perl、Lua 等各种脚本语言在请求时按变量名动态获取这个变量的值。之所以你使用 set 指令进行过渡就可以工作是因为 set 指令定位
$fastcgi_script_name
这个变量是在配置加载时,而不是请求时。你可以自己修改 Nginx 源码树中的
src/http/modules/ngx_http_fastcgi_module.c
这个文件,从ngx_http_fastcgi_vars
这个全局数组的初始化定义中把NGX_HTTP_VAR_NOHASH
这个标志去除。从 ngx_lua 模块的角度,是没办法绕过 Nginx 核心中的这个限制的。关于类似这样的问题,可以参见下面这个讨论: