1

Here is a simple file upload form 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>

And the php file is pretty simple too.

<?php
die();

As you see, the PHP script do nothing in server side. But when we uploading a big file, the process still cost a long time.

I know, my PHP code will executed after the POST process ended. PHP MUST prepare the array named $_POST and $_FILES before the first line code parsed.

So my question is: Can PHP (with Apache or Nginx) check HTTP header before POST request finished?

For example, some PHP extensions or Apache modules.

I was told that Python or node.js can resolve this problem, just want to know if PHP can or not.

Thanks.

================ UPDATE 1 ================

My target is try to block some unexpected file-upload request. For example, we generated a unique token as POST target url (like http://some.com/upload.php?token=268dfd235ca2d64abd4cee42d61bde48&t=1366552126). In server side, my code like:

<?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
/* ... */

Code looks make sense :-P but cannot save bandwidth as I expected. The reason is PHP code runs too late, we cannot check token before file uploading finished. If someone upload file without correct token in url, the network and CPU of my server still wasted.

Any suggestion is welcome. Thanks a lot.

Alix
  • 256
  • 3
  • 17
  • The question I'll ask is why do you want to get the headers? The reason is there might be better ways to achieve what you're trying to achieve. – Emmanuel Okeke Apr 20 '13 at 12:41
  • When u say 'big' file, how 'big' do you mean? say 1Gb, 100Mb just give a range and also is it always large files? – Emmanuel Okeke Apr 22 '13 at 09:41

2 Answers2

1

The answer is always yes because this is Open Source. But first, some background: (I'm only going to talk about nginx, but Apache is almost the same.)

The upload request isn't sent to your PHP backend right away -- nginx buffers the upload body so your PHP app isn't tying up 100MB of RAM waiting for some guy to upload via a 300 baud modem. The downside is that your app doesn't even find out about the upload until it's done or mostly done uploading (depending on client_body_buffer_size).

But you can write a module to hook into the different "phases" internally to nginx. One of the hooks are called when the headers are done. You can write modules in LUA, but it's sill fairly complex. There may be a module that will send the "pre-upload" hook out to your script via HTTP. But that's not great for performance.

It's very likely you won't even need a module. The nginx.conf files can do what you need. (i.e. route the request to different scripts based on headers, or return different error codes based on headers.) See this page for examples of header checking (especially "WordPress w/ W3 Total Cache using Disk (Enhanced)"): http://kbeezie.com/nginx-configuration-examples/

Read the docs, because some common header-checking needs already have directives of their own (i.e. client_max_body_size will reject a request if the Content-Length header is too big.)

BraveNewCurrency
  • 12,654
  • 2
  • 42
  • 50
1

There is no solution in HTTP level, but is possible in TCP level. See the answer I chose in another question:

Break HTTP file uploading from server side by PHP or Apache

Community
  • 1
  • 1
Alix
  • 256
  • 3
  • 17