How should I go about handling http uploads that exceeds the post_max_size
in a sane manner?
In my configuration post_max_size
is a few MB larger than upload_max_filesize
The problems I'm having are:
If a user uploads a file exceeding post_max_size
- The _POST array is empty
- The _FILES array is empty, and of course any error codes therein are not present.
- No other info what kind of form post it is is accessible through theses means.
Part of the problem is that the receiving script takes different actions depending on the contents of the POST.
I do have access to the _SERVER
variables and can get clues as to what happened, i.e. CONTENT_TYPE
, CONTENT_LENGTH
and REQUEST_METHOD
. It does however seem very problematic to make guesses based on those contents.
MEMORY_LIMIT (set to 10 times the relevant sizes) and Apaches LimitRequestBody (set to unlimited) are found to not be at fault.
As it stands now I have a hard time even providing any meaningful messages to the user.
Is there any way to retain some form data to get better clues as to what has gone wrong? I'm very reluctant to move away from php.
Unless your upload form has fields other than the file input field, then $_POST should be empty - files are handled exclusively through the $_FILES. It's very odd that $_FILES would be empty if the post size is exceeded - the upload handlers have a specific error code (1/UPLOAD_ERR_INI_SIZE) to report such a condition. Also check that
memory_limit
is larger than the upload_max_filesize.Your webserver may be blocking the upload as well, which would occur before PHP is invoked. On Apache, it's controlled by
LimitRequestBody
.You can solve this on the server side without resorting to a query string. Just compare the *post_max_size* setting to the expected content length of the request. The following code is how Kohana does it.
You may need to revert to something that uses flash/silverlight etc. such as: http://www.plupload.com/
Or look at a Java-based solution...
Basically something that will break the upload into more managable (and resumable) chunks, and then re-assemble them on the server side.
I liked @Matthew answer, but needed a version that checked for multiple upload files.
This was my solution:
And, for completeness, here's the binding of the function to the form being submitted:
NOTE:
uploadMax is a variable that I set via php after calculating the maximum size of the allowable upload.
Per the PHP documentation:
If you need the limit increased for a specific script, you can try ini_set('post-max-size', $size_needed);. I'm not sure if it can be overridden within a script, though; that limit is probably there to specifically keep you from doing what you're trying to do.
For a simple fix that would require no server side changes, I would use the HTML5 File API to check the size of the file before uploading. If it exceeds the known limit, then cancel the upload. I believe something like this would work:
Obviously it's just a skeleton of an example, and not every browser supports this. But it wouldn't hurt to use this, as it could be implemented in such a way that it gracefully degrades into nothing for older browsers.
Of course this doesn't solve the issue, but it will at least keep a number of your users happy with minimal effort required. (And they won't even have to wait for the upload to fail.)
--
As an aside, checking
$_SERVER['CONTENT_LENGTH']
vs the size of the post and file data might help detect if something failed. I think it when there is an error it will be non zero, while the$_POST
and$_FILES
would both be empty.