在Lua + Nginx上踩过的坑

折腾了两三周,各种看文档查资料,总算把要支持的特性写好了,作为新手,简单记录下吧。

整个服务逻辑理解上不难,写起来也不太复杂,只是突然用以前只是听说过的语言Lua来写还是有些难度,而且以前没有处理过socket,理解上还是有些难度。好在公司内部培训简单的介绍了socket,再加上自己找资料去理解,写一些测试来验证,逐步也会用了。

新加的特性的HTTP Range请求,这个就是读RFC协议理解了。简单讲就是检查HTTP HEADER里的Range请求范围,错误就返回416 Range Not Satisfiable,正确就返回206 Partial Content,并发送指定Range的内容就好了。

因为对Nginx的Lua模块不熟(其实是没仔细看文档–!),在逻辑代码写完后,一直都会有两个问题出现:

  1. 返回的HTTP状态码问题;
  2. 多Range请求的Content-Length和多Range的长度不一致的问题。

第一个问题,明明应该返回206的状态码,一直返回200。问了下老大,说状态码应该在ngx.flush(true)前发送,而我一直是用return ngx.exit(206)。去HttpLuaNginx上的ngx.status上看了下,写的明明白白:

Read and write the current request’s response status. This should be called before sending out the response headers. Setting ngx.status after the response header is sent out has no effect but leaving an error message in your nginx’s error log file:

第二个问题,现在想想也挺捉急的。协议上写的很清楚,多Range请求,需要确定一个boundary字符串,在发送时用来分隔不同的Range。这就是为什么多个Range的内容长度比实际HTTP头里面的Content-Length小的原因!记得当时抓包,每次多Range时都会多出来40个字节的长度,现在了然了~~

最后写点感想:第一个问题时,在问老大之前,也是google了多久的,网上的答案也是千奇百怪的,有的说是头里面的Cache设置错误,有的说需要生成ETag。当时搜了下ETag的生成,貌似还挺复杂的,于是就跑去问老大这个状态码的问题,一句话点明,看了文档解决。所以说,在google之前,真的要RTFM啊!而google到的解决方法,只能作为参考,还是需要进一步去探究啊。