【问题标题】:Can PHP (with Apache or Nginx) check HTTP header before POST request finished?PHP(使用 Apache 或 Nginx)可以在 POST 请求完成之前检查 HTTP 标头吗?
【发布时间】:2013-04-13 15:30:24
【问题描述】:

这是一个简单的文件上传表单 HTML。

<form enctype="multipart/form-data" action="upload.php" method="POST">
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

而且 php 文件也很简单。

<?php
die();

如您所见,PHP 脚本在服务器端什么都不做。但是当我们上传一个大文件时,这个过程仍然需要很长时间。

我知道,我的 PHP 代码将在 POST 过程结束后执行。 PHP 必须在解析第一行代码之前准备名为 $_POST 和 $_FILES 的数组。

所以我的问题是:PHP(使用 Apache 或 Nginx)可以在 POST 请求完成之前检查 HTTP 标头吗?

例如,一些 PHP 扩展或 Apache 模块。

有人告诉我Python或者node.js可以解决这个问题,只是想知道PHP是否可以。

谢谢。

================ 更新1 ================

我的目标是尝试阻止一些意外的文件上传请求。例如,我们生成了一个唯一令牌作为 POST 目标 URL(如 http://some.com/upload.php?token=268dfd235ca2d64abd4cee42d61bde48&t=1366552126)。在服务器端,我的代码如下:

<?php
define(MY_SALT, 'mysalt');
if (!isset($_GET['t']) || !isset($_GET['token']) || abs(time()-$_GET['t'])>3600 || md5(MY_SALT.$_GET['t'])!=$_GET['token']) {//token check
    die('token incorrect or timeout');
}
//process the file uploaded
/* ... */

代码看起来很有意义:-P 但不能像我预期的那样节省带宽。原因是 PHP 代码运行太晚,我们无法在文件上传完成之前检查令牌。如果有人在 url 中上传没有正确令牌的文件,我的服务器的网络和 CPU 仍然浪费。

欢迎提出任何建议。非常感谢。

【问题讨论】:

  • 我要问的问题是你为什么要获取标题?原因是可能有更好的方法来实现您想要实现的目标。
  • @OkekeEmmanuelOluchukwu 感谢您的帮助,请查看我的更新内容。
  • 当你说“大”文件时,“大”是什么意思?说 1Gb、100Mb 只是给出一个范围,而且它总是大文件吗?

标签: php linux apache http file-upload


【解决方案1】:

HTTP 级别没有解决方案,但在TCP 级别是可能的。查看我在另一个问题中选择的答案:

Break HTTP file uploading from server side by PHP or Apache

【讨论】:

    【解决方案2】:

    答案总是肯定的,因为这是开源的。不过先说点背景:(我只说nginx,Apache也差不多)

    上传请求不会立即发送到您的 PHP 后端 - nginx 会缓冲上传正文,因此您的 PHP 应用程序不会占用 100MB 的 RAM 等待某人通过 300 波特调制解调器上传。不利的一面是,您的应用在上传完成或大部分完成上传(取决于client_body_buffer_size)之前甚至不会发现上传。

    但是您可以编写一个模块来挂钩到 nginx 内部的不同“阶段”。当标头完成时,将调用其中一个钩子。您可以在 LUA 中编写模块,但它仍然相当复杂。可能有一个模块会通过 HTTP 将“预上传”挂钩发送到您的脚本。但这不利于性能。

    很可能您甚至不需要模块。 nginx.conf 文件可以做你需要的。 (即根据标头将请求路由到不同的脚本,或根据标头返回不同的错误代码。)请参阅此页面以获取标头检查的示例(尤其是“WordPress w/ W3 Total Cache using Disk (Enhanced)”):http://kbeezie.com/nginx-configuration-examples/

    阅读文档,因为一些常见的标头检查需求已经有自己的指令(即,如果 Content-Length 标头太大,client_max_body_size 将拒绝请求。)

    【讨论】:

    • 对不起,恐怕你误解了我的问题。
    猜你喜欢
    • 2020-10-20
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多