<?php
/*
Утилита отдачи файлов
Автор: Denvas
Функционал:
1. Скачивание файлов только определенного расширения
2. Защита от скачивания файлов из "неправильных" папок
3. Поддержка докачки не учитывая поддерживает это apache или нет
4. В случае неразрешенных расширений, неправильных путей или ошибок чтения выставляет 404 ошибку (страница не найдена)
5. Запрос так download.php или если стоит модреврайт то просто файл.
6. В jad файлах меняет пути
*/
//==================================================//
/*
Настройки
*/
include_once("config.php");
include_once("session.php");
include_once("function.php");
include_once("shop.php");
//==================================================//
/*
Выставление заголовокв
*/
function FileHeader($filename){
global $download_type;
$path_parts=pathinfo($filename);
$ext=strtolower($path_parts["extension"]);
$contenttype="application/octet-stream";
if(isset($download_type[$ext]))$contenttype=$download_type[$ext];
//отдача заголовоков
header("Content-type: ".$contenttype);
header("Content-Disposition: attachment; filename=".$path_parts["basename"]);
}
//==================================================//
/*
Скачивание jad файла
*/
function FileDownloadJAD($localfile,$filename){
$content=file($localfile);
$nline=count($content);
for($j=0;$j<$nline;$j++){
$line=strtolower($content[$j]);
if(strpos($line,"midlet-jar-url")===0){
$content[$j]="MIDlet-Jar-URL: http://".@$_SERVER['HTTP_HOST'].strtr($_SERVER["REQUEST_URI"],array(".jad"=>".jar"))."\r\n";
};
};
$content=join("",$content);
FileHeader($filename);
FileDownloadFile("",$content);
return 1;
}
//==================================================//
/*
Скачивание файла с поддержкой докачки
*/
function FileDownloadFile($localfile="",$content=""){
if($localfile)$attach_size=filesize($localfile); else $attach_size=strlen($content);
@set_time_limit(0);//выполнять без ограничений
$headers = getallheaders();
$start=-1;$size=0;
if(isset($headers['Range'])){//определение откуда стартовать
$str=$headers['Range'];
if(strstr($str,"bytes=")){
$str=substr($str,6);
$elem=explode('-',$str);
$start=$elem[0];
if(!empty($elem[1]))$size=$elem[1];
};//if(strstr($str,"bytes="))
};//if(isset($headers['Range']))
if(($start>=0)&&($start<$attach_size)&&($start+$size<$attach_size)){
if($size<=0)$size=$attach_size-$start;
header("Accept-Ranges: bytes");
header("Content-Range: bytes ".$start."-".($attach_size-1)."/".$attach_size);
}
else{
header("Accept-Ranges: bytes");
$size=$attach_size;
};
header("Content-Length: ".$size);
header("Cache-Control: none" );
header("Connection: close");
if($localfile){//из файла
$attach_size=filesize($localfile);
$fd=@fopen($localfile, "rb");
if($start>0)fseek($fd, $start);
fpassthru($fd);
fclose($fd);
}
else{//данные
if($start>0)print substr($content,$start); else print $content;
};
return 0;
}//function DownloadFile
//==================================================//
/*
Отдать файл на скачивание
*/
function FileDownload($localfile,$filename){
if(!file_exists($localfile))return -1;
$path_parts=pathinfo($filename);
$ext=strtolower($path_parts["extension"]);
//особый случай. JAD файл. В нем нужно изменить данные.
if(strcmp($ext,"jad")==0)return FileDownloadJAD($localfile,$filename);
//обычный файл, его править не нужно
FileHeader($filename);
return FileDownloadFile($localfile);
}
//==================================================//
/*
Отдать файл $name с позиции $start размером $size
*/
/*
function get_file($name,$start=-1,$size=0){
global $download_log,$path_download,$download_type;
$downpath=$path_download.$name;
//проверка на существование фала
if(!file_exists($downpath))return -1;
//взятие расширения файла
$path_parts=pathinfo($downpath);
$ext=strtolower($path_parts["extension"]);
if(!isset($download_type[$ext]))return -2;
//чтение и отдача файла с заголовками
if(!($fd=fopen($downpath,"rb")))return -3;
$attach_size=filesize($downpath);
if(($start>=0)&&($start<$attach_size)&&($start+$size<$attach_size)){
if($size<=0)$size=$attach_size-$start;
header("Accept-Ranges: bytes");
header("Content-Range: bytes ".$start."-".($attach_size-1)."/".$attach_size);
}
else{
Header("Accept-Ranges: bytes");
$size=$attach_size;
};
fseek($fd, $start);
header("Cache-Control: none" );
header("Content-type: ".$download_type[$ext]);
header("Content-Disposition: attachment; filename=".$path_parts["basename"]);
header("Content-Length: ".$size);
header("Connection: close");
fpassthru($fd);
fclose($fd);
return 1;
};//function get_file($name)
*/
//==================================================//
$filename=basename($_SERVER["PHP_SELF"]);
$download_log=$path_log."/download.log";
if(strcmp($filename,"download.php")==0){
if(empty($_SERVER['PATH_INFO']))NotFound();
$name=$_SERVER['PATH_INFO'];
}
else{
$name="/".$filename;
};
//выполнять без ограничений
@set_time_limit(0);
//взятие имени файла
//защита от выхода на уровень вверх (чтоб с сайта ни чего не утащили)
$name=preg_replace("/\.\.+/",".",$name);
/*
//Взять из заголовка Range-Unit: $start | $size
$headers = getallheaders();
$start=-1;$size=0;
if(isset($headers['Range'])){//определение откуда стартовать
$str=$headers['Range'];
if(strstr($str,"bytes=")){
$str=substr($str,6);
$elem=explode('-',$str);
$start=$elem[0];
if(!empty($elem[1]))$size=$elem[1];
};
};
*/
$shop=GetProduct(isset($_GET["cat"])?(int)$_GET["cat"]:"");$flag=-1;
for($j=0;$j<count($shop);$j++){
for($i=0;$i<count($shop[$j]["file"]);$i++){
if(strcmp("/".$shop[$j]["file"][$i],$name)==0){$flag=$j;break;};
};
if($flag>=0)break;
};
if($flag<0)NotFound();
if($shop[$flag]["price"]>0){
if(isset($_REQUEST["ses"])){
$session=strtr($_REQUEST["ses"],array("."=>"","/"=>"","\\"=>"","'"=>"","\""=>""));
$ses=GetSession($session,-$shop[$flag]["price"],$shop[$flag]);
if(!is_array($ses))NotFound();
}
else NotFound();
};//if($shop[$flag]["price"]>0)
//отдать файл
$res=FileDownload($path_download."/".$name,$name);
if($res<0)NotFound();
//записать лог, если задано название
if($download_log){
$str=$name."|".$res;
if(isset($headers['Range']))$str.="|Range:".$headers['Range'];
$fd=fopen($download_log,"ab");
if($fd){
flock($fd,LOCK_EX);
fwrite($fd,$str."\n");
fclose($fd);
};
};//if($download_log)
?>