User Tools

Site Tools


php:speed_limit_downloader

We needed to download some large files in the middle of the day at my workplace with a limited connection (12mbit), and didn't want to disturb business data. Also we didn't want to pay for a fancy Windows client to limit the speed of the downloads, so I wrote a quick PHP script that can do it for us.

downloader.php
<?php
if (empty($_GET['url'])) {
	echo "<html><title>PHP speed limiter downloader thingy</title><body>";
	echo "<table>";
	echo "<form action=\"?\" method=\"get\">";
	echo "<tr><td>URL</td><td><input type=\"text\" name=\"url\" size=\"100\"></td></tr>";
	echo "<tr><td>Speed (in kilobytes)</td><td><input type=\"text\" name=\"speed\" size=\"100\"></td></tr>";
	echo "<tr><td colspan=\"2\"><input type=\"submit\" value=\"Start download\"></td></tr>";
	echo "</form>";
	echo "</table>";
	echo "</body></html>";
} else {
// Turn on output buffering
	ob_start();
 
// Which file to open?
	$filethis = $_GET['url'];
	$speedlimit = (1024*$_GET['speed']);
	$speedlimit = (int) $speedlimit;
 
// If speed is larger than 8192 (which it usually is), we need to change sleep to match it.
	if ($speedlimit > 8192) {
		$loopspersec = ($speedlimit/8192);
		$usleeptimer = (1000000/$loopspersec);
		$usleeptimer = round($usleeptimer);
		$speedlimit = 8192;
	} else {
		$usleeptimer = 1000000;
	}
 
// Define the filehandle
	$handle = fopen($filethis, "r");
 
// Did we successfully create a handle?
	if ($handle) {
// Set some headers
		header('Content-Description: File Transfer');
		header('Content-Type: application/octet-stream');
		header('Content-Disposition: attachment; filename='.basename($filethis));
		header('Content-Transfer-Encoding: binary');
		header('Expires: 0');
		header('Cache-Control: must-revalidate');
		header('Pragma: public');
//		header('Content-Length: ' . filesize($filethis));
// Flush the headers, weeeeeeeeeeeee
		ob_flush(); flush();
 
// Loop the file, outputting at a limited rate.
		while (!feof($handle)) {
//			echo $buffer."\nNEXTROW\n";
// Read 20 KB, then compress it and then send it to the client.
//			$buffer = fread($handle, 204800);
			$buffer = fread($handle, $speedlimit);
//			$buffer = fread($handle, 1024);
// Gzip the data.
//			$buffer = gzcompress($buffer, 9);
// Here you go mr. client, eat up.
			echo $buffer;
			ob_flush(); flush();
			usleep($usleeptimer);
		}
		fclose($handle);
	} else {
		echo "ERROR: Could not open file.";
	}
	ob_flush(); flush();
}
php/speed_limit_downloader.txt · Last modified: 2015/08/15 20:56 (external edit)