<?php
namespace Can\RestBundle\EventListener;
use Can\RestBundle\CanRestBundle;
use Can\RestBundle\RateLimit\RateLimitConfiguration;
use Can\RestBundle\RateLimit\RateLimitHeader;
use Can\RestBundle\RateLimit\RateLimitInfo;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
/**
* Adds the rate limit headers to the response.
*
* @group ratelimit
*
* @package can/rest-bundle
* @author lechecacharro <lechecacharro@gmail.com>
*/
class RateLimitHeadersListener
{
/**
* @var RateLimitConfiguration
*/
private $configuration;
/**
* RateLimitHeadersListener constructor.
*
* @param RateLimitConfiguration $configuration
*/
public function __construct(RateLimitConfiguration $configuration)
{
$this->configuration = $configuration;
}
/**
* @param ResponseEvent $event
*/
public function onResponse(ResponseEvent $event): void
{
if (! $this->configuration->isEnabled()) {
return;
}
$request = $event->getRequest();
if (! $request->attributes->get(CanRestBundle::ATTR_SERVICE_ZONE)) {
return;
}
/** @var RateLimitInfo $rateLimitInfo */
$rateLimitInfo = $event->getRequest()->attributes->get(CanRestBundle::ATTR_RATE_LIMIT_INFO, null);
if (null === $rateLimitInfo) {
return;
}
$response = $event->getResponse();
$response->headers->set($this->configuration->getLimitHeader(), $rateLimitInfo->getLimit());
$response->headers->set($this->configuration->getRemainingHeader(), $rateLimitInfo->getRemaining());
$response->headers->set($this->configuration->getResetHeader(), $rateLimitInfo->getWindowResetTime());
$response->headers->set($this->configuration->getWindowHeader(), $rateLimitInfo->getWindowLength());
if ($this->configuration->isDebug()) {
$response->headers->set(RateLimitHeader::KEY,
$request->attributes->get(CanRestBundle::ATTR_RATE_LIMIT_KEY)
);
if (null !== CanRestBundle::ATTR_RATE_LIMIT_CONSTRAINT) {
$response->headers->set(RateLimitHeader::CONSTRAINT,
$request->attributes->get(CanRestBundle::ATTR_RATE_LIMIT_CONSTRAINT)
);
}
if (null !== CanRestBundle::ATTR_RATE_LIMIT_PLAN) {
$response->headers->set(RateLimitHeader::PLAN,
$request->attributes->get(CanRestBundle::ATTR_RATE_LIMIT_PLAN)
);
}
}
if ($rateLimitInfo->isRateLimitExceeded()) {
$response->headers->set('Connection', 'close');
}
}
}