<?php
namespace Can\RestBundle\EventListener;
use Can\RestBundle\CanRestBundle;
use Can\RestBundle\Http\ResponseDigester;
use Can\RestBundle\Negotiation\NegotiationConfiguration;
use Can\RestBundle\Negotiation\NegotiationHeader;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
/**
* Computes and adds the response Digest header, if necessary.
*
* @group negotiation
*
* @package can/rest-bundle
* @author lechecacharro <lechecacharro@gmail.com>
*/
class DigestHeaderListener
{
/**
* @var NegotiationConfiguration
*/
private $configuration;
/**
* ContentHeadersListener constructor.
*
* @param NegotiationConfiguration $configuration
*/
public function __construct(NegotiationConfiguration $configuration)
{
$this->configuration = $configuration;
}
/**
* @param ResponseEvent $event
*/
public function onResponse(ResponseEvent $event): void
{
if (! $this->configuration->isAcceptInstanceDigests()) {
return;
}
if (! $event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
if (! $request->attributes->get(CanRestBundle::ATTR_SERVICE_ZONE)) {
return;
}
$digest = $request->attributes->get(CanRestBundle::ATTR_NEGOTIATION_DIGEST);
if (! $digest) {
return;
}
$response = $event->getResponse();
// Don't add content headers to empty responses
if ($response->isEmpty() || empty($response->getContent())) {
return;
}
$response->headers->set(NegotiationHeader::DIGEST, $this->computeDigest($digest, $response));
}
/**
* Computes the response entity digest.
*
* @param string $digest
* @param Response $response
*
* @return string
*/
protected function computeDigest(string $digest, Response $response): string
{
$responseDigester = new ResponseDigester($digest);
return sprintf('%s=%s', $digest, $responseDigester->entityDigest($response));
}
}