PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/sensio/framework-extra-bundle/EventListener/HttpCacheListener.php

https://gitlab.com/Isaki/le331.fr
PHP | 168 lines | 114 code | 32 blank | 22 comment | 21 complexity | a952dc2d84a747bf3f4f2e65b4f58955 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony framework.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener;
  11. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  12. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  13. use Symfony\Component\HttpKernel\KernelEvents;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
  17. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
  18. /**
  19. * HttpCacheListener handles HTTP cache headers.
  20. *
  21. * It can be configured via the Cache annotation.
  22. *
  23. * @author Fabien Potencier <fabien@symfony.com>
  24. */
  25. class HttpCacheListener implements EventSubscriberInterface
  26. {
  27. private $lastModifiedDates;
  28. private $etags;
  29. private $expressionLanguage;
  30. public function __construct()
  31. {
  32. $this->lastModifiedDates = new \SplObjectStorage();
  33. $this->etags = new \SplObjectStorage();
  34. }
  35. /**
  36. * Handles HTTP validation headers.
  37. */
  38. public function onKernelController(FilterControllerEvent $event)
  39. {
  40. $request = $event->getRequest();
  41. if (!$configuration = $request->attributes->get('_cache')) {
  42. return;
  43. }
  44. $response = new Response();
  45. $lastModifiedDate = '';
  46. if ($configuration->getLastModified()) {
  47. $lastModifiedDate = $this->getExpressionLanguage()->evaluate($configuration->getLastModified(), $request->attributes->all());
  48. $response->setLastModified($lastModifiedDate);
  49. }
  50. $etag = '';
  51. if ($configuration->getETag()) {
  52. $etag = hash('sha256', $this->getExpressionLanguage()->evaluate($configuration->getETag(), $request->attributes->all()));
  53. $response->setETag($etag);
  54. }
  55. if ($response->isNotModified($request)) {
  56. $event->setController(function () use ($response) {
  57. return $response;
  58. });
  59. } else {
  60. if ($etag) {
  61. $this->etags[$request] = $etag;
  62. }
  63. if ($lastModifiedDate) {
  64. $this->lastModifiedDates[$request] = $lastModifiedDate;
  65. }
  66. }
  67. }
  68. /**
  69. * Modifies the response to apply HTTP cache headers when needed.
  70. */
  71. public function onKernelResponse(FilterResponseEvent $event)
  72. {
  73. $request = $event->getRequest();
  74. if (!$configuration = $request->attributes->get('_cache')) {
  75. return;
  76. }
  77. $response = $event->getResponse();
  78. // http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-12#section-3.1
  79. if (!in_array($response->getStatusCode(), array(200, 203, 300, 301, 302, 304, 404, 410))) {
  80. return;
  81. }
  82. if (null !== $age = $configuration->getSMaxAge()) {
  83. if (!is_numeric($age)) {
  84. $now = microtime(true);
  85. $age = ceil(strtotime($configuration->getSMaxAge(), $now) - $now);
  86. }
  87. $response->setSharedMaxAge($age);
  88. }
  89. if (null !== $age = $configuration->getMaxAge()) {
  90. if (!is_numeric($age)) {
  91. $now = microtime(true);
  92. $age = ceil(strtotime($configuration->getMaxAge(), $now) - $now);
  93. }
  94. $response->setMaxAge($age);
  95. }
  96. if (null !== $configuration->getExpires()) {
  97. $date = \DateTime::createFromFormat('U', strtotime($configuration->getExpires()), new \DateTimeZone('UTC'));
  98. $response->setExpires($date);
  99. }
  100. if (null !== $configuration->getVary()) {
  101. $response->setVary($configuration->getVary());
  102. }
  103. if ($configuration->isPublic()) {
  104. $response->setPublic();
  105. }
  106. if ($configuration->isPrivate()) {
  107. $response->setPrivate();
  108. }
  109. if (isset($this->lastModifiedDates[$request])) {
  110. $response->setLastModified($this->lastModifiedDates[$request]);
  111. unset($this->lastModifiedDates[$request]);
  112. }
  113. if (isset($this->etags[$request])) {
  114. $response->setETag($this->etags[$request]);
  115. unset($this->etags[$request]);
  116. }
  117. $event->setResponse($response);
  118. }
  119. public static function getSubscribedEvents()
  120. {
  121. return array(
  122. KernelEvents::CONTROLLER => 'onKernelController',
  123. KernelEvents::RESPONSE => 'onKernelResponse',
  124. );
  125. }
  126. private function getExpressionLanguage()
  127. {
  128. if (null === $this->expressionLanguage) {
  129. if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
  130. throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
  131. }
  132. $this->expressionLanguage = new ExpressionLanguage();
  133. }
  134. return $this->expressionLanguage;
  135. }
  136. }