2012-06-20 21:39:23 -07:00

122 lines
3.1 KiB
PHP
Executable File

<?php
/**
* A resumable download and force download file class
*
* @author Devin Smith <devin@cana.la>
* @date 2010.06.03
*
*/
class Cana_File extends Cana_Model {
private $_file;
public function __construct($params) {
$this->_file = self::cleanFileName($params['file']);
$this->_path = $params['path'];
$this->_name = $params['name'] ? $params['name'] : $params['file'];
}
public function get($attachment = false, $resume = true, $filename = null) {
$file = $this->_path.$this->_file;
$filename = $filename ? $filename : $this->_name;
if (!file_exists($file)) {
header('HTTP/1.1 404 Not Found');
exit;
}
if ($attachment) {
if (ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', 'Off');
}
}
$size = filesize($file);
$fileinfo = pathinfo($file);
//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
if (is_null($filename)) {
$filename = (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ?
preg_replace('/\./', '%2e', $fileinfo['basename'], substr_count($fileinfo['basename'], '.') - 1) :
$fileinfo['basename'];
}
//$file_extension = strtolower($fileinfo['extension']);
if ($resume && isset($_SERVER['HTTP_RANGE'])) {
list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if ($size_unit == 'bytes') {
list($range, $extra_ranges) = explode(',', $range_orig, 2);
} else {
$range = '';
}
} else {
$range = '';
}
if ($range) {
list ($seek_start, $seek_end) = explode('-', $range, 2);
} else {
$seek_start = '';
$seek_end = '';
}
$seek_end = (empty($seek_end)) ? ($size - 1) : min(abs(intval($seek_end)),($size - 1));
$seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);
if ($resume) {
if ($seek_start > 0 || $seek_end < ($size - 1)) {
header('HTTP/1.1 206 Partial Content');
} else {
header('HTTP/1.1 200 OK');
}
header('Accept-Ranges: bytes');
header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$size);
} else {
header('HTTP/1.1 200 OK');
header('Accept-Ranges: bytes');
}
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Date: '.date('r'));
header('Last-Modified: '.date('r',filemtime($file)));
header('Content-Length: '.($seek_end - $seek_start + 1));
header('Content-Transfer-Encoding: binary');
if ($attachment) {
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Type: application/force-download');
} else {
header('Content-Type: '. mime_content_type($file));
}
$fp = fopen($file, 'rb');
fseek($fp, $seek_start);
while(!feof($fp)) {
set_time_limit(0);
print(fread($fp, 1024*8));
flush();
}
fclose($fp);
}
public static function cleanFileName($file) {
$find = ['/\\\/','/\.\.\//'];
$replace = ['/',''];
$file = preg_replace($find,$replace,$file);
return $file;
}
}