Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ThrottleRequests
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
3 / 3
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handle
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 addHeaders
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Cache\RateLimiter;
7use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
8use Symfony\Component\HttpKernel\Exception\HttpException;
9
10class ThrottleRequests
11{
12    protected $limiter;
13
14    public function __construct(RateLimiter $limiter)
15    {
16        $this->limiter = $limiter;
17    }
18
19    public function handle($request, Closure $next, $key = null, $maxAttempts = 8, $decayMinutes = 1)
20    {
21        $key = $key ?: $request->ip();
22
23        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
24            $retryAfter = $this->limiter->availableIn($key);
25
26            $exception = new HttpException(SymfonyResponse::HTTP_TOO_MANY_REQUESTS, 'Too Many Requests');
27            $exception->setHeaders(['Retry-After' => $retryAfter]);
28
29            throw $exception;
30        }
31
32        $this->limiter->hit($key, $decayMinutes * 60);
33
34        $response = $next($request);
35
36        return $this->addHeaders($response, $key, $maxAttempts, $decayMinutes);
37    }
38
39    protected function addHeaders($response, $key, $maxAttempts, $decayMinutes)
40    {
41        $response->headers->add([
42            'X-RateLimit-Limit' => $maxAttempts,
43            'X-RateLimit-Remaining' => $maxAttempts - $this->limiter->attempts($key) + 1,
44            'X-RateLimit-Reset' => $this->limiter->availableIn($key),
45        ]);
46
47        return $response;
48    }
49}