Ngx_lua post data error/bug?

This is a follow on from:
http://mailman.nginx.org/pipermail/nginx/2011-October/029905.html

The conditional statements take care of the basic error but what
happens is that when “post” requests match any of the test regexes, an
error is thrown …
“lua handler aborted: runtime error: attempt to yield across
metamethod/C-call boundary blah, blah, blah”.

It appears this is due to a limitation in Lua 5.1 and this yeilding is
a major item for Lua 5.2. However, trying to build Nginx with the lua
module against Lua 5.2 fails…

/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_conf.c

/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:
In function ‘ngx_http_lua_new_thread’:
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:189:
error: ‘LUA_GLOBALSINDEX’ undeclared (first use in this function)
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:189:
error: (Each undeclared identifier is reported only once
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:189:
error: for each function it appears in.)
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:
In function ‘ngx_http_lua_del_thread’:
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:228:
warning: implicit declaration of function ‘lua_getfenv’
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:234:
warning: implicit declaration of function ‘lua_setfenv’
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:
In function ‘init_ngx_lua_globals’:
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:507:
error: ‘LUA_GLOBALSINDEX’ undeclared (first use in this function)
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:
In function ‘ngx_http_lua_discard_bufs’:
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:544:
warning: unused parameter ‘pool’
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:
In function ‘ngx_http_lua_set_multi_value_table’:
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_util.c:1167:
warning: implicit declaration of function ‘lua_objlen’
make[1]: *** [objs/addon/src/ngx_http_lua_util.o] Error 1
make[1]: *** Waiting for unfinished jobs…
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_conf.c:
In function ‘ngx_http_lua_merge_loc_conf’:
/usr/src/redhat/BUILD/nginx-1.0.8/ngx-lua-module-0.31rc17-0/src/ngx_http_lua_conf.c:95:
warning: unused parameter ‘cf’
make[1]: Leaving directory `/usr/src/redhat/BUILD/nginx-1.0.8’
make: *** [build] Error 2
error: Bad exit status from /var/tmp/rpm-tmp.63523 (%build)

The upshot is that perhaps only LuaJIT 2.0 can be used for all
features in recent versions of ngx_lua.

Luckily, I took a backup of my server state so I’ll be rolling back
and commenting out the “post” block.

On 21 October 2011 21:06, Nginx U. [email protected] wrote:

This is a follow on from:
lua_need_request_body ... limitations?

The conditional statements take care of the basic error but what
happens is that when “post” requests match any of the test regexes, an
error is thrown …
“lua handler aborted: runtime error: attempt to yield across
metamethod/C-call boundary blah, blah, blah”.

It appears this is due to a limitation in Lua 5.1 …

Testing shows that the error is generated because of the
‘dofile(“/etc/nginx/regex_rules.lua”)’ line.

I.E., when the regex rules are placed directly in the
access_by_lua_file, a hit on a regex is processed as expected.
When the rules are included using the dofile function, a hit on a
regex results in the "attempt to yield across

On Sat, Oct 22, 2011 at 3:43 AM, Nginx U. [email protected] wrote:

Testing shows that the error is generated because of the
‘dofile(“/etc/nginx/regex_rules.lua”)’ line.

Lua’s “dofile” builtin is implemented as a C function in both Lua 5.1
and LuaJIT 2.0. And when you call ngx.location.capture or ngx.exec or
ngx.exit or ngx.req.read_body or something like those in the
regex_rules.lua, it’ll effectively initiate a coroutine yield and that
yield will run across C function boundary, which is disallowed.

I think it’s more efficient to use Lua modules and the “require”
builtin because dofile will load the .lua file from disk at every
request and it’s quite costy while “require” will only load the .lua
module file only once unless lua_code_cache is turned off. Here is an
example,

-- regex_rules.lua
module("regex_rules", package.seeall)
function check()
    ngx.req.read_body()
    -- other processing goes here...
end

# nginx.conf
lua_package_path 

“/path/to/regex_rules.lua’s-parent-directory/?.lua;;”
server {
location /foo {
access_by_lua ’
local regex_rules = require “regex_rules”
regex_rules.check()
';
# content handler config goes here…
}
}

BTW, compatibility with Lua 5.2 is not maintained by ngx_lua (yet).

Regards,
-agentzh

On 22 October 2011 04:25, agentzh [email protected] wrote:

yield will run across C function boundary, which is disallowed.
ngx.req.read_body()
';
# content handler config goes here…
}
}

BTW, compatibility with Lua 5.2 is not maintained by ngx_lua (yet).

Magic … Works perfectly.

You are a legend!