Если у Вас возникла потребность в отдаче (выгрузке) файлов Вашим пользователям, и Вы хотите контролировать кому, с какой скоростью и сколько отдать, предлагаю Вам свой 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 &#038;& !in_array($userCountry,split(',',$this->
		  enabledCountry))) ||
          ($this->disabledCountry &#038;& in_array($userCountry,split(',',$this->
		  disabledCountry))) ||
          ($this->whiteList &#038;& !in_array($_SERVER['REMOTE_ADDR'],split(',',$this->
		  whiteList))) ||
          ($this->banList &#038;& 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 &#038;& 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 &#038;& $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 &#038;& $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) &#038;& !preg_match('/country:s*(S*)/',$buf,$matches))
              $buf = fgets($sock,128);
            $result = strtoupper($matches[1]);
          }
          fclose ($sock);
        }
        return $result;
      } # End getCountry
    }

    ?>



Постоянные ссылки

При копировании ссылка на TeaM RSN обязательна!

URI

Html (ЖЖ)

BB-код (Для форумов)

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

Вы должны войти, чтобы оставить комментарий.