views:

433

answers:

3

I'm using PHP for file uploads. In the PHP manual it shows an example using a MAX_FILE_SIZE hidden field, saying that it will detect on the client side (i.e. the browser) whether the file is too large or not.

I've just tried the example in Firefox, Chrome and IE and it doesn't work. The file is always uploaded, even if it is way larger than the specified hidden field.

Incidentally, if the file is larger than MAX_FILE_SIZE then calling move_uploaded_file doesn't work, so it seems the variable is having an effect server-side, but not client-side.

+2  A: 

On MAX_FILE_SIZE

Read This:

...At http://www.php.net/manual/en/features.file-upload.php#features.file-uplo ad.post-method and equivalent locations in other formats, it is stated that browsers take the value of a MAX_FILE_SIZE form field into account.

This information is repeated elsewhere on the web and in books, but appears to originate from the PHP documentation (it does not appear in terms of other server-side technologies).

There is nothing in any of the HTML, HTTP or related specs to indicate that this is the case (in particular RFC 1867 which introduced file uploads to HTML doesn't mention it, so it isn't even a case of a kludge that was mentioned in the first RFC and then dropped) nor does it make sense in the context of the HTML specs (there is nothing to indicate any relationship between that particular hidden input and the file input). The only statements about hidden fields I could find in any of them was warnings in the security considerations sections against user-agents basing any file-related operations on anything mentioned in a hidden field.

No browsers appear to perform this as an "extension". Indeed given that there are potentially other possible meanings for a hidden field with that name in an application handling several file uploads, it would have to be considered a design flaw any any did.

I submit that there is no such mechanism in mainstream browsers (if any at all) and indeed shouldn't be. Reference to it should be dropped from documentation.

I'd further suggest that since this idea has propagated from this documentation elsewhere that a note about it not working should to be added.

If a mechanism is required or desired for more rapidly handling this sort of file handling issue then it requires functionality to allow PHP to intercept streams being uploaded before request completion, which would be completely different to how this documentation suggest it should be dealt with, even if it was true...


the code below come from swfUplaod php implementation:

// Check post_max_size (http://us3.php.net/manual/en/features.file-upload.php#73762)
    $POST_MAX_SIZE = ini_get('post_max_size');
    $unit = strtoupper(substr($POST_MAX_SIZE, -1));
    $multiplier = ($unit == 'M' ? 1048576 : ($unit == 'K' ? 1024 : ($unit == 'G' ? 1073741824 : 1)));

    if ((int)$_SERVER['CONTENT_LENGTH'] > $multiplier*(int)$POST_MAX_SIZE && $POST_MAX_SIZE) {
        header("HTTP/1.1 500 Internal Server Error");
        echo "POST exceeded maximum allowed size.";
        exit(0);
    }
// Validate the file size (Warning the largest files supported by this code is 2GB)
    $max_file_size_in_bytes = 2147483647;           
    $file_size = @filesize($_FILES[$upload_name]["tmp_name"]);
        if (!$file_size || $file_size > $max_file_size_in_bytes) {
            HandleError("File exceeds the maximum allowed size");
            exit(0);
        }
aSeptik
+1; good investigation.
strager
`you need to verify the file uploaded was less than MAX_FILE_SIZE using PHP` no, you don't. Just get rid of this useless field
Col. Shrapnel
"requires functionality to allow PHP to intercept streams being uploaded before request completion" -> PHP can intercept request if its length exceeds the limit specified in `post_max_size`, but it requires browser to sent request header containing `Content-Length`, and from modern browsers only Opera seems to be sending this header.
dev-null-dweller
aSeptik, the question was about client-side validation. Your edited code has no more sense than previous one. I appreciate the little search job you've done, but all in vain. One need some practical experience to answer questions, not only search skills.
Col. Shrapnel
@Col. Shrapnel - the sense is that since MAX_FILE_SIZE can't be 100% reliable you must set a variable to store your want max file size!
aSeptik
You have it already - an `upload_max_filesize` setting
Col. Shrapnel
@dev-null-deweller - so!? all the method provided by you make use of flash for achieve the result! my answer is simple and concise! i think the OP already know all the link you have provided!
aSeptik
@Col. Shrapnel - the OP alrady know **upload_max_filesize** directive he come from the php.net page!
aSeptik
So, he doesn't need anything else. if (isset($_FILES['file']['error']) and $_FILES['file']['error']===0) is enough. And he has asking for the **client side** solution
Col. Shrapnel
@Col. Shrapnel - Question title can be sometimes ambiguous and can differ from what is asked in the post (the content of post is entirely related to the MAX_FILE_SIZE)! btw in my very first post that i have deleted i have also mentioned the use of upload_max_filesize directive! the problem here is just with people that must downvote at any cost, cause is supposed, they have not only search skills!
aSeptik
+1  A: 

As far as I know there is no simple, cross-browser solution to achieve this. The only working solutions are Flash or Java based since these technologies can access filesystem and get file info.

Example scripts: YUI2 Uploader, FancyUpload, SWFUpload

dev-null-dweller
+1  A: 

This probably only works on Firefox 3.6 for now:

<script type="text/javascript">
    function checkSize()
    {
        var input = document.getElementById("upload");

        // check for browser support (may need to be modified)
        if(input.files && input.files.length == 1)
        {           
            if (input.files[0].fileSize > 1024) /* or maybe .size */
            {
                alert("The file must be less than 1KB");
                return false;
            }
        }

        return true;
    }
</script>


<form method="post" enctype="multipart/form-data" onsubmit="return checkSize()">    
    <input type="file" id="upload" />
    <input type="submit" />
</form>

See http://www.w3.org/TR/FileAPI/.

konforce