<?php
namespace Can\RestBundle\EventListener;
use Can\RestBundle\CanRestBundle;
use Can\RestBundle\Fetch\Fetch;
use Can\RestBundle\Fetch\FetchConfiguration;
use Can\RestBundle\Fetch\FetchHandlerInterface;
use Can\RestBundle\Fetch\FetchHeader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
/**
* Manages fetch headers.
*
* @group fetch
*
* @package can/rest-bundle
* @author lechecacharro <lechecacharro@gmail.com>
*/
class FetchListener
{
/**
* @var FetchConfiguration
*/
private $configuration;
/**
* @var FetchHandlerInterface
*/
private $handler;
/**
* FetchListener constructor.
*
* @param FetchConfiguration $configuration
* @param FetchHandlerInterface $handler
*/
public function __construct(FetchConfiguration $configuration, FetchHandlerInterface $handler)
{
$this->configuration = $configuration;
$this->handler = $handler;
}
/**
* @param RequestEvent $event
*/
public function onRequest(RequestEvent $event): void
{
if (! $this->configuration->isEnabled()) {
return;
}
$request = $event->getRequest();
if (! $request->attributes->get(CanRestBundle::ATTR_SERVICE_ZONE)) {
return;
}
$fetch = new Fetch(
$this->getRequestHeader($request, FetchHeader::SEC_FETCH_DEST),
$this->getRequestHeader($request, FetchHeader::SEC_FETCH_MODE),
$this->getRequestHeader($request, FetchHeader::SEC_FETCH_SITE),
strtolower($this->getRequestHeader($request, FetchHeader::SEC_FETCH_USER)) === 'true'
);
$request->attributes->set(CanRestBundle::ATTR_FETCH, $fetch);
if ($fetch->isEmpty()) {
return;
}
$fetchApproved = $this->handler->handle($request, $fetch);
if (! $fetchApproved) {
// Reject the request returning an error response, using
// the HTTP status code specified by the fetchErrorStatus
// configuration option (a client error)
$event->setResponse(new Response('', $this->configuration->getFetchErrorStatus()));
}
$request->attributes->set(CanRestBundle::ATTR_FETCH_APPROVED, $fetchApproved);
}
/**
* @param Request $request
* @param string $header
*
* @return string
*/
protected function getRequestHeader(Request $request, string $header): string
{
$value = $request->headers->get($header);
if (is_array($value)) {
$value = $value[0];
}
return strval($value);
}
}