I have a scenario where certain files are stored outside of the Document Root directory, like this...

/home/user/public_html/{drupal files are in here}
/home/user/data/{special data files are in here}

I would like to allow users with special permissions to download files from /home/user/data using Drupal's built-in file wrapper, but I'm not sure how to link to the files.

Addendum: Most of my files are stored in the usual location:


It is only some of them I need to store in the external data folder. For security reasons I do not want to change the sites/default/files/ directory to /home/user/data.

3 Answers 3


Drupal 6 doesn't support having both private and public files enabled, but there are some modules that provide this, for example http://drupal.org/project/private_download.

If that modules doesn't do what you need, you can also write your own, see file_download() for inspiration. This is the page callback that serves private files through PHP by checking access with hook_file_download().

  • Good call on private_donwload.module. It manages the problem a little differently than I had planned, but is totally workable.
    – Codeblind
    Commented Apr 5, 2011 at 17:19

I'm not good in *nix, but I think you should to create symlink to this directory from public_html/ and cmod -R 777 to foreign folder.

  • 1
    I could create a symlink, but I think that would be effectively the same as if I had placed the data folder in the sites/all/default/files directory.
    – Codeblind
    Commented Apr 5, 2011 at 2:30

I do this all the time for security reasons.

1) You'll need to configure your open_basedir to include the directory or directories where you store your files outside of the web server's docroot.

2) You'll need some separate logic to insure that the person is allowed to get the file(s), such as placing the download link/button on a page that only these users have access.

3) When the authorized person hits your special download link, they are triggering logic of yours that uses something like file_get_contents() on the desired file outside of docroot, which is possible because you configured open_basedir to know about the desired file's directory

4) Now you have the desired file in a variable, just pass it to this routine, and the user's browser will pop a "save file" dialog - the file is being pushed, rather then pulled, to the user. TaDa!

* prompt the user to download the passed string as a file.
function _push_download( $output, $filename ) 
  header("Pragma: public");
  header("Expires: 0");
  header("Cache-Control: private");
  header("Content-type: application/octet-stream");
  header("Content-Disposition: attachment; filename=$filename");
  header("Accept-Ranges: bytes");
  echo $output;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.