Skip to content

Commit

Permalink
Fix the RateLimite issue when generating dynamic keys
Browse files Browse the repository at this point in the history
  • Loading branch information
MilesChou committed Dec 5, 2024
1 parent 7db7ea9 commit e11ff7d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/Illuminate/Cache/RateLimiter.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ public function limiter($name)

foreach ($result as $limit) {
if ($duplicates->contains($limit->key)) {
$limit->key = $limit->fallbackKey();
$limit->key = empty($limit->key)
? $limit->fallbackKey()
: $limit->key.':'.$limit->fallbackKey();
}
}

Expand Down
29 changes: 29 additions & 0 deletions tests/Cache/RateLimiterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Illuminate\Tests\Cache;

use Illuminate\Cache\ArrayStore;
use Illuminate\Cache\RateLimiter;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Cache\Repository;
use Illuminate\Contracts\Cache\Repository as Cache;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -38,6 +40,33 @@ public function testRegisterNamedRateLimiter(mixed $name, string $expected): voi

$this->assertNotNull($limiterClosure);
}

public function testShouldUseOriginKeyAsPrefixWhenMultipleLimiterWithSameKey()
{
$rateLimiter = new RateLimiter(new Repository(new ArrayStore));

$rateLimiter->for('user_limiter1', fn (string $userId) => [
Limit::perSecond(3)->by($userId),
Limit::perMinute(5)->by($userId),
]);

$userId1 = '123';
$userId2 = '456';

$userLimiters1 = $rateLimiter->limiter('user_limiter1')($userId1);
$userLimiters2 = $rateLimiter->limiter('user_limiter1')($userId2);

for ($i = 0; $i < 3; $i++) {
$this->assertFalse($rateLimiter->tooManyAttempts($userLimiters1[0]->key, $userLimiters1[0]->maxAttempts));
$this->assertFalse($rateLimiter->tooManyAttempts($userLimiters2[0]->key, $userLimiters2[0]->maxAttempts));

$rateLimiter->hit($userLimiters1[0]->key, $userLimiters1[0]->decaySeconds);
$rateLimiter->hit($userLimiters2[0]->key, $userLimiters2[0]->decaySeconds);
}

$this->assertNotSame($userLimiters1[0]->key, $userLimiters2[0]->key);
$this->assertNotSame($userLimiters1[1]->key, $userLimiters2[1]->key);
}
}

enum BackedEnumNamedRateLimiter: string
Expand Down

0 comments on commit e11ff7d

Please sign in to comment.