adding traficLimiter
saving config in class constants
This commit is contained in:
parent
18d590550b
commit
74162ee90d
1 changed files with 71 additions and 9 deletions
|
@ -1,6 +1,17 @@
|
|||
<?php
|
||||
class DataHandler {
|
||||
protected $data_folder = 'data/';
|
||||
// (string) folder to store data in
|
||||
// webserver has to have write access to this folder
|
||||
// must end with a slash
|
||||
const DATA_FOLDER = 'data/';
|
||||
|
||||
// (string) filename to store trafic_limiter data
|
||||
// could lead to data disclosure if filename extension is not php
|
||||
const IP_LIST_FILENAME = 'trafic_limiter.php';
|
||||
|
||||
// (int) limit request per IP in seconds; no limit if zero
|
||||
const TRAFIC_LIMITER = 30;
|
||||
|
||||
protected $id;
|
||||
protected $version;
|
||||
|
||||
|
@ -33,16 +44,27 @@ class DataHandler {
|
|||
$return = new stdClass();
|
||||
$return->id = $this->id;
|
||||
|
||||
// check if version is out of date
|
||||
// try to read existing data
|
||||
$data_org = $this->readData();
|
||||
if ($data_org !== false && md5($data_org) !== $version) {
|
||||
$return->result = false;
|
||||
$return->errorMsg = 'used version is out of date';
|
||||
return $return;
|
||||
if ($data_org !== false) {
|
||||
// check if version is out of date
|
||||
if (md5($data_org) !== $version) {
|
||||
$return->result = false;
|
||||
$return->errorMsg = 'used version is out of date';
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// check traficLimiter
|
||||
if (!$this->traficLimiterCanPass()) {
|
||||
$return->result = false;
|
||||
$return->errorMsg = 'to many request in last ' . self::TRAFIC_LIMITER . ' seconds from your IP address';
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
// write data
|
||||
if(file_put_contents($this->data_folder.$this->id, $data, LOCK_EX ) === false) {
|
||||
if(file_put_contents(self::DATA_FOLDER.$this->id, $data, LOCK_EX ) === false) {
|
||||
$return->result = false;
|
||||
$return->errorMsg = 'data could not be written';
|
||||
return $return;
|
||||
|
@ -63,13 +85,53 @@ class DataHandler {
|
|||
}
|
||||
|
||||
// check if id is already used, generate new one if necessary
|
||||
if (file_exists($this->data_folder.$randomString)) $randomString = getNewId();
|
||||
if (file_exists(self::DATA_FOLDER.$randomString)) $randomString = getNewId();
|
||||
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
/*
|
||||
* limit request per IP
|
||||
* returns true on valid request
|
||||
* returns false on invalid request or error
|
||||
*/
|
||||
protected function traficLimiterCanPass() {
|
||||
if (self::TRAFIC_LIMITER === 0) return true;
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$filename = self::DATA_FOLDER.self::IP_LIST_FILENAME;
|
||||
|
||||
// create storage for ip_list if not exists
|
||||
if (file_exists($filename) === false) {
|
||||
if (file_put_contents($filename, "<?php\n\$ip_list=array();\n?>") === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// load ip_list
|
||||
require $filename;
|
||||
|
||||
// check if IP can pass
|
||||
if (isset($ip_list[$ip]) && (($ip_list[$ip] + self::TRAFIC_LIMITER) > time())) return false;
|
||||
|
||||
// delete expired IPs
|
||||
foreach ($ip_list as $ip => $time) {
|
||||
if (($time + self::TRAFIC_LIMITER) < time()) unset($ip_list[$ip]);
|
||||
}
|
||||
|
||||
// add new IP
|
||||
$ip_list[$ip] = time();
|
||||
|
||||
// save ip_list
|
||||
if (file_put_contents($filename, "<?php\n\$ip_list=" . var_export($ip_list, true) . "\n?>") === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function readData() {
|
||||
return file_exists($this->data_folder.$this->id) ? file_get_contents($this->data_folder.$this->id) : false;
|
||||
return file_exists(self::DATA_FOLDER.$this->id) ? file_get_contents(self::DATA_FOLDER.$this->id) : false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
Loading…
Reference in a new issue