php-mpos/public/include/classes/memcache_ad.class.php
Joey 63c3b96a29 now enforce client & server validity on login with strict on
fixed csrf token check for a few pages where it mightve been broken
session manager now can be bound to base user class and used, like in login
logout now pushes you to login regardless, no longer has param to push to custom url
fixed validate client, hijacking sessions no longer works
2014-01-28 07:26:32 -05:00

69 lines
2.4 KiB
PHP

<?php
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
class MemcacheAntiDos
{
public $cache;
public static $key = 'mcad_';
public static $request_model = array(
'ident' => '',
'last_hit' => 0,
'last_flush' => 0,
'hits_since_flush' => 0
);
public $rate_limit_this_request = false;
public function __construct($config, &$memcache, $userORip, $request, $mcSettings) {
$this->cache = $memcache;
// set our config options
$per_page = $config['per_page'];
$flush_sec = $config['flush_seconds'];
$rate_limit = $config['rate_limit'];
unset($config);
// prep stuff we need to check this request
$key_md5 = substr(md5($userORip), 0, 4);
$request_md5 = substr(md5($request), 0, 4);
$request_key = $mcSettings['keyprefix'].self::$key.$key_md5."_".$request_md5."_".$per_page;
$request_data = $this->cache->get($request_key);
$now = time();
// check the request
if (is_array($request_data)) {
// this request key already exists, update it
$request_data['ident'] = $key_md5;
$request_data['last_hit'] = $now;
$request_data['hits_since_flush'] += 1;
// not rate limited yet, update the rest of the object
if ($request_data['hits_since_flush'] < $rate_limit) {
if (($request_data['last_flush'] + $flush_sec) <= $now || ($request_data['last_hit'] + $flush_sec) <= $now) {
// needs to be flushed
$request_data['hits_since_flush'] = 0;
$request_data['last_hit'] = 0;
$request_data['last_flush'] = $now;
// update the object
$this->cache->set($request_key, $request_data, $flush_sec);
$this->rate_limit_this_request = false;
} else {
// no flush, just update
$this->cache->set($request_key, $request_data, $flush_sec);
$this->rate_limit_this_request = false;
}
} else {
// too many hits, we should rate limit this
$this->rate_limit_this_request = true;
}
} else {
// doesn't exist for this request_key, create one
$new_data = self::$request_model;
$new_data['ident'] = $key_md5;
$new_data['last_hit'] = time();
$new_data['hits_since_flush'] = 1;
$new_data['last_flush'] = $now;
$this->cache->set($request_key, $new_data, $flush_sec);
$this->rate_limit_this_request = false;
}
}
public function rateLimitRequest() {
return $this->rate_limit_this_request;
}
}
?>