Basic Traffic Shaping in PHP

I ran into this problem today where we needed a PHP based solution to limit file download speeds. There are probably better ways to do this, so it might be wise to consider your possibilities before continuing.

It is amazingly simple to limit download speeds with php using no more than a half-handful of built in functions.

To get started, define the download path, filename, and download speed.

$file_path = "/path/to/file/demosong.mp3";
$file_name = "Cool_Song.mp3";
//download speed is in kb/s
$download_rate = 50;

note: you can easily change the download rate on a per-mimetype basis. ex:

if(strstr($file_name,'.mp3'))
{
$download_rate = 30;
}
else
{
$download_rate = 150;
}

Now, check that the file exists and then send some header information.

if(file_exists($file_path) && is_file($file_path))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($file_path));
header('Content-Disposition: filename='.$file_name);
flush();

note: it is a good idea to leave the flush() in there.

All we have to do now is read the file in chunks. PHP will sleep every second and output the $download_rate to the browser.

$file = fopen($file_path, "r");
while(!feof($file)) {
print fread($file, round($download_rate * 1024));
flush();
sleep(1);
}
fclose($file);
}
else
{
die('Error: The file '.$file_name.' does not exist!');
}

That sums it up. Below is the file code.

$file_path = "/path/to/file/demosong.mp3";
$file_name = "Cool_Song.mp3";
//download speed is in kb/s
$download_rate = 50;
if(strstr($file_name,'.mp3'))
{
$download_rate = 30;
}
else
{
$download_rate = 150;
}
if(file_exists($file_path) && is_file($file_path))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($file_path));
header('Content-Disposition: filename='.$file_name);
flush();
$file = fopen($file_path, "r");
while(!feof($file)) {
print fread($file, round($download_rate * 1024));
flush();
sleep(1);
}
fclose($file);
}
else
{
die('Error: The file '.$file_name.' does not exist!');
}

3 Responses to “Basic Traffic Shaping in PHP”

  1. Jeffrey Says:

    That is awesome! I have been looking for a script like this for a while. I have found tons that will limit the amount of downloads or the type of file to download but I haven’t’ found one (until now ;) of course) that will limit the download speed. It is surprisingly small and simple which is even more cool!

    Thanks and keep up the awesome work!

  2. Keith Says:

    Now how would I go about implementing this to all downloads on http://www.gamersview.co.uk/downloads but users get the full speed?

  3. dawnerd Says:

    Basically you would just have to alter the $download_rate variable. Assuming you already have checks in place if the user is a member, setting the variable should be no harder than if(member) then (faster download)

Leave a Reply






Copyright 2008 Troy Whiteley & OjaiSoft

CSS | PHP | XHTML/HTML | JavaScript | Featured Sites

Home | Labs | License | RSS | Log in