5 class Throttle extends \Rsi\Fred\Security\Check{
7 public $mask =
'/(\\.\\d+|(:\\d+){4})$/';
19 protected function subnet($addr = null){
20 return preg_replace($this->mask,
'',$addr ?: $this->
component(
'security')->remoteAddr);
24 return $this->path . str_replace([
'.',
':'],
'-',$this->
subnet($addr)) .
$this->ext;
28 $f = fopen($filename,
'r');
35 foreach((
new \GlobIterator($this->path .
'*' . $this->ext)) as $filename => $file)
36 if(trim($this->
timeLine($filename)) < $this->purgeLimit) \Rsi\File::unlink($filename);
40 if($time < $this->purgeLimit){
44 if($count > $this->limitBan)
return false;
45 if($prev === null ? $count == $this->limitLog : ($count >= $this->limitLog) && ($prev < $this->limitLog))
46 $this->
component(
'log')->add($this->logPrio,
'Subnet ' . $this->
subnet() .
' getting close to ban limit',__FILE__,__LINE__);
48 foreach($this->sleep as $limit => $time){
49 if($count < $limit)
break;
56 public function check($expected =
false){
58 if($exists = is_file($filename = $this->
filename())){
59 if((($result = $this->session->lastResult) === null) || ($this->session->lastCheck < $this->_fred->startTime - $this->checkTtl)){
61 $this->session->lastResult = $result = $this->
checkLimits(trim($time),$count = filesize($filename) - strlen($time),$this->session->prevCount);
62 $this->session->lastCheck = $this->_fred->startTime;
63 $this->session->prevCount = $count;
64 if($result === null) $exists =
false;
66 if($result ===
false)
return false;
68 $f = fopen($filename,$exists ?
'a' :
'w');
69 if(!$exists) fwrite($f,time() .
"\n");
70 fwrite($f,substr($char = date(
's'),0,1) ==
'0' ? substr($char,1,1) : chr($char + ($char < 35 ? 87 : 30)));
72 if(!$exists) chmod($filename,0666);
75 if($this->_fred->debug)
throw $e;
81 return \Rsi\File::unlink($this->
filename($addr));
90 if(!$this->_path) $this->_path = $this->
component(
'security')->path;
$logPrio
Log prio for the warning message.
$interval
Number of seconds after which the counter gets reset.
$ext
Extension for throttle registration file.
checkLimits($time, $count, $prev)
$checkTtl
Re-use throttle info for this amount of time (seconds).
$sleep
Extra sleep time (value, milliseconds) if the counter gets above a certain value (key, ascending).
$limitBan
Number of requests after which the subnet is banned.
$mask
IP address subnet mask (part to remove).
$limitLog
Number of requests after which the subnet is added to the log.
component($name)
Get a component (local or default).