Если у Вас возникла потребность в отдаче (выгрузке) файлов Вашим пользователям, и Вы хотите контролировать кому, с какой скоростью и сколько отдать, предлагаю Вам свой 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.
Скачать одним архивом: download.rar
Пример:
Файл 1.php. Качаем линк http://serv/1.php?download=docucd_v210_[iso].zip
< ?php # 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(); ?>
Код класса
< ?php # 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 } ?>
Постоянные ссылки
При копировании ссылка на TeaM RSN обязательна!
Оставить комментарий
Вы должны войти, чтобы оставить комментарий.