0

I have an html form, including an input file element. The form is processed by a php script. Most of the time, everything works fine — I can access the form data through $_POST and $_FILES, I can check the data submitted and I can manipulate the file. The action on the form is set to return to the same page as that on which the form appears.

However, I am unable to process anything when the user tries to upload a file which is too large. This is what happens:

  1. Nothing gets uploaded and the page reloads.
  2. $_FILES['uploadFile']['error'] is null, so I can't catch the error.
  3. isset($_POST['submit']) is false, so I can't process the input.
  4. There is no error message.

My form looks like this:

<form action="hwsa.html?form[id_assignment]=<?php echo($id_assignment); ?>" method="post" enctype="multipart/form-data" class="assignment-submission">

    <p>Select file to upload. N.B. Only pdf files allowed; maximum size 5 MB.</p>
        <input type="hidden" name="MAX_FILE_SIZE" value="5120000" />
        <input type="file" name="uploadFile" id="assignment-file">
    </p>
    <p>
        <input type="submit" name="submit" value="Submit" class="btn-reverse">
        <input type="submit" name="submit" value="Cancel" class="btn-reverse">
    </p>
</form>

I can process other errors, like using the wrong file type, in a block like this:

If (isset($_POST['submit']))
{
    If ($_POST['submit']=='Cancel')
    {
        //Process cancel
    }
    If ($_POST['submit']=='Submit')
    {
        $size=$_FILES['uploadFile']['size'];
        $sizeWarning = ($_FILES['uploadFile']['size'] > 5120000);

        $fileType = strtolower(pathinfo($_FILES['uploadFile']['name'], PATHINFO_EXTENSION));
        $typeWarning = ($fileType != 'pdf');

        $emptyWarning = ($_FILES['upLoadFile']['size'] == 0);
        // Process errors or process successful upload.
    }
}

Any help would be greatly appreciated!

Thank you in advance.

  • what is the file size you try to upload and what is the max upload size of your server? – Baracuda078 Jul 29 '20 at 12:21
  • Does this answer your question? [Change the maximum upload file size](https://stackoverflow.com/questions/2184513/change-the-maximum-upload-file-size) – CBroe Jul 29 '20 at 12:21
  • You can also do the size and file type check in javascript, that way you can inform the user if there is something wrong without first posting all the data to the server. ALWAYS also check these info on the server side. Never trust data that is comming from the client side – Baracuda078 Jul 29 '20 at 12:26
  • @CBroe, thank you for your reply. No, that doesn't actually answer the question because I do want to keep the size limit in place. – Bruce Button Jul 29 '20 at 12:43
  • @Baracuda078 thank you for that suggestion. I will implement some Javascript to check that, but as you say, I still need to check on the server side. And that is where I am struggling. The size limit on the server is 8M. I am testing with various sizes both smaller and bigger than that. Smaller than 5M work fine, but 10M or more gives me this problem. – Bruce Button Jul 29 '20 at 12:47
  • _“because I do want to keep the size limit in place”_ - then you simply _can’t_ react to this from within your script. If the uploaded data goes beyond _those_ limits, then your PHP script does not get invoked in the first place, the whole process is cancelled before it even gets this far. – CBroe Jul 29 '20 at 13:30
  • @CBroe thank you for that clarification. That is very helpful. Is there perhaps another error message that I could react to (perhaps using Javascript) in order to give feedback to the user? – Bruce Button Jul 29 '20 at 13:33

1 Answers1

0

When a file upload is so large that it gets discarded you get an empty post request but original request headers are kept so you can do the following checks:

  • Determine if it's a post request and skip checks if isn't:

    $is_post = strtolower(filter_input(INPUT_SERVER, 'REQUEST_METHOD')) === 'post';
    
  • Determine if user agent (browser or script) sent a Content-Length header, maybe with a fallback check when $post_size is null (which will throw false positives if all form fields are optional):

    $post_size = $_SERVER['CONTENT_LENGTH'] ?? null;
    if (($post_size === null || $post_size > 0) && !$_POST && !$_FILES) {
        // Error: post body was too large
    }
    

You can test this code by setting an arbitrarily small size limit, e.g.:

post_max_size = 1K

Try thoroughly (I've used these ideas but I haven't tested this exact code).

Álvaro González
  • 142,137
  • 41
  • 261
  • 360