nginx上传client_max_body_size问题

时间:2011-02-09 15:46:18

标签: http file-upload nginx

我正在运行nginx / ruby​​-on-rails,我有一个简单的多部分表单来上传文件。 一切正常,直到我决定限制我想要上传的文件的最大大小。 为此,我将nginx client_max_body_size 设置为 1m (1MB),并在规则中断时响应HTTP 413(Request Entity Too Large)状态

问题是当我上传一个1.2 MB的文件而不是显示HTTP 413错误页面时,浏览器会挂起一点,然后在“页面加载时重置连接时死亡” “消息。

我已经尝试过nginx提供的每一个选项,似乎没什么用。有没有人对此有任何想法?

这是我的nginx.conf:

worker_processes  1;
timer_resolution  1000ms;
events {
    worker_connections  1024;
}

http {
    passenger_root /the_passenger_root;
    passenger_ruby /the_ruby;

    include       mime.types;
    default_type  application/octet-stream;

    sendfile           on;
    keepalive_timeout  65;

    server {
      listen 80;
      server_name www.x.com;
      client_max_body_size 1M;
      passenger_use_global_queue on;
      root /the_root;
      passenger_enabled on;

      error_page 404 /404.html;
      error_page 413 /413.html;    
    }    
}

感谢。


**Edit**

环境/ UA:Windows XP / Firefox 3.6.13

3 个答案:

答案 0 :(得分:122)

当客户端通过发送413响应并关闭连接来通知它将发送大于client_max_body_size的主体时,

nginx“快速失败”。

大多数客户端在发送整个请求正文之前不会读取响应。因为nginx关闭了连接,所以客户端将数据发送到已关闭的套接字,从而导致TCP RST。

如果您的HTTP客户端支持它,处理此问题的最佳方法是发送Expect: 100-Continue标头。 Nginx从1.2.7开始正确支持此功能,如果413 Request Entity Too Large超过最大正文大小,则会回复100 Continue响应,而不是Content-Length

答案 1 :(得分:48)

你的上传是否在最后死亡?崩溃前99%?客户端主体和缓冲区是关键,因为nginx必须缓冲传入的数据。 body配置(请求体的数据)指定nginx如何处理从多部分表单客户端到应用程序逻辑的二进制数据的批量流。

clean设置通过指示nginx将传入缓冲区存储在文件中,然后通过删除它从磁盘清除此文件来释放内存和使用限制。

body_in_file_only设置为clean并调整client_max_body_size的缓冲区。原始问题的配置已经有sendfile,也增加了超时。我使用下面的设置来修复此问题,适用于您的本地配置,服务器和& http上下文。

client_body_in_file_only clean;
client_body_buffer_size 32K;

client_max_body_size 300M;

sendfile on;
send_timeout 300s;

答案 2 :(得分:7)

来自the documentation

  

有必要记住,浏览器不知道如何正确显示此错误。

我怀疑这是正在发生的事情,如果您使用FirebugLive HTTP Headers(两个Firefox扩展程序)等工具来检查HTTP来回,您将能够看到实际发生的情况上。