How can I allow a user to download a file which is stored outside of the webroot?
You need a PHP script that does the following:
- Set the content-type header correctly (depending on what the user is downloading)
- Set the content-length header correctly (depending on the file size)
- Open the file for reading (you can use fopen)
- Read the file and output its content to the output stream
- Done
You can also use readfile function to do basically the same. Here's an example from PHP's site:
<?php
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
Sharon
Updated on June 26, 2022Comments
-
Sharon almost 2 years
I am developing a system which allows registered users (who could be anybody) to upload files. I've block mime-types etc. to attempt to restrict the files to .doc, .docx and .pdf types, but for additional security, they are uploaded to a folder outside the webroot.
Other users can then choose to download the files. How do I allow them to do that? Obviously I can't just put in a link to the file, as it's outside the webroot. I'm not sure how to reach the file though! I presume I can use the php file functions to get to the file, but how do I then 'serve it up' to the user who has requested it?
What security implications might all of this have?
Thanks.
-
Sharon over 13 yearsCan you tell me more about this? The directory is in /userfiles from the home directory. What rules should I apply? How do I show a virtual path? Thanks.
-
Adeel over 13 yearsYou can edit your .htaccess file and define a rule like RewriteRule ^download.php$ download.php?path=yourpath/$1.doc Your user can only see download.php
-
El Yobo over 13 yearsThat pretty much defeats the security benefits of putting it outside the document root in the first place.
-
El Yobo over 13 yearsSlightly more complete example here, including mime type and possibly more correct casing - stackoverflow.com/questions/4275830/4277145#4277145; Gordon, what's missing?
-
Musa over 11 yearsWhile this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.
-
Dave Everitt over 11 yearsPoint taken - at present I only have time to add a little more info about the linked resources, so for now that's what I've done.