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!');
}

This entry was posted in PHP and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>