Need help with my download script


#1

Hi,

I have a website of DJ Sets. DJ Set normally is a MP3 file with 100MB… sometimes it’s larger, sometimes it isn’t.

I have all the files stored in a folder inside my website. But I don’t want people to know the correct path. So I’ve made a research and found a solution to make it more secure. The DOWNLOAD link calls my download.php with two variables (encripted). One is the “fake” name of the file, that user will download with this name, and the other is the correct full path of this mp3 file. example:

The download.php gets those two variables and decrypt them:

function decrypt($str){
  $str = base64_decode($str);
  $result = '';
  $key = "myEncryptionKey";
  for($i=0; $i<strlen($str); $i++) {
    $char = substr($str, $i, 1);
    $keychar = substr($key, ($i % strlen($key))-1, 1);
    $char = chr(ord($char)-ord($keychar));
    $result.=$char;
  }
return $result;
}

After this, with the correct variables decrypted, it starts to handle the download:

function readfile_chunked($filename,$retbytes=true) {
// Stream file
$handle = fopen($filename, 'rb');
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt =0;
   if ($handle === false) {
       return false;
   }
   while (!feof($handle)) {
       $buffer = fread($handle, $chunksize);
       echo $buffer;
       ob_flush();
       flush();
       if ($retbytes) {
           $cnt += strlen($buffer);
       }
   }
       $status = fclose($handle);
   if ($retbytes && $status) {
       return $cnt; // return num. bytes delivered like readfile() does.
   }
   return $status;

}

$filename = decrypt($_GET['name']);
$myFile = decrypt($_GET['id']);

$mm_type="application/octet-stream";

set_time_limit(0); //Set the execution time to infinite.

header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header("Pragma: hack"); // WTF? oh well, it works...
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($myFile)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");


readfile_chunked($myFile);

exit;

The thing is that I researched a lot to get to this code. People tell that this function “readfile_chunked()” is good to handle large files download.
But I’ve made some tests and sometimes it downloads the entire file, but most of the times it downloads only around 500kb. I don’t know if this has something to do with my PHP.INI configurations. But I need this working so bad. This helps me to get my website going well. With no issues. Any help I would appreciate! I use a shared hosted @dreamhost.

If you have any idea why it downloads only around 500kb or if you have any sugestions of other download script or something that I can keep my file’s privacy, it would help a lot. I’m charging for people to have access to download those large files, so not everyone can do it. That’s why i need this working so badly.

Any doubts just ask, I hope to get this working before christmas! I’ll write a letter to santa to give me a solution as well.

Best regards!


#2

See: http://discussion.dreamhost.com/thread-127481.html. (The thread is about Django, but it applies equally to PHP.)

Then PM me your domain so that I can enable mod_xsendfile for it.