<?php
/**
* @license SILK SOFTWARE HOUSE SP Z O O
*/
namespace App\EventSubscriber;
use App\Decoder\Interfaces\DecoderInterface;
use App\Entity\DeviceCommand;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Class ResponseEncryptingSubscriber.
*/
class ResponseEncryptingSubscriber implements EventSubscriberInterface
{
const MAX_BUFFER_SIZE = 400;
/**
* Decoder.
*
* @var DecoderInterface
*/
private $decoder;
/**
* Device ping path.
*
* @var string[]
*/
private $encryptedPaths;
/**
* ResponseEncryptingSubscriber constructor.
*
* @param DecoderInterface $decoder
* @param string[] $encryptedPaths Array of encrypted paths.
*/
public function __construct(DecoderInterface $decoder, array $encryptedPaths)
{
$this->decoder = $decoder;
$this->encryptedPaths = $encryptedPaths;
}
/**
* Get subscribed events.
*
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => [
['onKernelResponse', -9999],
],
];
}
/**
* On kernel response.
*
* @param ResponseEvent $event
*
* @throws AccessDeniedHttpException
*/
public function onKernelResponse(ResponseEvent $event)
{
if (!$event->isMasterRequest() || !in_array($event->getRequest()->getPathInfo(), $this->encryptedPaths)) {
return;
}
$serial = $event->getResponse()->headers->get('serial');
if ($serial) {
$event->getResponse()->headers->remove('serial');
}
$encrypted = $this->decoder->encrypt($event->getResponse()->getContent(), $serial);
$response = $event->getResponse();
$response->setContent($encrypted);
$response->headers->remove('Content-Type');
$response->headers->add(['Content-Type' => 'text/plain']);
if (strlen($encrypted) > self::MAX_BUFFER_SIZE) {
$response->setStatusCode(Response::HTTP_REQUEST_ENTITY_TOO_LARGE);
$contentWhereSizeFailed = json_encode(['cmd' => DeviceCommand::NO_COMMAND]);
$response->setContent($this->decoder->encrypt($contentWhereSizeFailed, $serial));
}
$event->setResponse($response);
}
}