<?php

class download{
var $path;
var $name;
var $mime = 'application/octet-stream';

function download($name,$path)
{
$this->path = $path;
$this->name = $name;
}

function exists(){return is_file($this->path);}

function output()
{
$this->mime=$this->get_mime();
@ob_end_clean();
$from=0;
$to=$size=filesize($this->path);
if (isset($_SERVER['HTTP_RANGE']))
{
if (preg_match ('#bytes=-([0-9]+)#i',$_SERVER['HTTP_RANGE'],$range)) // если указан отрезок от конца файла
{
$from=$size-$range[1]; // начало файла
$to=$size; // конец файла
}
elseif(preg_match('#bytes=([0-9]+)-#i',$_SERVER['HTTP_RANGE'],$range)) // если указана только начальная метка
{
$from=$range[1]; // начало
$to=$size; // конец
}
elseif(preg_match('#bytes=([0-9]+)-([0-9]+)#i',$_SERVER['HTTP_RANGE'],$range)) // если указан отрезок файла
{
$from=$range[1]; // начало
$to=$range[2]; // конец
}
header('HTTP/1.1 206 Partial Content');

$cr='Content-Range: bytes '.$from .'-'.$to.'/'.$size;
}
else header('HTTP/1.1 200 Ok');

$etag=md5($this->path);
$etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
header('ETag: "'.$etag.'"');
header('Accept-Ranges: bytes');
header('Content-Length: ' .($to-$from));
if (isset($cr))header($cr);
header('Connection: close');
header('Content-Type: ' . $this->mime);
header('Last-Modified: ' . gmdate('r', filemtime($this->path)));
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($this->path)).' GMT');
header('Expires: '.gmdate('D, d M Y H:i:s', TIME + 3600).' GMT');
$f=fopen($this->path, 'rb');

if (!preg_match('#^image/#i',$this->mime))
header('Content-Disposition: attachment; filename='.convert::of_utf8(basename($this->name)).';');

fseek($f, $from, SEEK_SET);
$size=$to;
$downloaded=0;
while(!feof($f) and !connection_status() and ($downloaded<$size))
{
$block = min(1024*8, $size - $downloaded);
echo fread($f, $block);
$downloaded += $block;
flush();
}
fclose($f);
return $downloaded;
}





function get_mime()
{
// получение mime-типа файла по расширению
if (preg_match('#([^\.]+)$#', $this->name,$ext))
switch ($ext[1]) {
// текстовые файлы
case 'php':return 'text/plain';
case 'txt':return 'text/plain';
case 'emy':return 'text/x-vmel';
case 'mel':return 'text/x-vmel';
case 'jad':return 'text/vnd.sun.j2me.app-descriptor';
// приложения
case 'jar':return 'application/java-archive';
case 'thm':return 'application/vnd.eri.thm';
case 'mpn':return 'application/vnd.mophun.application';
case 'mpc':return 'application/vnd.mophun.certificate';
case 'sis':return 'application/vnd.symbian.install';
// архивы
case 'zip':return 'application/x-zip-compressed';
case 'rar':return 'application/x-rar-compressed';
case '7z':return 'application/x-7z-compressed';
case 'gz':return 'application/x-gzip';
case 'hid':return 'application/x-tar';
case 'tar':return 'application/x-tar';
// звуки и музыка
case 'imy':return 'audio/imelody';
case 'mmf':return 'application/vnd.smaf';
case 'amr':return 'audio/amr';
case 'wav':return 'audio/x-wav';
case 'mp3':return 'audio/mpeg';
case 'wav':return 'audio/wav';
case 'midi':return 'audio/midi';
case 'mid':return 'audio/midi';
case 'rmf':return 'audio/rmf';
// видео
case 'flv':return 'video/flv';
case 'mp4':return 'video/mp4';
case '3gp':return 'video/3gpp';
// изображения
case 'jpg':return 'image/jpeg';
case 'jpeg':return 'image/jpeg';
case 'gif':return 'image/gif';
case 'png':return 'image/png';
case 'bmp':return 'image/bmp';


}

return 'application/octet-stream';
}




}




?>