I am working on a website in which it would be useful to to allow a user the option of downloading the content of a file, even when it's going to be updated by another user at the same time or later.
My problem is that the solution I've tried so far allows downloading, but will disrupt any later updating of the file. I don't think I can represent the code relating to the updating concisely (it is spread over multiple files), except that it's through AJAXing the data (which I'm not sure why it would cause this problem). In case it's relevant, this is a file which gets updated multiple times.
When I use fireftp I can download the file without disrupting this process, which makes me optimistic there's a PhP solution. I am currently downloading the data by Ajaxing the file contents to the page the "downloading user" is on. The code for this (within php) is:
$file_contents = file_get_contents ($_POST['file'])); //file address comes through Ajax POST request.
echo ($file_contents); //to access the content client side
Is there another way to access the text/content within a file without any unintended consequences on other server processing of it?
I am creating an upload interface to upload files in php.
Files are uploading fine.
But I want to give the user some feedback as how much time will it take to upload, how much of the uploading has been done etc..
I have found online code which gives ajax plugin to do what I want.
BUT my question is more fundamental, WHERE do I get the data in php that tells me how much of the file is received? what is the connection speed(connection speed and file size can be used to get time left) and other information needed?
can i get the data form php or am i looking at the wrong place?
Everything is in the documentation:
http://www.php.net/manual/en/session.upload-progress.php
WHERE do i get the data in php that tells me how much of the file is received
You don't. Uploading is handled by the webserver. When the upload is complete your PHP script will run and it gets a reference to the temp file(s) created by your webserver.
I think there are plugins or mods that do allow you to monitor theses processes. There is session.uploader-progress.php
but there is a much easier solution!
Use the JS FileReader API to slice the file into small chunks (like 5mb) then you can already make a pretty good loading bar. Additionally you can monitor the progress of XMLHTTPRequests to see how many bytes have been sent. This should get you a pretty spot on progress indicator.
This also alleviates common problems with exceeding max_upload_size.
An actual code solution is quite involved so I will refrain from posting one. You should be able to find samples or tutorials.
I have a quick question if anyone could help. I am building a CMS for a client where they can log in, and change content (including pictures via upload file form) that are all stored in a database.
My question.. I have been researching, and everywhere says I need to store the image files outside the root folder. Is this necessary in my case if only a few people will be uploading files, inside an admin panel, where they must first log in to the site? I will have already taken steps client side by making sure of file type, size, extension etc... then changing the name of the file before adding it to my DB... Is this secure enough, or am I asking for trouble down the road?
Thanks
Its generally a good idea to store uploaded content someplace where it cant directly be addressed by a browser. You dont want someone uploading a .php file (or some other format you forgot to check for) and then being able execute it by pulling up the direct url. Rather, you'd have a wrapper script that delivered the file.
So yes, its a good idea, but not 'necessary' (by the dictionary definition of the word). You can certainly choose not to do so if in your judgement the admin area is otherwise secure.
That said, in the scenario you describe, as long as its only admin users who can upload images, I dont think its a huge deal either way.
btw, if you are not already, verify the images by their file headers or content, not file extension.
Alright, so a little preface: I've been working on adding drag and drop file uploading to the course management system called Moodle (specifically 2.0.1). This version of Moodle uses the YUI3 framework and uploads the form data with the file to be uploaded and the save-as name through an io-upload-iframe. The file is stored in the super global $_FILES until the filesystem is sent the relevant data on where to store it permanently.
The trouble I'm having is that instead of using YUI3's drag and drop features (Which, from a cursory look at their website is not the kind of drag and drop I need anyways) I'm using the native HTML5 drag and drop code. This seems to work in most major browsers (I haven't had the time to test much, and it's outside the scope of this project). The trouble I'm having is that this design of DND immediately gives you a file from the Event object in javascript. I could send this file object off to wherever I want, but the filesystem is only designed to handle variables temporarily stored in the $_FILES variable. I've not been able to find any easy way of getting this file stored there, unfortunately. I could to an HTTP request of various forms (either one of YUI3's special Y.io() requests or an XHR), but this requires a lot of duplicated code from the original source code.
Anybody have some suggestions?
Hard to tell what your problem is. But whatever your server or filesystem is, it has nothing to do with the temporarity of the $_FILES array.
When you receive the DND event, and YUI subsequently sends the file, then you will receive some data either in $_FILES or in $_POST. If so, just use move_uploaded_file or file_put_contents and store it elsewhere.
Assign that moved file a md5() hash as name, and have that returned as file identifier for your AJAX-DND upload request.
You can then use that hash id in your Javascript code, and refer to the already uploaded image file by this reference. Should your app initiate a normal form request after the drag'n'dropping, then you just include the collected image reference ids. And thus your server-side code can associate it again.
You could even reconstruct the $_FILES array if you want to:
foreach ((array)$_POST["prev_image_ids"] as $md5) {
$md5 = basename($md5);
$_FILES["image"][] = array(
"tmp_name" => $fn="./already-uploaded/$md5",
"size" => filesize($fn), "type"=>"image/whatever",
"name" => "unknown.jpg", "error"=>UPLOAD_ERR_OK,
); // you could store away those original attributes too
}
I've got a Mac server and I'm building PHP code to allow users to upload images, documents, and even video files. Researching this has definitely gotten me nervous, I want the uploaded content to be virus free.
Is building something myself going to be a huge challenge? Would you do it, or would you find some OS or OTS product? (And do you know of any you can recommend)?
Conceptually, what you're talking about is pretty straightforward. Accepting and processing uploads is pretty simple, it's definitely not something I think you need to worry about buying a pre-built solution for.
Generally things like images and videos can't really have "viruses" (unless the viewer application is really poor and lets them run code somehow - also known as "Internet Explorer"), but it's not really difficult to virus-scan them anyway if you'd like to. Just find a command-line scanner that can run on the server (something like Clam AV), and whenever a file is uploaded, run it through the scanner and reject the upload (and log the event) if it fails the scan.
If you're uploading very large files, you might also consider a Flash upload/status bar so that users can see how much of the file is uploaded. SWFUpload is a good choice for that.
You can scan files with ClamAV by doing something like this in PHP:
$out = '';
$int = -1;
exec('/usr/local/bin/clamscan --stdout /path/to/file.ext', $out, $int);
if ($int == 0)
{
print('No virus!');
}
/*
Return codes from clamscan:
0 : No virus found.
1 : Virus(es) found.
40: Unknown option passed.
50: Database initialization error.
52: Not supported file type.
53: Can't open directory.
54: Can't open file. (ofm)
55: Error reading file. (ofm)
56: Can't stat input file / directory.
57: Can't get absolute path name of current working directory.
58: I/O error, please check your file system.
59: Can't get information about current user from /etc/passwd.
60: Can't get information about user '' from /etc/passwd.
61: Can't fork.
62: Can't initialize logger.
63: Can't create temporary files/directories (check permissions).
64: Can't write to temporary directory (please specify another one).
70: Can't allocate memory (calloc).
71: Can't allocate memory (malloc).
*/
The short answer: Don't buy anything. The experience and sense of accomplishment you will gain from coding this yourself is far more worth it.
The long answer: Trusting any form of user input is generally a bad idea. However, being sensible about what you do with user data is always the best way to go. If you don't do foolish things*, you'll be fine, and you'll gain tremendously from the experience.
( * I know that's a little ambiguous, but hey, try identifying a mistake before you've made it. I know I rarely can. ;)
I'm building sort of the same right now using FancyUpload from digitarald for Mootools 1.2.1
check this example: http://localhost/fancyupload/showcase/photoqueue/ to see how cool that is.
Just make sure you read up on how to pass a session to Flash (using GET / POST parameters!! Your session cookies will not work. ) and do some checks on the filetype.
Personally, i'd not let my users upload video's. Just use youtube and embed that stuff.
Oh yeah, and if you want to have thumbnails of thet stuff that's uploaded, go for ImageMagick installed on your server along with Ghostscript. Imagemagick can then even generate thumbnails from PDF's!
"Is building something myself going to be a huge challenge?" Yes, it is. Not as huge as to outsource it to a third party solution, but what you want to code here is possibly the most dangerous thing that you can get to code on a php web script: allowing users to upload files to your server. You need to be extremelly careful to filter the files you are going to accept to prevent users from uploading php scripts to your server. Common mistakes that people do while filtering are:
Not filter at all.
Filter based on incorrect regular expressions easily bypassables.
Not using is_uploaded_file and move_uploaded_file functions can get to LFI vulnerabilities.
Not using the $_FILES array (using global variables instead) can get to RFI vulns.
Filter based on the type from the $_FILES array, fakeable as it comes from the browswer.
Filter based on server side checked mime-type, fooled by simulating what the magic files contain (i.e. a file with this content GIF8 is identified as an image/gif file but perfectly executed as a php script)
Use blacklisting of dangerous files or extensions as opposed to whitelisting of those that are explicitely allowed.
Incorrect apache settings that allow to upload an .htaccess files that redefines php executable extensions (i.e. txt)..
I could go on, but I think you were already scared before asking :)
As per the viruses thing, yeah, just run an AV.
Here’s code to process the uploaded files, just so you get the idea:
foreach ($_FILES as $file) {
if (!$file['error']) {
move_uploaded_file ($file['tmp_name'], 'uploads/'. $file['name']);
} elseif (4 != $file['error']) {
$error_is = $file['error'];
// do something with the error :-)
}
}
header ('Location: ...'); // go to the updated page, like, with the new files
die;
You're better off using a third-party virus scanner to make sure the uploads are virus-free.
(Writing your own code to check for virus sounds like a daunting task)
Examples:
Gmail I think is using Norton, while Yahoo!Mail I think is using McAfee.
Keith Palmer suggestes small script.
Use clamdscan instead of clamscan.
clamdscan communicates with setup clamd (clamav daemon), while clamscan is a standalone application so virus signatures are loaded EACH TIME you call it, this could be generate quite a big load on your server.
Besides you could also try clamuko (this gives you on-access scanning), so you could just drop files into dir observed by clamuko.
There is also FUSE-based ClamFS which could probably be better solution, if you can't insert modules into the kernel.