【问题标题】:How to stop a oversize file upload while upload is in process?如何在上传过程中停止超大文件上传?
【发布时间】:2012-02-20 21:18:17
【问题描述】:

我正在使用 apache、PHP。

所以,对于 php,即使我设置了最大文件大小,如果有人上传一个大文件,它会将整个文件上传到服务器,然后 PHP 返回错误。那正确吗?

当文件大小或请求大小大于特定大小时,我希望 Web 服务器或 PHP 停止。

有办法吗?我记得像设置 post_max_size 或在 apache.conf 中设置一些东西,但不确定当文件超过最大限制时它是否会停止。

  • 我不信任客户端验证。所以,我正在寻找 apache 或 php 级别的解决方案。 :)

【问题讨论】:

  • 客户端验证非常人性化,看HTML5 File API。它当然还需要服务器端验证。

标签: php apache file-upload size limit


【解决方案1】:

Apache's LimitRequestBody,afaik,它只是在结束时停止连接......

【讨论】:

  • 这可行,但会为您提供 Apache 错误页面,而不是将控制权传递给 PHP。错误代码为 413,可以通过 ErrorDocument 选项处理。但是,某些版本中的一个奇怪的 Apache 错误会导致所请求的页面返回除了错误文档。狂野!
  • 为了增加乐趣,一些 Apache 版本会跳过错误页面并在达到限制时硬关闭连接。某些版本会显示超出限制的某个大小的错误,但会在其他(任意)限制处关闭连接。
  • 好吧,不要在损坏的 Apache 上运行它然后 :P 你是对的当然,它确实不是很用户友好。然而,它确实符合“我希望 Web 服务器或 PHP 停止” 的要求,选择第一个。除了在网络服务器前面放置一些代理之外,我不知道另一种方法。
  • 如果我如此偏执地降低LimitRequestBody 相当大,我实际上会对硬关闭感到满意,尽管它确实违反了 HTTP 协议。我怀疑任意限制与如何从输入流中读取块有关,在 1 中读取的一定数量的字节超出了限制。
  • 我将 LimitRequestBodyErrorDocument 413 http://error-message-url-here/ 结合使用 - 效果很好,谢谢!
【解决方案2】:

max_execution_time 和 max_input_time 这些设置定义了脚本的最长生命周期以及脚本在接受输入时应该花费的时间。如果正在传输几兆字节的数据,则 max_input_time 应该相当高。您可以通过在脚本中调用 set_time_limit() 函数来覆盖 ini 文件中 max_input_time 的设置。

这取自http://www.radinks.com/upload/config.php

如果您为这些 ini 条目设置较低的值,则脚本应该在上传完成之前超时

【讨论】:

  • max_execution_time 根本不包括文件上传。 max_input_time 只是 parse 时间,即使对于数 GB 的上传,也通常是亚秒级。这些设置在这里没有帮助。
【解决方案3】:

无法从服务器端阻止它 - 在 PHP 决定是否拒绝之前,文件仍将被上传。您需要在客户端添加该检测。虽然您无法使用常规 HTML 表单执行此操作,但 Flash 上传者可以在上传开始之前找出文件大小。

在服务器端,你不能用 PHP 做任何有用的事情——在 PHP 有机会说“不”之前,文件总是已经完全上传。要阻止上传(即通过 POST 断开客户端的一部分),您需要一些 Web 服务器魔法来降低堆栈。 Perlbal 能够做到这一点。编写自己的 Apache 模块是一种(蛮力)解决方案。如果您担心大型上传会占用网络服务器资源,那么在您的主网络服务器前使用任何类型的轻量级代理都是一种解决方案。

这真的取决于为什么您要限制大型上传。如果是为了节省用户时间,只需添加指定最大文件大小的消息即可。如果是服务器资源,在服务器前使用轻量级代理。如果是别的东西,那么它是什么?

【讨论】:

  • 从不做客户端验证
  • 服务器可以随时停止下载。我敢打赌有一个解决方案,我只是不确定它的级别有多低。
  • @ordag,永远依赖客户端验证 ;-)
  • 原因是,我们甚至不希望文件本地存储在 tmp 中。 PHP 将在应用程序本身检查图像之前将图像存储在 /tmp 中。如果我可以检测到 http 请求大小并在超出限制时拒绝它会更好。 :)
【解决方案4】:

使用名为MAX_FILE_SIZE 的隐藏字段,其值指示最大文件大小(以字节为单位)。 See Example #1 on this page 了解更多信息。

<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

【讨论】:

  • MAX_FILE_SIZE 只是一个自愿的用户指示器,因此浏览器可以警告客户端,它绝不是强制/可执行的。
  • 我原本也是这么想的,但是PHP手册让我觉得如果上传太大就立即丢弃。在某种程度上,如果不是这种情况是有道理的,但这取决于发送的有关文件的“元数据”。对于不正确的信息,我深表歉意。
  • 就浏览器而言,这并没有做任何事情,它所做的只是在 POST 数据中发送一个附加值。见stackoverflow.com/q/1381364/247696
【解决方案5】:

这里是一个简单的jquery解决方案How to check file input size with jQuery? 但是客户端验证很容易被黑客入侵。

【讨论】:

    【解决方案6】:

    在 php.ini 中使用 $_FILES。

    if($_FILES['name']['size'] > $limit){
    // continue;
    }
    

    【讨论】:

    • 我相信这个代码会在上传完成后执行。
    【解决方案7】:

    使用 PHP 5.5 中的会话进度功能为每次上传使用计时器(超时),并测量每个上传大小的平均时间。

    【讨论】:

      猜你喜欢
      • 2017-10-23
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多