Once, I had to face problem, how to generate download link dynamicly. I did not want everybody could download my files by copy pasting link into browser. Here is the solution I have created:
First we need a regular download link. This link is directed to the php script which handles whole process of downloading. Two variables are send to the php script by "GET".
<?php
//uses hash of date to ensure security
$password = "pass";
$strToHash = date('m.d.y').$password;
$hash = hash('md5', $strToHash);
echo "<a href='dl.php?filename=icon.ico&id={$hash}'>working DOWNLOAD</a><br><br>";
echo "<a href='dl.php?filename=icon.ico&id=1'>not working DOWNLOAD</a>";
?>
- filename which we want to download
- id which is our MD5 hash generated based on the date and a password.
Everythig looks like this:
As you can see, hypertext runs dl.php script. This script has two tasks:
- control if it was run by our link. It is done by the hash control
- allow us to download the requested file (defined by filename variable)
Here is the code:
<?php
$download_path = "C:\\"; //directory where downloadable files are stored
$password = "pass"; //password
$filename = $_GET['filename'];
$hash1 = $_GET['id'];
$strToHash = date('m.d.y').$password;
$hash2 = hash('md5', $strToHash);
if(strcmp($hash1, $hash2) != 0){
die("Please try again later.");
}
// Detect missing filename
if(!$filename) die("I'm sorry, you must specify a file name to download.");
// Make sure we can't download files above the current directory location.
if(eregi("\.\.", $filename)) die("I'm sorry, you may not download that file.");
$file = str_replace("..", "", $filename);
// Make sure we can't download .ht control files.
if(eregi("\.ht.+", $filename)) die("I'm sorry, you may not download that file.");
// Combine the download path and the filename to create the full path to the file.
$file = "$download_path$file";
// Test to ensure that the file exists.
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
// Extract the type of file which will be sent to the browser as a header
$type = filetype($file);
// Send file headers
header("Content-type: $type");
header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
readfile($file);
?>
Source code, you may download here.