diff --git a/src/Symfony/Component/RateLimiter/Policy/FixedWindowLimiter.php b/src/Symfony/Component/RateLimiter/Policy/FixedWindowLimiter.php index 3f982e602ce67..298cd1ba24321 100644 --- a/src/Symfony/Component/RateLimiter/Policy/FixedWindowLimiter.php +++ b/src/Symfony/Component/RateLimiter/Policy/FixedWindowLimiter.php @@ -68,7 +68,7 @@ public function reserve(int $tokens = 1, float $maxTime = null): Reservation $reservation = new Reservation($now, new RateLimit($window->getAvailableTokens($now), \DateTimeImmutable::createFromFormat('U', floor($now)), true, $this->limit)); } else { - $waitDuration = $window->calculateTimeForTokens($tokens); + $waitDuration = $window->calculateTimeForTokens($tokens, $now); if (null !== $maxTime && $waitDuration > $maxTime) { // process needs to wait longer than set interval diff --git a/src/Symfony/Component/RateLimiter/Policy/Window.php b/src/Symfony/Component/RateLimiter/Policy/Window.php index 93452797075a0..39248a53d7f7c 100644 --- a/src/Symfony/Component/RateLimiter/Policy/Window.php +++ b/src/Symfony/Component/RateLimiter/Policy/Window.php @@ -75,15 +75,13 @@ public function getAvailableTokens(float $now) return $this->maxSize - $this->hitCount; } - public function calculateTimeForTokens(int $tokens): int + public function calculateTimeForTokens(int $tokens, float $now): int { if (($this->maxSize - $this->hitCount) >= $tokens) { return 0; } - $cyclesRequired = ceil($tokens / $this->maxSize); - - return $cyclesRequired * $this->intervalInSeconds; + return (int) ceil($this->timer + $this->intervalInSeconds - $now); } public function __serialize(): array diff --git a/src/Symfony/Component/RateLimiter/Tests/Policy/FixedWindowLimiterTest.php b/src/Symfony/Component/RateLimiter/Tests/Policy/FixedWindowLimiterTest.php index 0cffc14e1aee6..84df7bc850aae 100644 --- a/src/Symfony/Component/RateLimiter/Tests/Policy/FixedWindowLimiterTest.php +++ b/src/Symfony/Component/RateLimiter/Tests/Policy/FixedWindowLimiterTest.php @@ -37,6 +37,7 @@ protected function setUp(): void public function testConsume() { + $now = time(); $limiter = $this->createLimiter(); // fill 9 tokens in 45 seconds @@ -51,6 +52,9 @@ public function testConsume() $rateLimit = $limiter->consume(); $this->assertFalse($rateLimit->isAccepted()); $this->assertSame(10, $rateLimit->getLimit()); + // Window ends after 1 minute + $retryAfter = \DateTimeImmutable::createFromFormat('U', $now + 60); + $this->assertEquals($retryAfter, $rateLimit->getRetryAfter()); } /** pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy