Controllable feedback of files

If you had need{requirement} for feedback (unloading) of files to your users, and you want to supervise to whom, with what speed and how much to give, I offer you the php-class. The given class is a motley crew of an another's code under my edition and improvements. Copyrights I do not bring, since for often it is difficult to define{determine}, who exactly posessed the right of superiority{championship} on this or that piece of a code, and to be engaged in calculation of authors specially desires no. On semu beforehand I bring to unknown authors of an apology for plagiarism:). But me as practising programmer, the result interested first of all. More shortly: all interested person / JAFUbªsT``¿¼ who would not like to translate time for the invention of a bicycle, I suggest to use mine.


The description


The class submitted below allows:


- To allow / forbid dokachku files;

- To limit speed of feedback (by default 5 KB);

- To give files to users on the names transmitted to a class (authorization of these lozhitsja on your shoulders - the class only accepts a login name and on it  counts volume).


For each user in a folder stats the folder named the user is (by default got{started}. From a login name regehkspom it is cut out all but "0-9a-za-z_-". For each ip-address the corresponding file (for example is got{started}: 10.1.3.94) in which during an operating time of a script the downloaded volume enters the name. On this file actually the control of the given volume also is carried out. Removal / zeroing of a file by a class is not made - if it is necessary for you - add.

To resolve / forbid feedback of files under the list of the countries, ip-addresses. In all lists a separator a point, all signs (including blanks are taken into account!). Lokalkhost and local addresses (192.168.xxx.xxx, 10.xxx.xxx.xxx, 172.16.xxx.xxx) are called as localhost and local network accordingly. Definition of the country on an ip-address is carried out through service whois.ripe.net.


Example:


File 1.php. We swing a link 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 ();


?>


Code of a class


* filename: cdownload.inc.php



define (' kb ', 1024);

define (' mb ', kb*1024);


class cdownload {

* -------------------------------------------------------------------------------------

* The description: a unloading of a file to the user with support dokachki and restriction of speed

* -------------------------------------------------------------------------------------

var $downloadtimelimit = 300; * the Limit of an operating time of function of a unloading

var $username = ' anonymous / '; * the User by default

var $sizelimit = 0; * the Limit of volume of a unloading (0 - without restrictions)

var $speedlimit = 5; * the Limit of speed of a unloading, kb/s

var $enablepartial = 1; * the Sanction dokachki (0 - it is forbidden)

var $statfolder = ' stats / '; * the Folder of an arrangement of statistics

var $filename; * the Unloaded file (should be set!)

var $enabledcountry; * the Resolved{Allowed} countries (the list divided{shared} by points,

* null - razreshenye all)

var $disabledcountry; * the Forbidden countries (the list divided{shared} by points)

var $whitelist; * the List of the resolved{allowed} ip-addresses (the list divided{shared} by points)

var $banlist; * the List of the forbidden ip-addresses (the list divided{shared} by points)


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

}


?>