0

I have tried the basic ones found in a Google search and even tried to write one myself, however i keep getting a problem with it. It seems to download the content server-side or something and then push it to the user, which will already have been downloaded. It will open the download page and take around 10 seconds to download and then give the file to the user in full, which makes it look like its not downloading.

I was wondering if there are any classes that have been written to throttle download speeds, or how i can fix this problem.

I have this currently;

header("Content-type: application/force-download");
    header("Content-Transfer-Encoding: Binary");
    header("Content-length: ".filesize("uploads/$filename"));
    header("Content-disposition: attachment; filename=\"$origname");
    readfile("uploads/$filename");

Thanks!

HarryBeasant
  • 490
  • 1
  • 9
  • 21

3 Answers3

5
@set_time_limit(0); // don't abort if it takes to long
header("Content-type: application/force-download");
header("Content-Transfer-Encoding: Binary");
header("Content-length: ".filesize("uploads/".$filename));
header('Content-disposition: attachment; filename="'.$origname.'"');
$perSecond = 5; // 5 bytes per second

$file = fopen("uploads/".$filename, 'r');
while(!feof($file)) {
    echo fread($file, $perSecond);
    flush();
    sleep(1);
}

This will send a file with throttled download speed to the user. It works basically like this:

  • Open a file
  • loop until we are at the end
  • echo X bytes
  • flush the output to the User
  • sleep for one second.
TimWolla
  • 31,849
  • 8
  • 63
  • 96
  • I have added what it currently looks like, how would i integrate this? – HarryBeasant Feb 05 '12 at 20:36
  • @HarryBeasant Simply replace the readfile with my snippet and file.txt in my snippet with your filename (and of course perSecond as well) Edit: i just updated my answer – TimWolla Feb 05 '12 at 20:37
  • Done that, the problem being is that it processes the download server side and then pushes it to the browser. So you can't see it downloading. – HarryBeasant Feb 05 '12 at 20:41
  • @HarryBeasant I don't think this could be done when your file cannot be processed in chunks – TimWolla Feb 05 '12 at 20:45
  • You could modify the code to support the Range: header, so you can see a file's progress as it downloads. – halfer Feb 05 '12 at 20:48
  • @HarryBeasant It want meant like: If you have to recalculate a file in a once and not chunk by chunk – TimWolla Feb 05 '12 at 20:58
  • I have implemented this code to download a zip file. The file downloads fine however when I open the file the default behaviour is for that file to get zipped again vs being unzipping. When using readfile the default behaviour when opening was working as expected, unzipping the file. Any thoughts on this? – Shawn Northrop Sep 02 '12 at 17:25
  • Just figured it out :) I added some header info that was causing some trouble – Shawn Northrop Sep 02 '12 at 17:36
0

I was wondering if there are any classes that have been written to throttle download speeds

Now there is: bandwidth-throttle/bandwidth-throttle

use bandwidthThrottle\BandwidthThrottle;

$in  = fopen(__DIR__ . "/resources/video.mpg", "r");
$out = fopen("php://output", "w");

$throttle = new BandwidthThrottle();
$throttle->setRate(100, BandwidthThrottle::KIBIBYTES); // Set limit to 100KiB/s
$throttle->throttle($out);

stream_copy_to_stream($in, $out);
Markus Malkusch
  • 7,738
  • 2
  • 38
  • 67
0

You might find my alpha-stage Bandwidth project of interest. Probably needs a bit more work, but there's plenty of interesting stuff already. I don't think it has a F/OSS license yet; ping me if you want me to give it one!

halfer
  • 19,824
  • 17
  • 99
  • 186