【问题标题】:nginx upload client_max_body_size issuenginx上传client_max_body_size问题
【发布时间】:2011-06-24 05:50:54
【问题描述】:

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

问题是,当我上传一个 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

【问题讨论】:

    标签: http file-upload nginx


    【解决方案1】:

    来自the documentation

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

    我怀疑这是正在发生的事情,如果您使用诸如 FirebugLive HTTP Headers(两个 Firefox 扩展)之类的工具检查 HTTP 来回,您将能够看到真正发生的事情。

    【讨论】:

    • 我在这里也遇到过这种情况:forum.nginx.org/read.php?2,2620 nginx 作者说人们可以尝试更改 lingering_time/lingering_timeout - 这两种方法对我的情况都没有影响。此外,当我上传具有 1MB 限制的 1.2MB 文件时,我只是看不到如何会出现持续的超时问题,并且很容易获得稳定的 5Mbps 连接。我嗅到了响应,它确实发送了带有“连接:关闭”标题的 413 页面,但连接似乎没有关闭。
    • 我想我很难相信即使有一个完全有效的 413 HTTP 状态,它也不会在浏览器中触发。我用谷歌搜索了很多人们无法摆脱该页面的地方,但我什至从未见过它。
    • 如果你禁用乘客,它会关闭连接吗?
    • 嗯,我比较了有乘客和没有乘客的反应。当一切正常运行并且我上传的文件比我的 1MB 限制大几倍(~14MB)时,我多次收到 413 响应(因为客户端不断发送块)并且最终的“连接重置”看起来确实像超时。如果没有乘客,我会收到一个 413 即时响应并且所有进度都停止,但我仍然看到“连接重置”页面,而不是我的静态 413.html 或任何暗示“实体太大”的内容
    【解决方案2】:

    当客户端通过发送 413 响应并关闭连接来通知它将发送大于 client_max_body_size 的正文时,nginx“快速失败”。

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

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

    【讨论】:

    • 哦,我应该指出,这个答案假设客户端发送Content-Length,而不是发送Transfer-Encoding: chunked
    • nginx 作者在邮件列表上发布了一个补丁来解决这个问题:nginx.2469901.n2.nabble.com/… 不过,它是否会被添加到 1.2.x 稳定分支中尚无定论。
    • 谢谢,这实际上解释了很多。当然看起来Expect 是处理大型请求的方式。
    • 更新了我的回答,指出我之前提到的补丁已提交并合并到 1.2.7 版本中。
    • 只是为了节省寻找好语法的时间(就像我花的那样):request.setHeader(HttpHeaders.EXPECT, CONTINUE);import org.apache.http.HttpHeaders;import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.CONTINUE;
    【解决方案3】:

    你的上传最后会死吗?崩溃前99%?客户端主体和缓冲区是关键,因为 nginx 必须缓冲传入的数据。正文配置(请求正文的数据)指定 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;
    

    【讨论】:

    • 即使这确实导致 nginx 返回正确的 HTTP 413,UA 最终仍会发送整个请求正文,不是吗?在这种情况下,我认为值得尝试@joe-shaw 建议的方法。
    • @krukid 看起来我们在 NGINX “快速失败”之前完成了 99% 的上传,我同意你的看法。在这种情况下,请求对象周围的所有迹象都是积极的,即诊断是内部服务器应用程序逻辑正常 - 无论在 Nginx 后面运行什么。因此,虽然请求可能已经形成良好的格式,但我们需要考虑为什么 NGINX 会在响应时阻塞。 client_max_body_size 应该是我们查看的第一个配置选项,然后考虑缓冲区,因为如果上传足够大,正确的解决方案取决于我们的服务器也可以处理多少内存。
    • @Bent Cardan。这种方法似乎更好,我试过了。但是对于一个 4mb 的文件,大约 20 秒后我仍然收到 413 错误。我的 upspeeds 无法在 20 秒内管理 4 MB,所以它是在数据流动了相当长一段时间后发生的。想法?
    • 我已经在nginx.conf文件中添加了更改_client_max_body_size 300M; sendfile on;send_timeout 300s; _ 它非常适合我谢谢
    • 解决方案适用于openshift php7 nginx
    猜你喜欢
    • 2018-02-20
    • 2020-12-31
    • 2015-04-13
    • 1970-01-01
    • 2013-05-31
    • 2012-02-21
    • 2018-12-06
    • 2017-01-02
    • 2011-01-04
    相关资源
    最近更新 更多