Files
UploadShied/core/Services/FloodService.php

59 lines
1.4 KiB
PHP

<?php
declare(strict_types=1);
namespace UploadLogger\Core\Services;
use UploadLogger\Core\Config;
final class FloodService
{
private Config $config;
public function __construct(?Config $config = null)
{
$this->config = $config ?? new Config(['modules' => []]);
}
public function check(string $ip): int
{
$window = (int)$this->config->get('limits.flood_window_sec', 60);
$stateDir = (string)$this->config->get('paths.state_dir', __DIR__ . '/../../state');
$key = rtrim($stateDir, '/\\') . '/upl_' . md5('v3|' . $ip);
$now = time();
$count = 0;
$start = $now;
$fh = @fopen($key, 'c+');
if ($fh === false) {
return 1;
}
if (flock($fh, LOCK_EX)) {
$raw = stream_get_contents($fh);
if ($raw !== false) {
if (preg_match('/^(\d+):(\d+)$/', trim($raw), $m)) {
$start = (int)$m[1];
$count = (int)$m[2];
}
}
if ((($now - $start) > $window)) {
$start = $now;
$count = 0;
}
$count++;
rewind($fh);
ftruncate($fh, 0);
fwrite($fh, $start . ':' . $count);
fflush($fh);
flock($fh, LOCK_UN);
}
fclose($fh);
return $count;
}
}