最近有个需求,需要nginx根据POST参数将请求转发到不同的后端,调研后决定使用OpenResty(Nginx + Lua)作为代理服务器。
写个小Demo:
location /test {
set $target_url '';
rewrite_by_lua_block {
if "POST" == ngx.req.get_method() then
ngx.req.read_body()
local args = ngx.req.get_body_data()
if string.match(args, "name=\"Key\"") == nil then
ngx.var.target_url = "http://127.0.0.1:8000"
else
ngx.var.target_url = "http://127.0.0.1:8080"
end
}
proxy_pass $target_url;
}
试了下,请求被正确转发了。好像一切都很好,实际用的时候,接口返回了500,因为args
的值为nil
。
看了文档:
This function returns nil if
1. the request body has not been read,
2. the request body has been read into disk temporary files,
3. or the request body has zero size.
第一条,请求体没有被读,不知道怎么判断。第二条,请求体被读进了一个临时文件,依旧不知道怎么判断。第三条,请求体是空的,基本可以否定。
后来查到:
由于内存的限制,ngx_http_read_client_request_body()接口读取的请求体会部分或者全部写入一个临时文件中,根据请求体的大小以及相关的指令配置,请求体可能完整放置在一块连续内存中,也可能分别放置在两块不同内存中,还可能全部存在一个临时文件中,最后还可能一部分在内存,剩余部分在临时文件中。
————————————————
版权声明:本文为CSDN博主「weixin_39634022」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39634022/article/details/111848493
猜测请求体太大被写入了临时文件,lua部分代码改为:
local filename = ngx.req.get_body_file()
if type(filename) ~= "nil" then
file = io.open(filename, "r")
for line in file:lines() do
if string.match(line, "name=\"Key\"") ~= nil then
file:read()
if string.match(string.lower(file:read()), "value") == nil then
ngx.var.target_url = "http://127.0.0.1:8000"
else
ngx.var.target_url = "http://127.0.0.1:8080"
end
break
end
end
file:close()
end
请求成功。
然后将两种方式结合起来,如果其中一种找不到就去尝试另一种。
因为对Nginx和Lua都不熟悉,以上也只是一种比较笨重的实现方式。学习后再来优化。
参考:
- nginx-api-for-lua
- nginx 获取body参数_nginx请求体读取
- Lua 参考手册
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)