From 2e163db8265757266bd6d9e4906182706c9ca0e2 Mon Sep 17 00:00:00 2001 From: Mohamed Said Date: Sat, 26 Aug 2017 19:24:18 +0200 Subject: [PATCH 1/2] let ThrottleRequestsWithRedis extend ThrottleRequests and dry --- .../Routing/Middleware/ThrottleRequests.php | 13 ++- .../Middleware/ThrottleRequestsWithRedis.php | 105 +----------------- 2 files changed, 17 insertions(+), 101 deletions(-) diff --git a/src/Illuminate/Routing/Middleware/ThrottleRequests.php b/src/Illuminate/Routing/Middleware/ThrottleRequests.php index 067dd699667c..a448ced1e726 100644 --- a/src/Illuminate/Routing/Middleware/ThrottleRequests.php +++ b/src/Illuminate/Routing/Middleware/ThrottleRequests.php @@ -109,7 +109,7 @@ protected function resolveRequestSignature($request) */ protected function buildException($key, $maxAttempts) { - $retryAfter = $this->limiter->availableIn($key); + $retryAfter = $this->getTimeUntilNextRetry($key); $headers = $this->getHeaders( $maxAttempts, @@ -122,6 +122,17 @@ protected function buildException($key, $maxAttempts) ); } + /** + * Get the number of seconds until the next retry. + * + * @param string $key + * @return int + */ + protected function getTimeUntilNextRetry($key) + { + return $this->limiter->availableIn($key); + } + /** * Add the limit header information to the given response. * diff --git a/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php b/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php index 369a78706466..25259a19c6b1 100644 --- a/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php +++ b/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php @@ -3,18 +3,13 @@ namespace Illuminate\Routing\Middleware; use Closure; -use RuntimeException; -use Illuminate\Support\Str; -use Illuminate\Support\InteractsWithTime; use Illuminate\Redis\Limiters\DurationLimiter; use Symfony\Component\HttpFoundation\Response; use Illuminate\Contracts\Redis\Factory as Redis; use Symfony\Component\HttpKernel\Exception\HttpException; -class ThrottleRequestsWithRedis +class ThrottleRequestsWithRedis extends ThrottleRequests { - use InteractsWithTime; - /** * The Redis factory implementation. * @@ -76,104 +71,14 @@ public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes } /** - * Resolve the number of attempts if the user is authenticated or not. - * - * @param \Illuminate\Http\Request $request - * @param int|string $maxAttempts - * @return int - */ - protected function resolveMaxAttempts($request, $maxAttempts) - { - if (Str::contains($maxAttempts, '|')) { - $maxAttempts = explode('|', $maxAttempts, 2)[$request->user() ? 1 : 0]; - } - - return (int) $maxAttempts; - } - - /** - * Resolve request signature. - * - * @param \Illuminate\Http\Request $request - * @return string - * @throws \RuntimeException - */ - protected function resolveRequestSignature($request) - { - if ($user = $request->user()) { - return sha1($user->getAuthIdentifier()); - } - - if ($route = $request->route()) { - return sha1($route->getDomain().'|'.$request->ip()); - } - - throw new RuntimeException( - 'Unable to generate the request signature. Route unavailable.' - ); - } - - /** - * Create a 'too many attempts' exception. + * Get the number of seconds until the next retry. * * @param string $key - * @param int $maxAttempts - * @return \Symfony\Component\HttpKernel\Exception\HttpException - */ - protected function buildException($key, $maxAttempts) - { - $retryAfter = $this->decaysAt - $this->currentTime(); - - $headers = $this->getHeaders( - $maxAttempts, - $this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter), - $retryAfter - ); - - return new HttpException( - 429, 'Too Many Attempts.', null, $headers - ); - } - - /** - * Add the limit header information to the given response. - * - * @param \Symfony\Component\HttpFoundation\Response $response - * @param int $maxAttempts - * @param int $remainingAttempts - * @param int|null $retryAfter - * @return \Symfony\Component\HttpFoundation\Response - */ - protected function addHeaders(Response $response, $maxAttempts, $remainingAttempts, $retryAfter = null) - { - $response->headers->add( - $this->getHeaders($maxAttempts, $remainingAttempts, $retryAfter) - ); - - return $response; - } - - /** - * Get the limit headers information. - * - * @param int $maxAttempts - * @param int $remainingAttempts - * @param int|null $retryAfter - * @return array + * @return int */ - protected function getHeaders($maxAttempts, $remainingAttempts, $retryAfter = null) + protected function getTimeUntilNextRetry($key) { - $headers = [ - 'X-RateLimit-Limit' => $maxAttempts, - 'X-RateLimit-Remaining' => $remainingAttempts, - ]; - - if (! is_null($retryAfter)) { - $headers['Retry-After'] = $retryAfter; - $headers['X-RateLimit-Reset'] = $this->availableAt($retryAfter); - } - - return $headers; + return $this->decaysAt - $this->currentTime(); } /** From 0d9386404ddae3629c039f5b2d3f6cb921550eef Mon Sep 17 00:00:00 2001 From: Mohamed Said Date: Sat, 26 Aug 2017 19:25:27 +0200 Subject: [PATCH 2/2] fix style --- src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php b/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php index 25259a19c6b1..b188bbba0d3e 100644 --- a/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php +++ b/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php @@ -4,9 +4,7 @@ use Closure; use Illuminate\Redis\Limiters\DurationLimiter; -use Symfony\Component\HttpFoundation\Response; use Illuminate\Contracts\Redis\Factory as Redis; -use Symfony\Component\HttpKernel\Exception\HttpException; class ThrottleRequestsWithRedis extends ThrottleRequests {