【问题标题】:Cancel an HTTP POST request server side取消一个 HTTP POST 请求服务器端
【发布时间】:2011-06-01 06:42:30
【问题描述】:

我正在尝试编写一个用于上传大文件 (>500MB) 的脚本。我想在处理上传之前进行一些身份验证,例如:

$id = $_GET['key'];
$size = $_GET['size'];
$time = $_GET['time'];
$signature = $_GET['signature'];

$secret = 'asdfgh123456';

if(sha1($id.$size.$time.$secret) != $signature){
echo 'invalid signature';
exit;
}
process upload...

不幸的是,php 仅在文件上传到临时目录后才运行此代码,占用了宝贵的服务器资源。在上传之前有没有办法做到这一点?我用 perl/cgi 尝试过类似的事情,但发生了同样的事情。

【问题讨论】:

    标签: php perl http post


    【解决方案1】:

    哇,已经有 5 个答案说明了它是如何做到的。 mod_perl to the rescue,在这里你可以在整个请求正文上传之前拒绝一个请求。

    【讨论】:

    • 哇,谢谢。你给了我一线希望 :] 我不是 perl 程序员(因此是 php 代码),但我会做一些阅读,看看我能不能让它工作。
    • 我的身份验证函数现在使用 PerlPostReadRequestHandler 处理程序。我可能可以将它放在处理程序堆栈的更下方,但它工作正常。
    • 客户端的Flash上​​传器有点困惑,在返回错误之前上传了一段时间,但它肯定会停止服务器端的上传。谢谢!
    • 谢谢。我正在将大文件从 Flash 上传到 ASP.NET。我已经实现了一个 HttpModule,它调用 HttpContext.GetService(typeof(HttpWorkerRequest)) 来检索一个 HttpWorkerRequest,它允许我在上传实体主体流时访问它。这也允许我提前关闭工作人员请求的连接以立即停止客户端上的上传,例如,如果我想在执行某些身份验证后取消上传。当我以这种方式关闭连接时,Flash 客户端完全没有混淆;上传立即停止。
    【解决方案2】:

    Apache 会在调用 PHP 脚本之前负责上传,因此您将无法访问它。

    您可以将流程拆分为两个页面(身份验证、文件上传页面),或者,如果您需要在一页中完成所有操作,请在检查身份验证参数后使用 AJAX 式解决方案来上传文件。

    【讨论】:

    • 除了,您显然无法从 JavaScript 访问文件大小。 google.com/…,虽然理论上可以在有限的支持下使用 HTML5-ish File API stackoverflow.com/questions/1606842/…
    • @yc:对。无法在客户端检查文件大小。这是一种权衡。
    • 我主要担心的是恶意用户使用大量无效上传来破坏服务器。有什么办法可以预防吗?
    • @Jack000,PHP 不是对抗 DDOS 攻击的合适域。人们可以将文件发布到任何 uri,而不仅仅是 PHP 的。您需要研究较低级别的网络解决方案。见:en.wikipedia.org/wiki/Ddos#Prevention_and_response
    • 感谢您的提示。看来我必须在 apache 级别解决问题。
    【解决方案3】:

    据我所知,您无法在 PHP 中做到这一点。 PHP 脚本响应请求而启动,但在文件上传之前不会“发送”请求,因为上传的文件是请求的一部分。

    【讨论】:

      【解决方案4】:

      这在您上传到的 PHP 脚本中绝对不可能。

      最简单的可能性确实是在上传之前提供一步验证。

      如果这不是一个选项,我会想到一个稍微奇怪的可能性 - 使用 RewriteMap 并将其映射到外部程序(应该可以使该程序成为 PHP 脚本)。

      使用RewriteMap 可以根据命令行程序的输出重写 URL。如果您使用此指令调用(单独的)PHP 脚本 - 但是您将无法使用用户的会话! - 在处理请求之前,您可以访问 GET 参数。

      如果处理失败(= 凭据无效),您可以将请求重定向到静态资源,这至少会阻止 PHP 启动。 (我假设上传的内容无论如何都会占用 一些 资源,但可能比重定向到 PHP 时要少。)

      不保证这是否可行!我对RewriteMap 没有经验。

      【讨论】:

        【解决方案5】:

        这是因为每个 HTTP 请求都是一个单独的包含 所有的表单/POST 数据,包括文件上传数据。

        因此,我认为无论您使用哪种脚本语言,都无法以这种方式处理文件上传请求。

        【讨论】:

        • 服务器当然可以在整个请求提交之前处理headers。框架是否可以访问这些数据完全是另一回事。
        • @EricLaw -MSFT- 理论上它显然可以(毕竟它只是一个正在进行的 I/O 流),但我从未见过这种能力暴露出来。
        【解决方案6】:

        我认为你做不到。您可以做的最好的事情可能是先运行 AJAX 函数 onSubmit 进行验证,然后如果它返回有效,则执行 POST 以上传文件。如果身份验证有效,您可以在 AJAX 脚本中设置 $_SESSION,然后在上传脚本中检查该会话变量以允许上传。

        【讨论】:

          猜你喜欢
          • 2017-09-07
          • 2017-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-27
          • 2013-04-14
          • 2019-04-26
          • 2020-01-09
          相关资源
          最近更新 更多