I have to set up a form allowing the upload of videos whose weight is about 20GB for each.
This processing must be done in PHP.
I did a test with Plupload, but it does not work very well beyond 100MB: the file is uploaded, but its data is unusable (cf screenshot).
Do you have any recommendations/best practices?
Thanks.
Just found the solution, in your .js file that handle the upload you just need to add the multipart option and to put the value to false :)
It means that the chunk should be sent as binary stream (ie. multipart : false) and not as multipart/form-data (default ie. multipart : true)
If need here is an example on how I handled video files upload with Plupload :
https://github.com/Rapkalin/bigupload
Hope this helps :)
At first point you need to make some changes in your php.ini configuration file. Look for upload_max_filesize, post_max_size, then you should look for max_execution_time, max_input_time. As i can see your file is missing an extension, easiest and fastest way to handle this is:
$strpos = strpos($file, '.');
if (!$strpos) return false;
$name = substr($file, 0, $strpos);
$ext = substr($file, ($strpos + 1));
Now you can encode your name and append extension later. Also it will be good to paste your script or sample so we can look at it.
Related
I use Laravel 5.4 and I try upload video file. Image file upload successfully.
$video = Request::file('video_file')) {
$fullName = 'videos/'.uniqid().time().'.'.$video->getClientOriginalExtension();
Storage::disk()->put($fullName, $video);
But it didn't work. When I try get information about file - size = 0
What I do wrong?
There’s a limit on the amount of data you can send in a POST request. If you exceed that limit, PHP will return zero as the size of the file.
Instead, you’ll need to upload the file in chunks. If you’re using something like Amazon Web Services, they have a JavaScript SDK that will handle multi-part uploads for you: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
Check out http://php.net/manual/en/ini.core.php#ini.post-max-size
PHP has a default max_post_size of 8mb I believe, anything larger than that will not go through. There is also a upload_max_filesize that you may want to check out. I'm not sure if increasing the limit is the correct answer here, as I'm not sure what complications that would bring. When we upload large Files we use blue imp's file uploader: https://github.com/blueimp/jQuery-File-Upload
It's pretty straight forward and automatically chunks the uploads for you.
I am trying to take a pic upload from a mobile device to a server. We are building with PhoneGap (Javascript), so we are having turn it into a string in order to send it to the server. I am having problems once I receive it, to turn it back into a readable image file.
Simply put, I need to take a string and a file name sent to me, decode it, convert it into a .png, then crop it into a circular image.
This is what I have going on currently
if (isset($_POST['file']))
{
//Result variable
$result = false;
$pic = base64_decode($_POST['file']);
$filename = $_POST['filename'];
if (strlen($pic) > 9 )
{
$fh = fopen("/var/www/pics/events/".$filename, 'w') or die("can't open file");
fwrite($fh, $pic);
fclose($fh);
}
}
I think I can get the rest of the code to work if I can figure out what I am doing wrong here that makes it not save properly as a image file? The file uploads correctly, but it stores with out an extension, and when I point to it in my browser, it comes up like it is supposed to be an image file, but never displays the image. That little broken picture icon with the colored shapes is what I get when I direct to it's location.
Do I need to be aware of what image type is being sent during this process at all? How is it knowing if it is a .gif, .jpg/jpeg, .png, etc...?
Thanks in advance for any help!
Nathan
For Security reasons you should sanitize the file name to prevent directory traversal.
On a brighter note, make sure the file is saved with the proper extension; if you are already saving with the correct extension you could have an encoding issue from the app.
If neither of the previous possibilities are the case make sure that your String Size does not exceed the maximum POST size limit in your php.ini; if that is the case increase the size limit.
I'm implementing a user-based image uploading tool for my website. The system should allow any users to upload JPEG and PNG files only. I'm, of course, worried about security and so I'm wondering how the many smarter people than myself feel about the following checks for allowing uploads:
1) First white list the allowable file extensions in PHP to allow only PNG, png, jpg, JPG and JPEG. Retrieve the user's file's extension via a function such as:
return end(explode(".", $filename));
This should help disallow the user from uploading something malicious like .png.php. If this passes, move to step 2.
2) Run the php function getimageize() on the TMP file. Via something like:
getimagesize($_FILES['userfile']['tmp_name']);
If this does not return false, proceed.
3) Ensure a .htaccess file is placed within the uploads directory so that any files within this directory cannot parse PHP files:
php_admin_value engine Off
4) Rename the user's file to something pre-determined. I.E.
$filename = 'some_pre_determined_unique_value' . $the_file_extension;
This will also help prevent SQL injection as the filename will be the only user-determined variable in any queries used.
If I perform the above, how vulnerable for attack am I still? Before accepting a file I should hopefully have 1) only allowed jpgs and pngs, 2) Verified that PHP says it's a valid image, 3) disabled the directory the images are in from executing .php files and 4) renamed the users file to something unique.
Thanks,
Regarding file names, random names are definitely a good idea and take away a lot of headaches.
If you want to make totally sure the content is clean, consider using GD or ImageMagick to copy the incoming image 1:1 into a new, empty one.
That will slightly diminish image quality because content gets compressed twice, but it will remove any EXIF information present in the original image. Users are often not even aware how much info gets put into the Metadata section of JPG files! Camera info, position, times, software used... It's good policy for sites that host images to remove that info for the user.
Also, copying the image will probably get rid of most exploits that use faulty image data to cause overflows in the viewer software, and inject malicious code. Such manipulated images will probably simply turn out unreadable for GD.
Regarding your number 2), don't just check for FALSE. getimagesize will also return the mime type of the image. This is by far a more secure way to check proper image type than looking at the mime type the client supplies:
$info = getimagesize($_FILES['userfile']['tmp_name']);
if ($info === FALSE) {
die("Couldn't read image");
}
if (($info[2] !== IMAGETYPE_PNG) && ($info[2] !== IMAGETYPE_JPEG)) {
die("Not a JPEG or PNG");
}
All the checks seem good, number 3 in particular. If performance is not an issue, or you are doing this in the background, you could try accessing the image using GD and seeing if it is indeed an image and not just a bunch of crap that someone is trying to fill your server with.
Concerning No. 2, I read on php.net (documentation of the function getimagesize() ):
Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution such as the Fileinfo extension instead.
I am creating file upload script and I'm looking for the best techniques and practices to validate uploaded files.
Allowed extensions are:
$allowed_extensions = array('gif','jpg','png','swf','doc','docx','pdf','zip','rar','rtf','psd');
Here's the list of what I'm doing.
Checking file extension
$path_info = pathinfo($filename);
if( !in_array($path_info['extension'], $allowed_extensions) ) {
die('File #'.$i.': Incorrent file extension.');
}
Checking file mime type
$allowed_mimes = array('image/jpeg','image/png','image/gif','text/richtext','multipart/x-zip','application/x-shockwave-flash','application/msword','application/pdf','application/x-rar-compressed','image/vnd.adobe.photoshop');
if( !in_array(finfo_file($finfo, $file), $allowed_mimes) ) {
die('File #'.$i.': Incorrent mime type.');
}
Checking file size.
What should I do to make sure uploaded files are valid files? I noticed strange thing. I changed .jpg file extension to .zip and... it was uploaded. I thought it will have incorrect MIME type but after that I noticed I'm not checking for a specific type but if a specific MIME type exist in array. I'll fix it later, that presents no problems for me (of course if you got any good solution/idea, do not hesitate to share it, please).
I know what to do with images (try to resize, rotate, crop, etc.), but have no idea how to validate other extensions.
Now's time for my questions.
Do you know good techniques to validate such files? Maybe I should unpack archives for .zip/.rar files, but what about documents (doc, pdf)?
Will rotating, resizing work for .psd files?
Basically I thought that .psd file has following mime: application/octet-stream but when
I tried to upload .psd file it showed me (image/vnd.adobe.photoshop). I'm a bit confused about this. Do files always have the same MIME type?
Also, I cannot force code block to work. Does anyone have a guess as to why?
Lots of file formats have a pretty standard set of starting bytes to indicate the format. If you do a binary read for the first several bytes and test them against the start bytes of known formats it should be a fairly reliable way to confirm the file type matches the extension.
For example, JPEG's start bytes are 0xFF, 0xD8; so something like:
$fp = fopen("filename.jpg", "rb");
$startbytes = fread($fp, 8);
$chunked = str_split($startbytes,1);
if ($chunked[0] == 0xFF && $chunked[1] == 0xD8){
$exts[] = "jpg";
$exts[] = "jpeg";
}
then check against the exts.
could work.
If you want to validate images, a good thing to do is use getimagesize(), and see if it returns a valid set of sizes - or errors out if its an invalid image file. Or use a similar function for whatever files you are trying to support.
The key is that the file name means absolutely nothing. The file extensions (.jpg, etc), the mime types... are for humans.
The only way you can guarantee that a file is of the correct type is to open it and evaluate it byte by byte. That is, obviously, a pretty daunting task if you want to try to validate a large number of file types. At the simplest level, you'd look at the first few bytes of the file to ensure that they match what is expected of a file of that type.
Simple question. Is there a way to only allow txt files upon uploading? I've looked around and all I find is text/php, which allows PHP.
$uploaded_type=="text/php
When you upload a file with PHP its stored in the $_FILES array. Within this there is a key called "type" which has the mime type of the file EG $_FILES['file']['type']
So to check it is a txt file you do
if($_FILES['file']['type'] == 'text/plain'){
//Do stuff with it.
}
It's explained very well here. Also, don't rely on file extentions it's very unreliable.
Simply put: there's no way. Browsers don't consistently support type limiters on file upload fields (AFAIK that was planned or even is integrated into the HTML standard, but barely implemented at best). Both the file extension and mime-type information are user supplied and hence can't be trusted.
You can really only try to parse the file and see if it validates to whatever format you expect, that's the only reliable way. What you need to be careful with are buffer overflows and the like caused by maliciously malformed files. If all you want are text files, that's probably not such a big deal though.
You could check the mime type of the uploading file. In codeIgniter, this code is used in the upload library:
$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
The variable $this->file_type then used to check the upload configuration, to see if the uploaded file is in allowed type or not. You can see the complete code in the CodeIgniter upload library file.
You need to check the file extension of the uploaded file.
There is Pear HttpUpload, it supports this.