Internal error on handling HTTP-request with duplicated header keys: Accept, Content-Type and Origin
Is there an existing issue for this?
No. I have searched the existing issues. Used queries:
attempt to call method 'match',attempt to call method 'find',attempt to call method 'gsub'duplicate,header
Similar issue: https://github.com/leafo/lapis/issues/794
Version
I used snapCloud master branch, commit b3d2a4c
luarocks list
# luarocks list
ansicolors
1.0.2-3 (installed) - /usr/local/lib/luarocks/rocks
argparse
0.7.1-1 (installed) - /usr/local/lib/luarocks/rocks
date
2.2.1-1 (installed) - /usr/local/lib/luarocks/rocks
etlua
1.3.0-1 (installed) - /usr/local/lib/luarocks/rocks
inspect
3.1.3-0 (installed) - /usr/local/lib/luarocks/rocks
lapis
1.16.0-1 (installed) - /usr/local/lib/luarocks/rocks
loadkit
1.1.0-1 (installed) - /usr/local/lib/luarocks/rocks
lpeg
1.1.0-2 (installed) - /usr/local/lib/luarocks/rocks
lua-cjson
2.1.0.10-1 (installed) - /usr/local/lib/luarocks/rocks
lua-resty-http
0.17.2-0 (installed) - /usr/local/lib/luarocks/rocks
lua-resty-mail
1.1.0-1 (installed) - /usr/local/lib/luarocks/rocks
luabitop
1.0.2-1 (installed) - /usr/local/lib/luarocks/rocks
luafilesystem
1.8.0-1 (installed) - /usr/local/lib/luarocks/rocks
luaossl
20220711-0 (installed) - /usr/local/lib/luarocks/rocks
luasec
1.3.2-1 (installed) - /usr/local/lib/luarocks/rocks
luasocket
3.1.0-1 (installed) - /usr/local/lib/luarocks/rocks
lub
1.1.0-1 (installed) - /usr/local/lib/luarocks/rocks
pgmoon
1.16.0-1 (installed) - /usr/local/lib/luarocks/rocks
snapcloud
dev-0 (installed) - /usr/local/lib/luarocks/rocks
xml
1.1.3-1 (installed) - /usr/local/lib/luarocks/rocks
Error
Duplicated HTTP headers Accept, Content-Type and Origin in the request lead to 500 (Internal Error).
It happens due to unusual behavior of the ngx.req.get_headers function. Consider simple example:
local my_header = ngx.req.get_headers()["X-MyHeader"]
The variable my_header may be:
nil, if there is no header namedX-MyHeaderstring(if only one header provided)- or (!)
table(if multiple headers provided).
The snapCloud code assumes the value only as a nil or a string and, therefore, if there are multiply headers -- the code crashes and produces 500 error code. The example of dealing with the table type case: https://github.com/Kong/kong/pull/14331/files#diff-71ca7cc8d190667cccff84bdd38a242104adcaa8a3a844874aa518484fdf291fR260
Duplicated Accept header
Logs from the server
, client: 127.0.0.1, server: 9dd6683d475e, request: "GET / HTTP/1.1", host: "127.0.0.1:8080"
2025/03/09 16:28:40 [error] 22283#22283: *198 lua entry thread aborted: runtime error: ./responses.lua:77: attempt to call method 'match' (a nil value)
stack traceback:
coroutine 0:
./responses.lua: in function 'handle_error'
/usr/local/share/lua/5.1/lapis/application.lua:196: in function 'render_error_request'
/usr/local/share/lua/5.1/lapis/application.lua:228: in function 'dispatch'
/usr/local/share/lua/5.1/lapis/nginx.lua:231: in function 'serve'
content_by_lua(nginx.conf.d/locations.conf:32):2: in main chunk, client: 127.0.0.1, server: 9dd6683d475e, request: "GET / HTTP/1.1", host: "127.0.0.1:8080"
2025/03/09 16:28:40 [notice] 22283#22283: *200 "^/(.*)\.html$" does not match "/", client: 127.0.0.1, server: 9dd6683d475e, request: "GET / HTTP/1.1", host: "127.0.0.1:8080"
2025/03/09 16:28:40 [error] 22283#22283: *200 connect() failed (111: Connection refused), client: 127.0.0.1, server: 9dd6683d475e, request: "GET / HTTP/1.1", host: "127.0.0.1:8080"
2025/03/09 16:28:40 [notice] 22283#22283: *200 [lua] global.lua:39: debug_print():
Related sources:
https://github.com/snap-cloud/snapCloud/blob/b3d2a4c048ab8b0df1f936c47d942c0790da8034/responses.lua#L77
Duplicated Content-Type header
Logs from server
./app.lua:184: attempt to call method 'find' (a nil value)
"\nstack traceback:
\n\t./app.lua:184: in function 'filter'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:22: in function 'run_before_filter'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:176: in function 'resolve'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:216: in function </usr/local/share/lua/5.1/lapis/application.lua:214>
\n\t[C]: in function 'xpcall'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:214: in function 'dispatch'
\n\t/usr/local/share/lua/5.1/lapis/nginx.lua:231: in function 'serve'
\n\tcontent_by_lua(nginx.conf.d/locations.conf:32):2: in main chunk"
Related sources:
https://github.com/snap-cloud/snapCloud/blob/b3d2a4c048ab8b0df1f936c47d942c0790da8034/app.lua#L183-L184
Duplicated Origin header
Logs from server
./lib/util.lua:34: attempt to call method 'gsub' (a nil value)
"\nstack traceback:
\n\t./lib/util.lua:34: in function 'domain_name'
\n\t./app.lua:187: in function 'filter'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:22: in function 'run_before_filter'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:176: in function 'resolve'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:216: in function </usr/local/share/lua/5.1/lapis/application.lua:214>
\n\t[C]: in function 'xpcall'
\n\t/usr/local/share/lua/5.1/lapis/application.lua:214: in function 'dispatch'
\n\t/usr/local/share/lua/5.1/lapis/nginx.lua:231: in function 'serve'
\n\tcontent_by_lua(nginx.conf.d/locations.conf:32):2: in main chunk"
Related sources:
https://github.com/snap-cloud/snapCloud/blob/b3d2a4c048ab8b0df1f936c47d942c0790da8034/app.lua#L187
https://github.com/snap-cloud/snapCloud/blob/b3d2a4c048ab8b0df1f936c47d942c0790da8034/lib/util.lua#L34
Steps to reproduce
Steps:
- Prepare project according to INSTALL.md
- Send an HTTP-packet with a duplicated
Acceptheader:curl -H "Accept: application/json" -H "Accept: application/json" 127.0.0.1:8080 - Send an HTTP-packet with a duplicated
Content-Typeheader:curl -H "Content-Type: application/json" -H "Content-Type: application/json" 127.0.0.1:8080 - Send an HTTP-packet with a duplicated
Originheader:curl -H "Origin: localhost" -H "Origin: localhost" 127.0.0.1:8080
Misc
The HTTP packet I provided may be somewhat of invalid. Nevertheless, I think that SnapCloud's Lua scripts should not crash even on the invalid HTTP packet. Thus, I consider that it is a bug.
Thanks for the report.
Yes, this is a bit of odd/unexpected behavior. However, there's a bunch of other higher priority items, so I don't think we will get to this very quickly. I'll babe the issue open though.