This repository has been archived by the owner on Jul 17, 2023. It is now read-only.
forked from Santino-Wu/StnRateLimitingBundle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRateLimitingRequest.php
108 lines (93 loc) · 2.49 KB
/
RateLimitingRequest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
namespace Stn\RateLimitingBundle\Request;
use Symfony\Component\HttpFoundation\Request;
use Predis\ClientInterface;
/**
* Rate limiting request
*
* @author Santino Wu <[email protected]>
*/
class RateLimitingRequest implements RateLimitingRequestInterface
{
/**
* @var integer
*/
private $limit;
/**
* @var integer
*/
private $remaining;
/**
* @var integer
*/
private $resetAt;
/**
* Constructor
*
* @param Request $request The request
* @param ClientInterface $client Redis client
* @param array $configs
*/
public function __construct(Request $request, ClientInterface $client, array $configs)
{
$cacheServer = $client;
$cacheKey = $this->generateCacheKey($request, $configs);
// Get times
$cacheServer
->getProfile()
->defineCommand('countrequest', 'Stn\RateLimitingBundle\Redis\Command\CountRequestCommand')
;
$times = $cacheServer->countrequest($cacheKey, (integer) $configs['ttl']);
$timezone = new \DateTimeZone('UTC');
$dateTime = new \DateTime('now', $timezone);
$this->limit = (integer) $configs['limit'];
$this->remaining = (integer) ($configs['limit'] - $times);
$this->resetAt = $dateTime->getTimestamp() + $cacheServer->ttl($cacheKey);
}
/**
* {@inheritdoc}
*/
public function isExceeded()
{
return 0 > $this->remaining;
}
/**
* {@inheritdoc}
*/
public function getLimit()
{
return $this->limit;
}
/**
* {@inheritdoc}
*/
public function getRemaining()
{
return $this->remaining;
}
/**
* {@inheritdoc}
*/
public function getResetAt()
{
return $this->resetAt;
}
/**
* Generate cache key with hash
*
* @param Request $request
* @param array $configs
*/
private function generateCacheKey(Request $request, array $configs)
{
$clientIp = $request->getClientIp();
$routerName = $request->attributes->get('_route');
$prefix = isset($configs['key_prefix']) ? (string) $configs['key_prefix'] : 'RL';
$keyLength = isset($configs['key_length']) && $configs['key_length'] > 0 ? (integer) $configs['key_length'] : 8;
return sprintf(
'%s:%s:count',
$prefix,
substr(hash('sha1', $clientIp . $routerName), 0, $keyLength)
);
}
}