1 | <?php |
||
11 | class RateLimitMiddleware implements MiddlewareInterface |
||
12 | { |
||
13 | protected Limiter $limiter; |
||
|
|||
14 | protected int $ttl = 60; // sec |
||
15 | protected int $max = 60; // sec |
||
16 | protected string $keyPrefix = 'limiter'; |
||
17 | protected ResponseInterface $responseTooManyRequest; |
||
18 | protected string $keyAttr = 'client-ip'; |
||
19 | |||
20 | public function __construct(Limiter $limiter, ResponseInterface $response) |
||
21 | { |
||
22 | $this->limiter = $limiter; |
||
23 | $this->responseTooManyRequest = $response->withStatus(429, 'Too Many Requests'); |
||
24 | } |
||
25 | |||
26 | 4 | public function setKeyAttr(string $attr): void |
|
27 | { |
||
28 | 4 | $this->keyAttr = $attr; |
|
29 | 4 | } |
|
30 | 4 | ||
31 | public function setKeyPrefix(string $keyPrefix): void |
||
32 | 3 | { |
|
33 | $this->keyPrefix = $keyPrefix; |
||
34 | 3 | } |
|
35 | 3 | ||
36 | public function setMax(int $max): void |
||
37 | 1 | { |
|
38 | $this->max = $max; |
||
39 | 1 | } |
|
40 | 1 | ||
41 | public function setTtl(int $ttl): void |
||
42 | 1 | { |
|
43 | $this->ttl = $ttl; |
||
44 | 1 | } |
|
45 | 1 | ||
46 | public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface |
||
47 | 1 | { |
|
48 | $limiterKey = $this->getKey($request); |
||
49 | 1 | ||
50 | 1 | if ($this->limiter->isExceeded($limiterKey, $this->max)) { |
|
51 | return $this->responseTooManyRequest; |
||
52 | 4 | } |
|
53 | |||
54 | 4 | $response = $next->handle($request); |
|
55 | $this->limiter->inc($limiterKey, $this->ttl); |
||
56 | 4 | ||
57 | 1 | return $response; |
|
58 | } |
||
59 | |||
60 | 4 | protected function getKey(ServerRequestInterface $request): string |
|
61 | 4 | { |
|
62 | $key = $request->getAttribute($this->keyAttr); |
||
63 | 4 | return sprintf('%s.%s', $this->keyPrefix, $key); |
|
64 | } |
||
65 | } |
||
66 |