/** * {@inheritdoc} */ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) { // Only allow page caching on master request. if ($type === static::MASTER_REQUEST && $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW) { $response = $this->lookup($request, $type, $catch); } else { $response = $this->pass($request, $type, $catch); } return $response; }
/** * Sets extra headers on successful responses. * * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event * The event to process. */ public function onRespond(FilterResponseEvent $event) { if (!$event->isMasterRequest()) { return; } $request = $event->getRequest(); $response = $event->getResponse(); // Set the X-UA-Compatible HTTP header to force IE to use the most recent // rendering engine. $response->headers->set('X-UA-Compatible', 'IE=edge', FALSE); // Set the Content-language header. $response->headers->set('Content-language', $this->languageManager->getCurrentLanguage()->getId()); // Prevent browsers from sniffing a response and picking a MIME type // different from the declared content-type, since that can lead to // XSS and other vulnerabilities. // https://www.owasp.org/index.php/List_of_useful_HTTP_headers $response->headers->set('X-Content-Type-Options', 'nosniff', FALSE); $response->headers->set('X-Frame-Options', 'SAMEORIGIN', FALSE); // If the current response isn't an implementation of the // CacheableResponseInterface, we assume that a Response is either // explicitly not cacheable or that caching headers are already set in // another place. if (!$response instanceof CacheableResponseInterface) { if (!$this->isCacheControlCustomized($response)) { $this->setResponseNotCacheable($response, $request); } // HTTP/1.0 proxies do not support the Vary header, so prevent any caching // by sending an Expires date in the past. HTTP/1.1 clients ignore the // Expires header if a Cache-Control: max-age directive is specified (see // RFC 2616, section 14.9.3). if (!$response->headers->has('Expires')) { $this->setExpiresNoCache($response); } return; } if ($this->debugCacheabilityHeaders) { // Expose the cache contexts and cache tags associated with this page in a // X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively. $response_cacheability = $response->getCacheableMetadata(); $response->headers->set('X-Drupal-Cache-Tags', implode(' ', $response_cacheability->getCacheTags())); $response->headers->set('X-Drupal-Cache-Contexts', implode(' ', $this->cacheContextsManager->optimizeTokens($response_cacheability->getCacheContexts()))); } $is_cacheable = $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW && $this->responsePolicy->check($response, $request) !== ResponsePolicyInterface::DENY; // Add headers necessary to specify whether the response should be cached by // proxies and/or the browser. if ($is_cacheable && $this->config->get('cache.page.max_age') > 0) { if (!$this->isCacheControlCustomized($response)) { // Only add the default Cache-Control header if the controller did not // specify one on the response. $this->setResponseCacheable($response, $request); } } else { // If either the policy forbids caching or the sites configuration does // not allow to add a max-age directive, then enforce a Cache-Control // header declaring the response as not cacheable. $this->setResponseNotCacheable($response, $request); } }
/** * Sets extra headers on successful responses. * * @param Symfony\Component\HttpKernel\Event\FilterResponseEvent $event * The event to process. */ public function onRespond(FilterResponseEvent $event) { if (!$event->isMasterRequest()) { return; } $request = $event->getRequest(); $response = $event->getResponse(); // Set the X-UA-Compatible HTTP header to force IE to use the most recent // rendering engine. $response->headers->set('X-UA-Compatible', 'IE=edge', FALSE); // Set the Content-language header. $response->headers->set('Content-language', $this->languageManager->getCurrentLanguage()->getId()); // Prevent browsers from sniffing a response and picking a MIME type // different from the declared content-type, since that can lead to // XSS and other vulnerabilities. // https://www.owasp.org/index.php/List_of_useful_HTTP_headers $response->headers->set('X-Content-Type-Options', 'nosniff', FALSE); // Attach globally-declared headers to the response object so that Symfony // can send them for us correctly. // @todo Remove this once drupal_process_attached() no longer calls // _drupal_add_http_header(), which has its own static. Instead, // _drupal_process_attached() should use // \Symfony\Component\HttpFoundation\Response->headers->set(), which is // already documented on the (deprecated) _drupal_process_attached() to // become the final, intended mechanism. $headers = drupal_get_http_header(); foreach ($headers as $name => $value) { // Symfony special-cases the 'Status' header. if ($name === 'status') { $response->setStatusCode($value); } $response->headers->set($name, $value, FALSE); } // Expose the cache contexts and cache tags associated with this page in a // X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively. if ($response instanceof CacheableResponseInterface) { $response_cacheability = $response->getCacheableMetadata(); $response->headers->set('X-Drupal-Cache-Tags', implode(' ', $response_cacheability->getCacheTags())); $response->headers->set('X-Drupal-Cache-Contexts', implode(' ', $this->cacheContextsManager->optimizeTokens($response_cacheability->getCacheContexts()))); } $is_cacheable = $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW && $this->responsePolicy->check($response, $request) !== ResponsePolicyInterface::DENY; // Add headers necessary to specify whether the response should be cached by // proxies and/or the browser. if ($is_cacheable && $this->config->get('cache.page.max_age') > 0) { if (!$this->isCacheControlCustomized($response)) { // Only add the default Cache-Control header if the controller did not // specify one on the response. $this->setResponseCacheable($response, $request); } } else { // If either the policy forbids caching or the sites configuration does // not allow to add a max-age directive, then enforce a Cache-Control // header declaring the response as not cacheable. $this->setResponseNotCacheable($response, $request); } }
/** * {@inheritdoc} */ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) { if ($type !== static::MASTER_REQUEST) { // Only allow page caching on master request. $cache_enabled = FALSE; } elseif (Settings::get('page_cache_without_database')) { // Check for a cache mode force from settings.php. $cache_enabled = TRUE; } else { $config = $this->config('system.performance'); $cache_enabled = $config->get('cache.page.use_internal'); } if ($cache_enabled && $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW) { $response = $this->lookup($request, $type, $catch); } else { $response = $this->pass($request, $type, $catch); } return $response; }
/** * Sets extra headers on successful responses. * * @param Symfony\Component\HttpKernel\Event\FilterResponseEvent $event * The event to process. */ public function onRespond(FilterResponseEvent $event) { if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) { return; } $request = $event->getRequest(); $response = $event->getResponse(); // Set the X-UA-Compatible HTTP header to force IE to use the most recent // rendering engine or use Chrome's frame rendering engine if available. $response->headers->set('X-UA-Compatible', 'IE=edge,chrome=1', FALSE); // Set the Content-language header. $response->headers->set('Content-language', $this->languageManager->getCurrentLanguage()->getId()); // Attach globally-declared headers to the response object so that Symfony // can send them for us correctly. // @todo Remove this once drupal_process_attached() no longer calls // _drupal_add_http_header(), which has its own static. Instead, // _drupal_process_attached() should use // \Symfony\Component\HttpFoundation\Response->headers->set(), which is // already documented on the (deprecated) _drupal_process_attached() to // become the final, intended mechanism. $headers = drupal_get_http_header(); foreach ($headers as $name => $value) { // Symfony special-cases the 'Status' header. if ($name === 'status') { $response->setStatusCode($value); } $response->headers->set($name, $value, FALSE); } $is_cacheable = $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW && $this->responsePolicy->check($response, $request) !== ResponsePolicyInterface::DENY; // Add headers necessary to specify whether the response should be cached by // proxies and/or the browser. if ($is_cacheable && $this->config->get('cache.page.max_age') > 0) { if (!$this->isCacheControlCustomized($response)) { // Only add the default Cache-Control header if the controller did not // specify one on the response. $this->setResponseCacheable($response, $request); } } else { // If either the policy forbids caching or the sites configuration does // not allow to add a max-age directive, then enforce a Cache-Control // header declaring the response as not cacheable. $this->setResponseNotCacheable($response, $request); } // Currently it is not possible to cache some types of responses. Therefore // exclude binary file responses (generated files, e.g. images with image // styles) and streamed responses (files directly read from the disk). // see: https://github.com/symfony/symfony/issues/9128#issuecomment-25088678 if ($is_cacheable && $this->config->get('cache.page.use_internal') && !$response instanceof BinaryFileResponse && !$response instanceof StreamedResponse) { // Store the response in the internal page cache. drupal_page_set_cache($response, $request); $response->headers->set('X-Drupal-Cache', 'MISS'); drupal_serve_page_from_cache($response, $request); } }
/** * Sets a response in case of a Dynamic Page Cache hit. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The event to process. */ public function onRouteMatch(GetResponseEvent $event) { // Don't cache the response if the Dynamic Page Cache request policies are // not met. Store the result in a request attribute, so that onResponse() // does not have to redo the request policy check. $request = $event->getRequest(); $request_policy_result = $this->requestPolicy->check($request); $this->requestPolicyResults[$request] = $request_policy_result; if ($request_policy_result === RequestPolicyInterface::DENY) { return; } // Sets the response for the current route, if cached. $cached = $this->renderCache->get($this->dynamicPageCacheRedirectRenderArray); if ($cached) { $response = $this->renderArrayToResponse($cached); $response->headers->set(self::HEADER, 'HIT'); $event->setResponse($response); } }
/** * Checks if the page is cacheable. * * @return bool * TRUE is the page is cacheable, FALSE if not. */ protected function isPageCacheable() { return $this->requestPolicy->check($this->requestStack->getCurrentRequest()) === RequestPolicyInterface::ALLOW; }