ngx.say使用Content-Length头问题

最近改老代码支持新的功能,改完部署到测试环境,模拟请求,后端响应结果正常,测试用例也能跑通,无意中看到了apisix打了一条waring日志:

apisix: 2021/04/19 14:02:17 [warn] 87#87: *26334356 upstream sent more data than specified in "Content-Length" header while reading upstream

看字面意思是响应的报文里超过了Content-Length头中设置的字节数

于是回过头翻看返回http响应部分的代码, 大致如下

ngx.header["Content-Type"] = 'application/json;charset=utf-8;'
ngx.header["Content-Length"] = string.len(resp)
ngx.say(resp)

可以看到返回响应前设置了Content-Length头,这个响应记录的是resp报文的长度,和实际发送的报文不一致

翻看官网的API文档可知,ngx.say会在发送的报文后面追加一个\n

Just as ngx.print but also emit a trailing newline.

通过抓包也印证了这个说明,可以看到最后一个字节0x0a就是追加的\n imgae

因此这里有下面几种改法

  1. 使用ngx.print替换ngx.say
  2. Content-Length头长度使用实际报文长度加1
  3. 去掉 Content-Length头,使用chunk方式输出

wechat
微信扫一扫,订阅我的博客动态^_^