Http.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /**
  3. * HTTP response
  4. *
  5. * Copyright © Magento, Inc. All rights reserved.
  6. * See COPYING.txt for license details.
  7. */
  8. namespace Magento\Framework\App\Response;
  9. use Magento\Framework\App\Http\Context;
  10. use Magento\Framework\App\ObjectManager;
  11. use Magento\Framework\Stdlib\Cookie\CookieMetadata;
  12. use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory;
  13. use Magento\Framework\Stdlib\CookieManagerInterface;
  14. use Magento\Framework\Stdlib\DateTime;
  15. use Magento\Framework\App\Request\Http as HttpRequest;
  16. use Magento\Framework\Session\Config\ConfigInterface;
  17. class Http extends \Magento\Framework\HTTP\PhpEnvironment\Response
  18. {
  19. /** Cookie to store page vary string */
  20. const COOKIE_VARY_STRING = 'X-Magento-Vary';
  21. /** Format for expiration timestamp headers */
  22. const EXPIRATION_TIMESTAMP_FORMAT = 'D, d M Y H:i:s T';
  23. /** X-FRAME-OPTIONS Header name */
  24. const HEADER_X_FRAME_OPT = 'X-Frame-Options';
  25. /**
  26. * @var \Magento\Framework\App\Request\Http
  27. */
  28. protected $request;
  29. /**
  30. * @var \Magento\Framework\Stdlib\CookieManagerInterface
  31. */
  32. protected $cookieManager;
  33. /**
  34. * @var \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory
  35. */
  36. protected $cookieMetadataFactory;
  37. /**
  38. * @var \Magento\Framework\App\Http\Context
  39. */
  40. protected $context;
  41. /**
  42. * @var \Magento\Framework\Stdlib\DateTime
  43. */
  44. protected $dateTime;
  45. /**
  46. * @var \Magento\Framework\Session\Config\ConfigInterface
  47. */
  48. private $sessionConfig;
  49. /**
  50. * @param HttpRequest $request
  51. * @param CookieManagerInterface $cookieManager
  52. * @param CookieMetadataFactory $cookieMetadataFactory
  53. * @param Context $context
  54. * @param DateTime $dateTime
  55. * @param ConfigInterface|null $sessionConfig
  56. */
  57. public function __construct(
  58. HttpRequest $request,
  59. CookieManagerInterface $cookieManager,
  60. CookieMetadataFactory $cookieMetadataFactory,
  61. Context $context,
  62. DateTime $dateTime,
  63. ConfigInterface $sessionConfig = null
  64. ) {
  65. $this->request = $request;
  66. $this->cookieManager = $cookieManager;
  67. $this->cookieMetadataFactory = $cookieMetadataFactory;
  68. $this->context = $context;
  69. $this->dateTime = $dateTime;
  70. $this->sessionConfig = $sessionConfig ?: ObjectManager::getInstance()->get(ConfigInterface::class);
  71. }
  72. /**
  73. * Sends the X-FRAME-OPTIONS header to protect against click-jacking
  74. *
  75. * @param string $value
  76. * @return void
  77. */
  78. public function setXFrameOptions($value)
  79. {
  80. $this->setHeader(self::HEADER_X_FRAME_OPT, $value);
  81. }
  82. /**
  83. * Send Vary cookie
  84. *
  85. * @return void
  86. */
  87. public function sendVary()
  88. {
  89. $varyString = $this->context->getVaryString();
  90. if ($varyString) {
  91. $cookieLifeTime = $this->sessionConfig->getCookieLifetime();
  92. $sensitiveCookMetadata = $this->cookieMetadataFactory->createSensitiveCookieMetadata(
  93. [CookieMetadata::KEY_DURATION => $cookieLifeTime]
  94. )->setPath('/');
  95. $this->cookieManager->setSensitiveCookie(self::COOKIE_VARY_STRING, $varyString, $sensitiveCookMetadata);
  96. } elseif ($this->request->get(self::COOKIE_VARY_STRING)) {
  97. $cookieMetadata = $this->cookieMetadataFactory->createSensitiveCookieMetadata()->setPath('/');
  98. $this->cookieManager->deleteCookie(self::COOKIE_VARY_STRING, $cookieMetadata);
  99. }
  100. }
  101. /**
  102. * Set headers for public cache
  103. * Accepts the time-to-live (max-age) parameter
  104. *
  105. * @param int $ttl
  106. * @return void
  107. * @throws \InvalidArgumentException
  108. */
  109. public function setPublicHeaders($ttl)
  110. {
  111. if ($ttl < 0 || !preg_match('/^[0-9]+$/', $ttl)) {
  112. throw new \InvalidArgumentException('Time to live is a mandatory parameter for set public headers');
  113. }
  114. $this->setHeader('pragma', 'cache', true);
  115. $this->setHeader('cache-control', 'public, max-age=' . $ttl . ', s-maxage=' . $ttl, true);
  116. $this->setHeader('expires', $this->getExpirationHeader('+' . $ttl . ' seconds'), true);
  117. }
  118. /**
  119. * Set headers for private cache
  120. *
  121. * @param int $ttl
  122. * @return void
  123. * @throws \InvalidArgumentException
  124. */
  125. public function setPrivateHeaders($ttl)
  126. {
  127. if (!$ttl) {
  128. throw new \InvalidArgumentException('Time to live is a mandatory parameter for set private headers');
  129. }
  130. $this->setHeader('pragma', 'cache', true);
  131. $this->setHeader('cache-control', 'private, max-age=' . $ttl, true);
  132. $this->setHeader('expires', $this->getExpirationHeader('+' . $ttl . ' seconds'), true);
  133. }
  134. /**
  135. * Set headers for no-cache responses
  136. *
  137. * @return void
  138. * @codeCoverageIgnore
  139. */
  140. public function setNoCacheHeaders()
  141. {
  142. $this->setHeader('pragma', 'no-cache', true);
  143. $this->setHeader('cache-control', 'no-store, no-cache, must-revalidate, max-age=0', true);
  144. $this->setHeader('expires', $this->getExpirationHeader('-1 year'), true);
  145. }
  146. /**
  147. * Represents an HTTP response body in JSON format by sending appropriate header
  148. *
  149. * @param string $content String in JSON format
  150. * @return \Magento\Framework\App\Response\Http
  151. * @codeCoverageIgnore
  152. */
  153. public function representJson($content)
  154. {
  155. $this->setHeader('Content-Type', 'application/json', true);
  156. return $this->setContent($content);
  157. }
  158. /**
  159. * @return string[]
  160. * @codeCoverageIgnore
  161. */
  162. public function __sleep()
  163. {
  164. return ['content', 'isRedirect', 'statusCode', 'context', 'headers'];
  165. }
  166. /**
  167. * Need to reconstruct dependencies when being de-serialized.
  168. *
  169. * @return void
  170. * @codeCoverageIgnore
  171. */
  172. public function __wakeup()
  173. {
  174. $objectManager = ObjectManager::getInstance();
  175. $this->cookieManager = $objectManager->create(\Magento\Framework\Stdlib\CookieManagerInterface::class);
  176. $this->cookieMetadataFactory = $objectManager->get(
  177. \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory::class
  178. );
  179. $this->request = $objectManager->get(\Magento\Framework\App\Request\Http::class);
  180. }
  181. /**
  182. * Given a time input, returns the formatted header
  183. *
  184. * @param string $time
  185. * @return string
  186. * @codeCoverageIgnore
  187. */
  188. protected function getExpirationHeader($time)
  189. {
  190. return $this->dateTime->gmDate(self::EXPIRATION_TIMESTAMP_FORMAT, $this->dateTime->strToTime($time));
  191. }
  192. }