<?php
namespace Plugin\AccessRateLimiter42;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Response;
use Plugin\AccessRateLimiter42\Service\RateLimiterService;
use Eccube\Event\TemplateEvent;
use Symfony\Component\HttpFoundation\RequestStack;
class Event implements EventSubscriberInterface{
/** @var RateLimiterService */
private $rateLimiterService;
/** @var RequestStack */
private $requestStack;
public function __construct(
RateLimiterService $rateLimiterService,
RequestStack $requestStack
){
$this->rateLimiterService = $rateLimiterService;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents(){
return [
KernelEvents::REQUEST => ['onKernelRequest', 1024],
'index.twig' => 'onRender',
'default_frame.twig' => 'onRender',
'error.twig' => 'onRender',
];
}
public function onKernelRequest(RequestEvent $event){
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
$path = $request->getPathInfo();
$adminRouteDir = $request->server->get('ECCUBE_ADMIN_ROUTE');
if(strpos($path, $adminRouteDir) !== false){
return;
}
$ip = $this->getClientIp($request);
if ($this->rateLimiterService->checkRateLimit($ip)) {
$this->rateLimiterService->recordAccess($ip);
$this->rateLimiterService->recordBlockedIp($ip);
$template = $this->rateLimiterService->getBlockTemplate();
$response = new Response(
$template,
429,
['Content-Type' => 'text/html; charset=UTF-8']
);
$event->setResponse($response);
return;
}
}
public function onRender(TemplateEvent $event){
$request = $this->requestStack->getCurrentRequest();
$ip = $this->getClientIp($request);
$this->rateLimiterService->recordAccess($ip);
$this->rateLimiterService->cleanupOldLogs();
}
/**
* クライアントIPアドレス取得
*/
private function getClientIp($request){
$ip = $request->getClientIp();
if ($request->headers->has('X-Forwarded-For')) {
$ips = explode(',', $request->headers->get('X-Forwarded-For'));
$ip = trim($ips[0]);
}
return $ip;
}
}