RateLimit API Reference
namespace Petrovo\RateLimit;
class RateLimiter
Veřejné Metody
setPath(string $storagePath): void
NUTNÉ: Nastaví cestu pro rate limit data. Musí být voláno během bootstrap!
Parametry:
- $storagePath (string) – Absolutní cesta k adresáři (bez trailing slash)
Příklad:
// app/bootstrap.php (VYŽADOVÁNO)
RateLimiter::setPath(DIR . '/var/rate-limits');
// Nebo vlastní cesta:
RateLimiter::setPath('/tmp/rate-limits');
Chování:
- Pokud setPath() není zavolán → RuntimeException při prvním check()
- Cesta nemusí existovat (vytvoří se automaticky)
- Trailing slash se automaticky odstraňuje
- Adresář je vytvořen s permisemi 0755 (recursive)
Proč je to povinné? - Explicitní inicializace (fail-fast vs. silent fallback) - Jasné bootstrap požadavky - Léčí proti neočekávaným chybám
check(string $ip, int $maxRequests = 20, int $perSeconds = 60): bool
Zkontroluje, zda je request z dané IP adresy v limitech.
Parametry:
$ip(string) – IP adresa requestu$maxRequests(int) – Maximální počet requestů (výchozí: 20)$perSeconds(int) – Časové okno v sekundách (výchozí: 60)
Návratová hodnota:
true– Request je v limitech, povoluj hofalse– Limit je překročen, zamítni request (HTTP 429)
Příklad – Login Endpoint:
$ip = $_SERVER['REMOTE_ADDR'];
if (!RateLimiter::check($ip, 10, 300)) { // 10 pokusů za 5 minut
http_response_code(429);
exit('Příliš mnoho pokusů. Zkus za 5 minut.');
}
// OK – zpracuj login
Příklad – Přísný API Limit:
if (!RateLimiter::check($ip, 5, 60)) { // 5 requestů za minutu
header('HTTP/1.1 429 Too Many Requests');
exit(json_encode(['error' => 'Rate limit exceeded']));
}
Vnitřní Chování:
- IP je hashována SHA-256 (prvních 16 znaků) → název souboru
- Soubor je zamčen (flock) – zamezí race conditions
- Staré timestampy mimo okno jsou odfiltrován (sliding window)
- Pokud limit umožňuje → timestamp se uloží, vrátí true
- Pokud limit zabraňuje → nic se neuloží, vrátí false
- Fail-open: Pokud se nepodaří otevřít/zamknout soubor → vrátí true (bezpečnost)
getCount(string $ip, int $perSeconds = 60): int
Vrátí počet requestů ze dané IP v aktuálním okně (bez zamykání).
Parametry:
$ip(string) – IP adresa$perSeconds(int) – Časové okno (výchozí: 60 sekund)
Návratová hodnota:
- int – Počet requestů v okně (0 pokud IP nemá data)
Příklad – Monitorování:
$ip = $_SERVER['REMOTE_ADDR'];
$count = RateLimiter::getCount($ip, 60);
if ($count > 15) {
// Podezřelá aktivita, log to
error_log("Vysoká aktivita z $ip: $count requestů/min");
}
Poznámka:
- Pouze čtení – bez zápisu do souboru
- Bez file locking (rychlejší pro monitoring)
- Vrátí 0 pokud soubor neexistuje
reset(string $ip): bool
Smazání všech rate limit dat pro danou IP (výmaz souboru).
Parametry:
$ip(string) – IP adresa pro resetování
Návratová hodnota:
true– Reset успешен (nebo soubor neexistoval)false– Chyba při mazání souboru
Příklad – Admin Funkce:
// User přikazuje resetovat limit pro konkrétní IP
if ($_GET['action'] === 'reset-limit' && is_admin()) {
$ip = $_GET['ip'];
if (RateLimiter::reset($ip)) {
echo "Reset limit pro $ip OK";
} else {
echo "Chyba při resetu";
}
}
Příklad – Reset po Úspěšném Login:
// Uživatel se úspěšně přihlásil – smaž limit
if ($login_success) {
RateLimiter::reset($_SERVER['REMOTE_ADDR']);
// Teď má čistý štít pro další pokusy
}
Interní Metody
Následující metody jsou private a nejsou určeny k přímému volání:
resolveFilePath(string $ip): string
Vrátí cestu souboru pro danou IP. Používá SHA-256 hash prvních 16 znaků.
getCacheDir(): string
Vrátí cestu k adresáři rate-limits (bez vytvoření).
ensureCacheDir(): void
Zajistí, že adresář existuje (vytvoří pokud potřeba).
cleanupOldFiles(): void
Smaž soubory starší 1 hodinu. Volá se automaticky (~1% requestů).
Chybové Chování
Fail-Open Design
Pokud cokoliv selže (chyba souborů, zamykání, JSON), RateLimiter vrátí true (povolí request):
$fp = fopen($file, 'c+');
if ($fp === false) {
return true; // Chyba souborů → povoleno (bezpečnost)
}
if (!flock($fp, LOCK_EX)) {
fclose($fp);
return true; // Nemůž zamknout → povoleno
}
Důvod: Raději nechť přejde pár extra requestů, než aby brániš legitimnímu provozu.
Příklady Standardních Limitů
// Login endpoint – střídmě
RateLimiter::check($ip, 10, 300); // 10 pokusů / 5 minut
// API endpoint – normálně
RateLimiter::check($ip, 100, 60); // 100 req / minutu
// Veřejný formulář (kontakt) – velmi přísně
RateLimiter::check($ip, 3, 3600); // 3 / hodina
// Password reset – přísně
RateLimiter::check($ip, 5, 3600); // 5 / hodina
// API webhook – volné
RateLimiter::check($ip, 1000, 60); // 1000 / minutu
Backcompat s Příponou .json
RateLimiter pracuje s JSON soubory v var/rate-limits/:
{
"requests": [timestamp1, timestamp2, ...]
}
Pole je pole Unix timestampů. Žádné další metadata se neukládá (je to maximálně jednoduché).