diff --git a/src/Illuminate/Cache/ArrayStore.php b/src/Illuminate/Cache/ArrayStore.php index b1f066dff939..22b42ba5f10f 100644 --- a/src/Illuminate/Cache/ArrayStore.php +++ b/src/Illuminate/Cache/ArrayStore.php @@ -57,7 +57,7 @@ public function get($key) $expiresAt = $item['expiresAt'] ?? 0; - if ($expiresAt !== 0 && $this->currentTime() >= $expiresAt) { + if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) { $this->forget($key); return; diff --git a/src/Illuminate/Foundation/Exceptions/Handler.php b/src/Illuminate/Foundation/Exceptions/Handler.php index 301918317dd7..1832b3206ecd 100644 --- a/src/Illuminate/Foundation/Exceptions/Handler.php +++ b/src/Illuminate/Foundation/Exceptions/Handler.php @@ -360,7 +360,7 @@ protected function shouldntReport(Throwable $e) with($throttle->key ?: 'illuminate:foundation:exceptions:'.$e::class, fn ($key) => $this->hashThrottleKeys ? md5($key) : $key), $throttle->maxAttempts, fn () => true, - 60 * $throttle->decayMinutes + $throttle->decayMinutes ); }), rescue: false, report: false); } diff --git a/tests/Foundation/FoundationExceptionsHandlerTest.php b/tests/Foundation/FoundationExceptionsHandlerTest.php index a804ecab2f10..15a61097b4b4 100644 --- a/tests/Foundation/FoundationExceptionsHandlerTest.php +++ b/tests/Foundation/FoundationExceptionsHandlerTest.php @@ -705,52 +705,6 @@ public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 6 $this->assertCount(14, $reported); $this->assertSame('Something in the app went wrong.', $reported[0]->getMessage()); } - - public function testRateLimitExpiresOnBoundary() - { - $handler = new class($this->container) extends Handler - { - protected function throttle($e) - { - return Limit::perMinute(1); - } - }; - $reported = []; - $handler->reportable(function (\Throwable $e) use (&$reported) { - $reported[] = $e; - - return false; - }); - $this->container->instance(RateLimiter::class, $limiter = new class(new Repository(new ArrayStore)) extends RateLimiter - { - public $attempted = 0; - - public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 60) - { - $this->attempted++; - - return parent::attempt(...func_get_args()); - } - }); - - Carbon::setTestNow('2000-01-01 00:00:00.000'); - $handler->report(new Exception('Something in the app went wrong 1.')); - Carbon::setTestNow('2000-01-01 00:00:59.999'); - $handler->report(new Exception('Something in the app went wrong 1.')); - - $this->assertSame(2, $limiter->attempted); - $this->assertCount(1, $reported); - $this->assertSame('Something in the app went wrong 1.', $reported[0]->getMessage()); - - Carbon::setTestNow('2000-01-01 00:01:00.000'); - $handler->report(new Exception('Something in the app went wrong 2.')); - Carbon::setTestNow('2000-01-01 00:01:59.999'); - $handler->report(new Exception('Something in the app went wrong 2.')); - - $this->assertSame(4, $limiter->attempted); - $this->assertCount(2, $reported); - $this->assertSame('Something in the app went wrong 2.', $reported[1]->getMessage()); - } } class CustomException extends Exception diff --git a/tests/Integration/Http/ThrottleRequestsTest.php b/tests/Integration/Http/ThrottleRequestsTest.php index 7f4382ad0462..6ddd2a0ef51e 100644 --- a/tests/Integration/Http/ThrottleRequestsTest.php +++ b/tests/Integration/Http/ThrottleRequestsTest.php @@ -4,7 +4,6 @@ use Illuminate\Cache\RateLimiter; use Illuminate\Cache\RateLimiting\GlobalLimit; -use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Container\Container; use Illuminate\Http\Exceptions\ThrottleRequestsException; use Illuminate\Routing\Middleware\ThrottleRequests; @@ -117,62 +116,4 @@ public function testItCanGenerateDefinitionViaStaticMethod() $signature = (string) ThrottleRequests::with(prefix: 'foo'); $this->assertSame('Illuminate\Routing\Middleware\ThrottleRequests:60,1,foo', $signature); } - - public function testItCanThrottlePerMinute() - { - $rateLimiter = Container::getInstance()->make(RateLimiter::class); - $rateLimiter->for('test', fn () => Limit::perMinute(3)); - Route::get('/', fn () => 'ok')->middleware(ThrottleRequests::using('test')); - - Carbon::setTestNow('2000-01-01 00:00:00.000'); - - // Make 3 requests, each a second apart, that should all be successful. - - for ($i = 0; $i < 3; $i++) { - match ($i) { - 0 => $this->assertSame('2000-01-01 00:00:00.000', now()->toDateTimeString('m')), - 1 => $this->assertSame('2000-01-01 00:00:01.000', now()->toDateTimeString('m')), - 2 => $this->assertSame('2000-01-01 00:00:02.000', now()->toDateTimeString('m')), - }; - - $response = $this->get('/'); - $response->assertOk(); - $response->assertContent('ok'); - $response->assertHeader('X-RateLimit-Limit', 3); - $response->assertHeader('X-RateLimit-Remaining', 3 - ($i + 1)); - - Carbon::setTestNow(now()->addSecond()); - } - - // It is now 3 seconds past and we will make another request that - // should be rate limited. - - $this->assertSame('2000-01-01 00:00:03.000', now()->toDateTimeString('m')); - - $response = $this->get('/'); - $response->assertStatus(429); - $response->assertHeader('Retry-After', 57); - $response->assertHeader('X-RateLimit-Reset', now()->addSeconds(57)->timestamp); - $response->assertHeader('X-RateLimit-Limit', 3); - $response->assertHeader('X-RateLimit-Remaining', 0); - - // We will now make it the very end of the minute, to check boundaries, - // and make another request that should be rate limited and tell us to - // try again in 1 second. - Carbon::setTestNow(now()->endOfMinute()); - $this->assertSame('2000-01-01 00:00:59.999', now()->toDateTimeString('m')); - - $response = $this->get('/'); - $response->assertHeader('Retry-After', 1); - $response->assertHeader('X-RateLimit-Reset', now()->addSeconds(1)->timestamp); - $response->assertHeader('X-RateLimit-Limit', 3); - $response->assertHeader('X-RateLimit-Remaining', 0); - - // We now tick over into the next second. We should now be able to make - // requests again. - Carbon::setTestNow('2000-01-01 00:01:00.000'); - - $response = $this->get('/'); - $response->assertOk(); - } }