Seite 1 von 1

A bug in latest version and some suggestions

Verfasst: Mo 06.Feb, 2006 22:40
von Neverbirth
In load.php, remove lines 18-21

Code: Alles auswählen

if ($userdata['user_id'] == 6)
{
	redirect(append_sid("downloads.$phpEx"));
}

Also, I've replaced the readfile function with this one:

Code: Alles auswählen

function readfile_chunked($filename,$retbytes=true) {
   $chunksize = 1*(1024*1024); // how many bytes per chunk
   $buffer = '';
   $cnt =0;
   // $handle = fopen($filename, 'rb');
   $handle = fopen($filename, 'rb');
   if ($handle === false) {
       return false;
   }
   while (!feof($handle)) {
			 set_time_limit(0);
       $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;

}
Don't know if you are aware of it, but you can't download files bigger than 10mb in some php compilations. Along with this one I've made another change:

In load.php replace:

Code: Alles auswählen

	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=\"$file_name\"");
	readfile($download_dir . "" . $file_path . "/" . $file_name);
With:

Code: Alles auswählen

	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
	header("Content-Type: application/octet-stream");
	header("Content-Length: ".@filesize($download_dir . "" . $file_path . "/" . $file_name));
	header("Content-Transfer-Encoding: binary");
	header("Content-Disposition: attachment; filename=\"$file_name\"");
	readfile_chunked($download_dir . "" . $file_path . "/" . $file_name);
This way you'll get the file size when downloading the file, and the download will be correctly seen with some applications as Adobe Reader when viewing some files.

Verfasst: Mo 06.Feb, 2006 23:23
von oxpus
Oh, okay, the first was an extra mod for my board. Sorry...

The rest of your suggestions we will insert as soon as possible.
Thanks for this!

Verfasst: Do 09.Feb, 2006 08:15
von oxpus
Little problem:
On some webservers the new method can destroy several downloads!
So I'll code for the next release the possibility to switch between the old and the new download method to be compatible to all inviroments...

Verfasst: Do 09.Feb, 2006 20:19
von Neverbirth
Strange, what do you exactly mean with destroy tho? anyway, I think the reason could be the header information, you could try using just:

Code: Alles auswählen

   header("Content-Type: application/octet-stream");
   header("Content-Length: ".@filesize($download_dir . "" . $file_path . "/" . $file_name));
   header("Content-Disposition: attachment; filename=\"$file_name\"");
   readfile_chunked($download_dir . "" . $file_path . "/" . $file_name);

Verfasst: Do 09.Feb, 2006 20:53
von oxpus
On some systems the filesize will be calculated wrong (not the big problem) but the readfile_chunked-function can malfunction!

Verfasst: Do 09.Feb, 2006 21:28
von Neverbirth
oxpus hat geschrieben:On some systems the filesize will be calculated wrong (not the big problem) but the readfile_chunked-function can malfunction!
Rather strange that the filesize will be calculated wrong as it's just the filesize function...

About the readfile_chunked function... you could try some slightly different variations...

Code: Alles auswählen

<?php
function readfile_chunked ($filename) {
  $chunksize = 1*(1024*1024); // how many bytes per chunk
  $buffer = '';
  $handle = fopen($filename, 'rb');
  if ($handle === false) {
   return false;
  }
  while (!feof($handle)) {
   $buffer = fread($handle, $chunksize);
   print $buffer;
  }
  return fclose($handle);
}
?>

Code: Alles auswählen

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

}
?>
It's suggested to use the ob_flush() and flush() functions after each read tho, and it's always better to use the set_time_limit() function, I've heard both readfile_chunked and the normal readfile can exceed the script execution time even if the function is completed, dunno...

Verfasst: Do 09.Feb, 2006 21:38
von oxpus
Thanks for them.
I'll test them out to to find the better one.

Little hint:
Smaller files will be better read by readfile();, so I'll handle smaller downloads with this original function.
But I'll insert a second option on the dl configuration to set the quota for readfile();, if the admin will use the new method.
This may be the best compromise to choose the best method for each webserver enviroment.