How can I allow a user to download a file which is stored outside of the webroot?

13,685

You need a PHP script that does the following:

  1. Set the content-type header correctly (depending on what the user is downloading)
  2. Set the content-length header correctly (depending on the file size)
  3. Open the file for reading (you can use fopen)
  4. Read the file and output its content to the output stream
  5. 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;
}
?>
Share:
13,685
Sharon
Author by

Sharon

Updated on June 26, 2022

Comments

  • Sharon
    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
    Sharon over 13 years
    Can 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
    Adeel over 13 years
    You 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
    El Yobo over 13 years
    That pretty much defeats the security benefits of putting it outside the document root in the first place.
  • El Yobo
    El Yobo over 13 years
    Slightly more complete example here, including mime type and possibly more correct casing - stackoverflow.com/questions/4275830/4277145#4277145; Gordon, what's missing?
  • Musa
    Musa over 11 years
    While 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
    Dave Everitt over 11 years
    Point 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.