【问题标题】:apache commons FileUpload - cutting off large files before whole file uploadedapache commons FileUpload - 在整个文件上传之前切断大文件
【发布时间】:2012-06-01 12:46:30
【问题描述】:

使用 Tomcat 6,我使用 apache commons FileUpload 来允许图像上传。我可以使用 setSizeMax 和 setFileSizeMax 设置最大文件。但似乎上传了整个大文件,然后检查它是否太大。根据另一个post,似乎 setSizeMax 应该切断上传,但这不是我得到的行为。

为了测试这一点,我将 sizeMax 和 fieSizeMax 设置得很低,并上传了一个相当大的文件。上传大文件需要 15 秒,而不是几乎瞬间将其切断。

有什么想法吗?这是一些代码,带有简化的异常子句。

    FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setFileSizeMax(30);
        upload.setSizeMax(28);
        List items = null;
        try {
            items = upload.parseRequest(request);
        } catch (Exception e) {
            out.println("exceeded max file size..");
            return;
        }

更多信息:使用 tomcat 6. 设置 maxPostSize 不适用于内容类型:multipart/form-data。此外,再次检查请求内容长度需要上传整个文件。最后,使用 FileUpload 的 steaming api 似乎也不起作用,因为它似乎再次要求在关闭流之前上传整个文件;即使 servlet 没有将字节写入磁盘,上传也会继续。必须有一种方法可以防止使用 tomcat 6 进行大量上传,因为上传图片等对于网络应用来说是一项非常常见的任务。

【问题讨论】:

  • 如果您可以要求您的用户使用兼容 HTML5 的浏览器,那么您可以在客户端进行验证。见*.com/questions/4112575/…
  • @rickz - 依靠客户端检查/验证来保护服务器端绝不是一个好主意。颠覆支票太容易了。
  • @StephenC 这不会带来安全风险。这只是提高 Web 应用程序性能的一种努力。如果客户端验证失败,那么服务器总是可以拒绝上传。
  • @rickz - 我的印象是 OP 正试图保护整体系统性能免受下载巨大文件的人的影响。这是一个拒绝服务问题,不难想象有人故意这样做......
  • @rickz - “如果客户端验证失败,那么服务器总是可以拒绝上传。”。另一方面,如果(被破坏的)客户端跳过验证并告诉服务器“没问题”,那么服务器就会收到不好的东西。人们一直在做这种事情,假装不这样是愚蠢的。

标签: java apache servlets file-upload size


【解决方案1】:

无论您是否将它们保存在服务器上,客户端都会发送这些位。服务器没有办法告诉客户端停止发送比特,而不是强制关闭输入流(因为 HTTP 的性质:响应跟随请求——它们不是同时的)。您可以尝试这样做,但大多数应用程序服务器会在您执行 close() 时从客户端排出输入流,因此不会有任何变化。

如果您可以控制客户端并要求使用 100-Continue(通过 Expect 标头),您可以窥探请求的 Content-Length 并通过发送否定回复而不是 100-Continue 来拒绝它.

【讨论】:

    【解决方案2】:

    Tomcat 的 HTTP 连接器有一个 maxPostSize 属性。见Tomcat docs

    编辑: 太糟糕了,它不适用于 multipart/form-data。您是否考虑过使用签名的 Applet 或使用“Java Web Start”来管理上传?

    【讨论】:

    • 据我所知, request.getContentLength 一直等到整个文件上传完毕。因此,仍然会完全上传一个巨大的文件,然后您可以运行该测试。这就是我得到的。
    • maxPostSize 不适用于内容类型的多部分/表单数据。它仅适用于内容类型 application/x-www-form-urlencoded。因此,设置 maxPostSize 对通过 Web 表单上传图像等典型情况没有影响。在我的测试中,对于通常使用 apache commons FileUpload 的情况,maxPostSize 完全被忽略。请参阅此帖子:link 进行讨论。
    • 在之前的解决方案中,我使用了一个小程序来控制这种类型的场景,但那是一个为更复杂的社区设计的应用程序。对于我当前项目的这一部分,要求是用户可以简单地上传图像。我认为签名的小程序会让用户感到困惑。人们一直在开发 webapp 来处理上传图片,所以必须有一个标准的方法。或者也许我应该选择另一种类型的服务器来处理上传?核心应用程序仍然在 java 中,但我可以使用专用的 VPS 和另一种技术进行上传?任何建议
    • 常见的选择是使用Tomcat前面的Apache Web Server。它具有 LimitRequestBody 指令。我自己没有经验。也许您将不得不问另一个问题才能找到 Apache 专家。