tags:

views:

81

answers:

3

I have a file that users will purchase via paypal, clickbank and paydotcom. I have to host the file's download page on my server.

I've placed the file in a directory outside my public_html folder. The folder is on the same level as public_html and called "download" for example.

The script below is supposed to do that, but I have two problems with it...

1) It doesn't seem too secure. just check for a payment confirmation token on the querystring?

2) I can't the $path variable to point to the download folder without including my site.com public folder in the path. For example, when I echo $path, I get

/home/myuser/public_html/mysite.com

But I need it to resolve to

/home/myuser/download/myprotectedfile.zip

I'm sure there is a more secure or clever way to do this, so I'm asking...

<?php

// place this code inside a php file and call it f.e. "download.php"
$path = $_SERVER['DOCUMENT_ROOT']."/path2file/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['download_file'];

if ($fd = fopen ($fullPath, "r")) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "pdf":
        header("Content-type: application/pdf"); // add here more headers for diff. extensions
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
        break;
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    }
    header("Content-length: $fsize");
    header("Cache-control: private"); //use this to open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
}
fclose ($fd);
exit;
// example: place this kind of link into the document where the file download is offered:
// <a href="download.php?download_file=some_file.pdf">Download here</a>
?>

The problem I'm having in getting this to work is the the value of $path includes my site.com reference, but the download directory is outside site.com. I need to get a reference up a level in order to point to the directory that holds the download file.

Also, as I stated earlier, I'm not sure how to do this (other than checking for an expected querystring value in a manner that's secure)

Thanks in advance!

A: 

You just need to consider the path like a normal directory path, not a web one. so to go up a level simply "../" e.g.

if you structure is like this

/path2file/inhere.pdf /public_html/download.php

the path to the file would simply be from download.php "../path2file/inhere.pdf"

metismo
A: 

well if public_html is your doc root then you should be able to get the path to download would be

realpath($_SERVER[DOCUMENT_ROOT].'/../download');

prodigitalson
A: 

You can use the parent directory shortcut ../ in your $path or the dirname function like:

$parent_dir = dirname( dirname( __FILE__ ) );
// first dirname is the directory of this file, second goes up one level, etc.

BTW, beware of indicating the path in your URL, one could read other files (like configuration files or ohter private files) by changing it to download.php?download_file=../../private/bank_certificate.pem. You should use realpath to get the absolute path of the file and compare it to an "authorized for download" file list.

streetpc
OK, I can use this to get a pointer to my directory where the file is stored. I'm just not sure the rest of my code is correct now. I keep getting an error stating..."Warning: Cannot modify header information - headers already sent by..."
Scott B
1. beware `dirname` returns the path as a string, not a file descriptor on the directory 2. This warning means that you already sent some output. It can happen if you `echo` 'ed something or when you have blank lines or whitespaces at the beginning / end of your php files (like before your `<?php` or after your `?>` in another included file).
streetpc