Skip to content
Newer
Older
100644 81 lines (78 sloc) 2.37 KB
a359e95 @desfrenes exported from svn
authored Mar 20, 2011
1 <?php
2 namespace shozu;
3 /**
4 * Very basic flood protection based on client IP. Don't trust this !
5 * This might suffice for common vandalism, but you'd better implement a
6 * proven solution way down your stack (the sooner, the better).
7 */
8 class AntiFlood
9 {
10 /**
11 * Throws an exception if resource has been hit too many times in a
12 * given period
13 *
14 * <code>
15 * // only access resource 5 times in a minute
16 * AntiFlood::limit('myResourceId', 5, 60);
17 * </code>
18 *
19 * @param string $resource_id identifier for protected resource
20 * @param integer $max_requests max number of requests
21 * @param integer $time_slice time period (in seconds)
22 */
23 public static function limit($resource_id, $max_requests = 5, $time_slice = 60, Cache $cache = null)
24 {
25 if(!self::hasAccess($resource_id, $max_requests, $time_slice, $cache))
26 {
27 throw new \shozu\AntiFlood\Exception('Flood detected', 403);
28 }
29 }
30
31 public static function hasAccess($resource, $max_requests = 5, $time_slice = 60, Cache $cache = null)
32 {
33 if(strtolower(php_sapi_name()) == 'cli')
34 {
35 return true;
36 }
37 if(is_null($cache))
38 {
39 if(function_exists('apc_fetch'))
40 {
41 $cache = Cache::_('anti-flood cache', array('type' => 'apc'));
42 }
43 else
44 {
45 $cache = Cache::_('anti-flood cache', array('type' => 'disk'));
46 }
47 }
48
49 $now = time();
50 $cache_key = 'antiflood - ' . $resource . ' - ' . getenv('REMOTE_ADDR');
51 $infos = $cache->fetch($cache_key);
52 if(!$infos)
53 {
54 $infos = array(
55 'start' => $now,
56 'count' => 1
57 );
58 $cache->store($cache_key,$infos, $time_slice);
59 return true;
60 }
61 $infos['count']++;
62 if($infos['count'] > $max_requests)
63 {
64 $elapsed = $now - $infos['start'];
65 if($elapsed > $time_slice)
66 {
67 $infos['count'] = 1;
68 $infos['start'] = $now;
69 $cache->store($cache_key,$infos, $time_slice);
70 return true;
71 }
72 else
73 {
74 return false;
75 }
76 }
77 $cache->store($cache_key,$infos, $time_slice);
78 return true;
79 }
80 }
Something went wrong with that request. Please try again.