04 23,2014

APP客户端上传文件引发NGINX返回411错误

昨天和android客户端联调一个上传接口的时候,客户端报错:”java.io.FileNotFoundException”,因为这个和IOS调试是正常的,然后我这边也没找到程序日记的请求记录,还以为是客户端的问题。

但是客户端查找了半天也没发现问题所在,没办法,查了下nginx的access日记。恍然发现,请求已经过来了,只是nginx返回411错误。

nginx给出的官方解释有三种情况会引发nginx弹411回去

client sent invalid "Content-Length" header
client sent method without "Content-Length" header
client sent "Transfer-Encoding: chunked" header

这个api使用的server正是nginx, 使用multipart提交图片文件的时候因为它忽略或省略了文件的真正的长度, 所以(通过抓包发现)在request header里就压根没有Content-Length. 那显然符合上面的第二种情况.

刚开始让android那边修改代码的,但是涉及到升级的问题,所以最好让服务端解决,google发现了这个nginx的module:nginxHttpChunkinModuleNginxHttpChunkinModule

nginx1.3.9以上的版本不需要这个模块了,所以这个针对的是nginx1.3.9以下的版本。

安装

首先下载这个模块,下载地址:https://github.com/agentzh/chunkin-nginx-module/tags ,选择你对应的nginx版本。

因为我的是nginx1.2.7版本,所以下载的是v0.23版本。

# cd /tmp
# wget https://github.com/agentzh/chunkin-nginx-module/archive/v0.23.tar.gz --content-disposition
//解压这个下载的文件重新编译nginx:
# tar -zvxf chunkin-nginx-module-0.23.tar.gz
//查看nginx的编译参数
# /usr/local/nginx/sbin/nginx -V

其中configure arguments就是你之前编译安装的参数。

nginx version: nginx/1.2.7
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) 
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

重新编译nginx

# cd /tmp/nginx1.2.7    //进入nginx的安装源
# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/tmp/chunkin-nginx-module-0.23

# make -j2
# make install

然后在nginx配置文件加上:

chunkin on;
error_page 411 = @my_411_error;
location @my_411_error {
    chunkin_resume;
}

这个时候启动nginx,上传已经正常了!