predefining ngx.var variables via map

1,486 views
Skip to first unread message

bjoe2k4

unread,
Feb 9, 2016, 4:52:41 AM2/9/16
to openresty-en
Hi,

i am currently in the process to move my applications from access_log to lua-resty-logger-socket und from ngx.var to ngx.ctx for variables that have a lifespan of a request.

I encountered one issue which i could not find in the docs of nginx/openresty. (I know that variables defined by the map directive have lazy evaluation, but it does not seem to work in lua scope.)

Usually i set some default value for ngx.var variables via the map directive in the http scope (instead of having to declare it with set in every server scope via the set directive):

http {
    map $host $rtype
{
       
default 'default';
   
}
    log_format test
'$rtype';
}

where $rtype is the variable that i want to set and $host is just an arbitrary variable to make the map directive work. This used to work before i migrated to lua-resty-logger-socket, i.e. i could do the following:

server {
...
rewrite_by_lua_block
{ ngx.var.rtype = "test" }
...
}

With a little bit of testing i found out that this only works, if the respective variable is used in the log_format directive (or maybe other directives as well). If i comment out the log_format line, then i get the following errors:

2016/02/09 10:11:33 [error] 7209#0: *8 lua entry thread aborted: runtime error: rewrite_by_lua(nginx.conf:50):1: variable "rtype" cannot be assigned a value
stack traceback
:
coroutine
0:
       
[C]: in function '__newindex'
        rewrite_by_lua
(nginx.conf:50):1: in function <rewrite_by_lua(nginx.conf:50):1>, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"

I am not sure if this is a bug, or expected behaviour, therefore i am here to ask ;-) (i use latest openresty 1.9.7.3)

Also i would like to have some advice on moving ngx.var assignements to ngx.ctx assingments (that i will later use in log_by_lua*). I decided namespace all variables to avoid possible conflicts with other apps by creating a ngx.ctx.var table. However now i would need to make sure that ngx.ctx.var exists before i can assign i.e. ngx.ctx.var.rtype. This additional check would be avoided, if i somehow could create this table somehow for every request by default, just like it was possible with ngx.var and the map directive.

Regards


Yichun Zhang (agentzh)

unread,
Feb 9, 2016, 4:10:36 PM2/9/16
to openresty-en
Hello!

On Tue, Feb 9, 2016 at 1:52 AM, bjoe2k4 wrote:
> 2016/02/09 10:11:33 [error] 7209#0: *8 lua entry thread aborted: runtime
> error: rewrite_by_lua(nginx.conf:50):1: variable "rtype" cannot be assigned
> a value

I think the error message is already quite clear :) Basically, unlike
"set", nginx variables defined by the "map" directive is owned by the
ngx_map module and cannot be assigned to by other modules. Pick up
another nginx variable names instead.

Regards,
-agentzh

王海波

unread,
Oct 25, 2017, 9:30:50 AM10/25/17
to openresty-en
how can i detect if variable can be set,something like:

if can_set(ngx.var.rtype) then
    ngx.var.rtype ="test"
end

在 2016年2月10日星期三 UTC+8上午5:10:36,agentzh写道:
Reply all
Reply to author
Forward
0 new messages