function dl_file_resume($filepath, $filename, $throttle = 0, $callback = '') { //Get the content type $content_type = my_get_mime_type($filename); //Begin writing headers header('Cache-Control:'); header('Cache-Control: public'); //Use the switch-generated Content-Type header('Content-Type: ' . $content_type); if (stristr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) { //workaround for IE filename bug with multiple periods / multiple dots in filename //that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe $iefilename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1); header('Content-Disposition: attachment; filename="' . $iefilename . '"'); } else header('Content-Disposition: attachment; filename="' . $filename . '"'); header('Accept-Ranges: bytes'); $filesize = filesize($filepath); //check if http_range is sent by browser (or download manager) if (isset($_SERVER['HTTP_RANGE'])) { list($a, $range) = explode('=', $_SERVER['HTTP_RANGE']); //if yes, download missing part str_replace($range, '-', $range); $size2 = $filesize - 1; $new_length = $size2 - $range; header('HTTP/1.1 206 Partial Content'); header("Content-Length: $new_length"); header("Content-Range: bytes $range$size2/$filesize"); } else { $size2 = $filesize - 1; header("Content-Range: bytes 0-$size2/$filesize"); header('Content-Length: ' . $filesize); } //open the file $fp = fopen($filepath, 'rb'); //seek to start of missing part @fseek($fp, $range); //start buffered download while (!feof($fp)) { //reset time limit for big files set_time_limit(0); if ($throttle != 0) { echo fread($fp, 1024 * $throttle); sleep(1); } else echo fread($fp, 1024 * 8); if ($callback()) break; flush(); @ob_flush(); } fclose($fp); }