json.lua icon indicating copy to clipboard operation
json.lua copied to clipboard

Not working with NGNIX

Open edenisn opened this issue 4 years ago • 5 comments

I installed nginx-full and trying to use json.lua with NGINX:

Example:

nginx.conf:

location /test { default_type 'text/plain'; content_by_lua_block { local json = require("json") ngx.say(json.decode('[1,2,3,{"x":10}]')) }

then curl http://localhost:8080/test and got 500 error. But everything is ok in lua console:

`> json = require("json")

json.encode({ 1, 2, 3, { x = 10 } }) [1,2,3,{"x":10}]`

What I am doing wrong?

edenisn avatar May 31 '20 16:05 edenisn

I'd guess that json.lua is not in nginx's (maybe special) $LUA_PATH?

guysv avatar May 31 '20 16:05 guysv

ahhh, it's present in nginx.conf:

lua_package_path "/usr/local/lib/lua/?.lua;;";

edenisn avatar May 31 '20 16:05 edenisn

If it's possible, can you pls provide example with NGINX? Thanks @guysv

edenisn avatar May 31 '20 16:05 edenisn

One more very strange thing: if I use code below in nginx.conf:

location /test { content_by_lua_block { local json = require("json") ngx.say(json.encode({ 1, 2, 3, { x = 10 } })) } }

It works fine

[1,2,3,{"x":10}]

edenisn avatar May 31 '20 16:05 edenisn

Isn't a lib related issue but a third-party module limitation (openresty/lua-nginx-module). https://github.com/openresty/lua-nginx-module/blob/.../src/ngx_http_lua_output.c#L285

According to the documentation, the ngx.say function expects a array table (with numeric index) as a parameter and not a table with string-type indexes.

[error] 1265#1265: *64 lua entry thread aborted: runtime error: content_by_lua(default.conf:17):3: bad argument #1 to 'say' (non-array table found)
stack traceback:
coroutine 0:
	[C]: in function 'say'

Non-array table arguments will cause a Lua exception to be thrown.

https://github.com/openresty/lua-nginx-module#ngxprint:~:text=Non%2Darray%20table...


A possible solution would be to use the lib itself to encode to string:

content_by_lua_block {
    local json = require("json")
    local decoded = json.decode('[1,2,3,{"x":10}]')
    local encoded = json.encode(decoded)
    ngx.say(encoded)
}

Tests:

content_by_lua_block {
    ngx.say({["test"] = "ok"}) -- error
}
--
content_by_lua_block {
    ngx.say({1, 2, 3, {["test"] = "ok"}}) -- error
}
--
content_by_lua_block {
    ngx.say({1, 2, 3}) -- works
}
--
content_by_lua_block {
    ngx.say({1, 2, 3, {1, 2}}) -- works
}
--
content_by_lua_block {
    ngx.say({1, 2, 3, {[1] = "ok"}}) -- works
}

xphip avatar Jun 28 '22 09:06 xphip