使用openresty接收curl请求参数为true的问题

前段时间使用openresty网关接收请求时,总会有零星的500错误出现。查看日志发现是在参数校验的地方出错。服务的参数校验部分主要功能除了判断参数是否存在以外,还需要判断输入的文本长度,以确定走长文本逻辑还是短文本逻辑。部分代码如下:

ngx.req.read_body()
local post_args ,err = ngx.req.get_post_args()
ngx.log(ngx.INFO,string.format('post_args: %s',cjson.encode(post_args)))
if not post_args['content'] then
	--此处省略打印日志部分及结果处理部分
	ngx.say("error")
	ngx.exit(ngx.OK)
end
local text = post_args['content']
local textlen = util.get_strlen(text)
local long = false
if textlen > 200 then
    long = true
end

正常情况下这段代码是没有问题的,它做的事情包括:

1.获取参数
2.判断content字段是否存在
3.判断content是否超过200个字

但是在其他业务方使用java调用的时候会出现错误,报错信息为:

stack traceback:
coroutine 0:
    [builtin:len]: in function 'len'
    /home/app/xxx/nginx/lua-script/util.lua:306: in function 'get_strlen'
    ...p/xxx/nginx/lua-script/text-v2.lua:269: in function 'xxx'
    ...p/xxx/nginx/lua-script/text-v2.lua:346: in function <...p/xxx/nginx/lua-script/text-v2.lua:1>, client: 10.112.81.41, server: localhost, request: "POST /aa/text-v2 HTTP/1.1", host: "text.prd.xxx.xx"

入参打印出来后的结果为

post_args:{"content":true,"bid":"thisistest"}

参数为什么会出现bool型
使用openresty接收curl请求参数为true的问题_第1张图片
后来通过交流,发现是调用方在被上游调用的时候content参数没有传,而他在编码的时候是使用java的map用于参数存储的。虽然不懂java,但问题好歹找到了,最重要的是可以复现了。
通过抓包,终于找到了参数传递的方式。对应的curl命令为:

curl --location --request POST 'http://localhost:8080/text' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'bid=3' --data-urlencode 'content'

终于找到了问题。始终让人疑惑的是为什么参数没有值,openresty里面却会默认给它赋值为true。造成代码里面参数校验时if not post_args["content"]这样的判断语句也会无法拦截。
接下来就可以解决问题了。让调用方改变调用方式或直接判断类型做参数拦截都可以

你可能感兴趣的:(随手记)