Главная » Полезные статьи » Язык PHP » Контролируемая отдача файлов
Распечатать статью

Контролируемая отдача файлов

Если у Вас возникла потребность в отдаче (выгрузке) файлов Вашим пользователям, и Вы хотите контролировать кому, с какой скоростью и сколько отдать, предлагаю Вам свой php-класс. Данный класс есть сборная солянка чужого кода под моей редакцией и улучшениями. Копирайты не привожу, т.к. за частую трудно определить, кому именно принадлежало право первенства на тот или иной кусок кода, да и заниматься вычислением авторов специально желания нет. По сему заранее приношу неизвестным авторам извинения за плагиат :). Но меня, как практикующего программиста, интересовал в первую очередь результат. Короче: всем желающим/страждущим, кому не хочется переводить свое время на изобретение велосипеда, предлагаю воспользоваться моим.

 

Описание

Представленный ниже класс позволяет:

— разрешать/запрещать докачку файлов;
— ограничивать скорость отдачи (по умолчанию 5 Кб);
— отдавать файлы пользователям по именам, передаваемым в класс (авторизация оных ложится на Ваши плечи — класс только принимает имя пользователя и по нему считает объем).

Для каждого пользователя в папке stats (по умолчанию) заводится своя папка по имени пользователя. Из имени пользователя регэкспом вырезается все кроме «0-9a-za-z_-«. Для каждого ip-адреса заводится соответствующий файл (например: 10.1.3.94) в который в течение времени работы скрипта записывается скачанный объем. По этому файлу собственно и осуществляется контроль отдаваемого объема. Удаление/обнуление файла классом не производится — если Вам это нужно — допишите сами.
разрешать/запрещать отдачу файлов по списку стран, ip-адресов. Во всех списках разделитель запятая, все знаки (в т.ч. пробелы учитываются!). Локалхост и локальные адреса (192.168.xxx.xxx, 10.xxx.xxx.xxx, 172.16.xxx.xxx) именуются как localhost и local network соответственно. Определение страны по ip-адресу осуществляется через сервис whois.ripe.net.

Пример:

Файл 1.php. Качаем линк http://serv/1.php?download=docucd_v210_[iso].zip
# filename: 1.php

include 'cdownload.inc.php'; $download = @new cdownload($_request['download']); $download->enabledcountry = 'localhost,local network,ua,ru'; $download->whitelist = '127.0.0.1,10.1.3.94'; $download->banlist = '184.12.13.5'; $download->username = 'pupkin'; $download->speedlimit = 10; $download->sizelimit = 2*mb; $download->downloadfile(); ?>

Код класса

# filename: cdownload.inc.php

define('kb',1024); define('mb',kb*1024); class cdownload { # ------------------------------------------------------------------------------------- # Описание : выгрузка файла пользователю с поддержкой докачки и ограничением скорости # ------------------------------------------------------------------------------------- var $downloadtimelimit = 300; # Лимит времени работы функции выгрузки var $username = 'anonymous/'; # Пользователь по умолчанию var $sizelimit = 0; # Лимит объема выгрузки (0 - без ограничений) var $speedlimit = 5; # Лимит скорости выгрузки, кб/с var $enablepartial = 1; # Разрешение докачки (0 - запрещена) var $statfolder = 'stats/'; # Папка расположения статистики var $filename; # Выгружаемый файл (должен быть задан!) var $enabledcountry; # Разрешенные страны (список разделенный запятыми, # null - разрешеные все) var $disabledcountry; # Запрещенные страны (список разделенный запятыми) var $whitelist; # Список разрешенных ip-адресов (список разделенный запятыми) var $banlist; # Список запрещенных ip-адресов (список разделенный запятыми) var $transferbytes = 0; function cdownload($filename,$username) { $this->filename = $filename; if ($username) $this->username = ereg_replace('[^0-9a-za-z_-]','',$username).'/'; $fullpath = $this->statfolder.$this->username; if (!file_exists($fullpath)) mkdir($fullpath); } # end cdownload function verifycountry() { $usercountry = $this->getcountry($_server['remote_addr']); if ( ($this->enabledcountry && !in_array($usercountry,split(',',$this->enabledcountry))) || ($this->disabledcountry && in_array($usercountry,split(',',$this->disabledcountry))) || ($this->whitelist && !in_array($_server['remote_addr'],split(',',$this->whitelist))) || ($this->banlist && in_array($_server['remote_addr'],split(',',$this->banlist))) ) { header('http/1.0 403 forbidden'); header('warning: 99# you country or ip address disabled'); exit; } } function downloadfile() { $this->verifycountry(); $blocksize = 8192; $headererrortext = 'error! a possible size is exceeded'; $this->username = ereg_replace('[^0-9a-za-z_-]','',$this->username).'/'; $this->filename = preg_replace('/.{2}/','',$this->filename); if (!file_exists($this->filename)) { header('http/1.0 404 not found'); exit; } $fsize = filesize($this->filename); $ftime = date('d, d m y h:i:s t', filemtime($this->filename)); $fd = @fopen($this->filename, 'rb'); if (!$fd) { header('http/1.0 403 forbidden'); exit; } if ($this->enablepartial && ereg('bytes=([0-9]+)-',$_server['http_range'],$range)) { header('http/1.1 206 partial content'); $range = $range[1]; fseek($fd, $range); } else header('http/1.1 200 ok'); $fullpath = $this->statfolder.$this->username; $this->transferbytes = file($fullpath.$_server['remote_addr']); $this->transferbytes = $this->transferbytes[0]; if ($this->sizelimit && $this->transferbytes>$this->sizelimit) { header('http/1.0 403 forbidden'); header('warning: 99# '.$headererrortext); exit; } $fp = fopen($fullpath.$_server['remote_addr'],'w'); header('content-disposition: attachment; filename='.ereg_replace('^.*/','',$this->filename)); header('last-modified: '.$ftime); header('accept-ranges: bytes'); header('content-length: '.($fsize-$range)); header('content-range: bytes '.$range.'-'.($fsize-1).'/'.$fsize); header('content-type: application/octet-stream'); set_time_limit($this->downloadtimelimit); while (!feof($fd)) { if ($this->sizelimit && $this->transferbytes>$this->sizelimit) { header('warning: 99# '.$headererrortext); exit; } echo fread($fd, $blocksize); $this->transferbytes += $blocksize; fseek($fp,0); fwrite($fp,$this->transferbytes); if ($this->speedlimit) usleep(8000000/$this->speedlimit); } fclose($fp); fclose($fd); } # end downloadfile function getcountry($ip) { $result = 'unknow'; if (ereg('127.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}',$ip)) return 'localhost'; if (ereg('10.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}|191.168.[0-9]{1,3}.[0-9]{1,3}|'. '172.16.[0-9]{1,3}.[0-9]{1,3}',$ip)) return 'local network'; if ($ip!='') { $sock = fsockopen('whois.ripe.net',43,$errno,$errstr); if ($sock) { fputs ($sock,$ip."rn"); while (!feof($sock) && !preg_match('/country:s*(s*)/',$buf,$matches)) $buf = fgets($sock,128); $result = strtoupper($matches[1]); } fclose ($sock); } return $result; } # end getcountry } ?>
Источник: internet-technologies.ru
Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи