For the past couple of days, I've been working on creating a script that will allow for secure downloads. That is, let's say you have a file, but you don't want this file sitting on the root. You already have some sort of login script in place, so people can't access the page without logging in, but how do you get the download to work *through* the script with the file outside the web root…
A LOT of research went into this… I'll link to two sites that were most helpful:
php-builder and then most helpful with a single function: experts-exchange (the files I was trying to download were rather large)
Now here's the code:
(not really going to go into a great length of description here – this post is more like my notetaking…)
I create a "download.php" page with this in it:
<?
$fullpath = "/home/pathtofile/outsideofwebroot/downloadfolder/".$_REQUEST["download"];
$downloadstringarray = pathinfo($_REQUEST["download"]);
$p = $downloadstringarray["basename"];
$file_size = filesize($fullpath);
if (file_exists($fullpath)) {
//header("Content-type: application/zip");
// might need the above… left it in here for future possible use –
// although the line below worked with zips
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$p\"");
header("Content-Transfer-Encoding: binary");
header("Content-length: ".(string)($file_size));
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')){
// IE cannot download from sessions without a cache
header('Cache-Control: public');
}
readfile($fullpath);
}
else
{
print "not found";
die();
}
?>
Then, I link to downloads like this:
<a href="download.php?download=folderinside/downloadfolder/file.zip">download this</a>
(add in "authentication both on the page that has the link – as well as the download.php page) – an easy "authentication" for this could be not allowing any access to the download.php page unless the referrer is the one you specify (that was one of the scripts I'd found, but wasn't applicable to the project I'm working on)
Update: actually, if you call "session_start() before that stuff? It dies. So my "authentication" flew out the window… so instead – I use that referrer check. But rather than enter in EVERY SINGLE PAGE of my site that referrences this download page – I check to make sure it's just coming from my site and folder where these pages are…
so above the code I posted above, put this:
$path_parts = pathinfo($_SERVER['HTTP_REFERER']);
Then I wrap the download code in this if statment:
if($path_parts["dirname"] == "http://www.YOURDOMAIN.com/pathtomy/folder") {
…etc…. (code from above)….
} else {
echo "you are not authorized to download this page!";
}
Updated to add: This probably goes without saying, but if you're getting errors withe filesize() and your file is in fact LESS than 2GB in size – check to make sure there are no spaces in the file name!!! (grrr) (If it's OVER 2GB, as far as I can tell – PHP can't handle doing it)