You are here

protected function PageCache::fetch in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/page_cache/src/StackMiddleware/PageCache.php \Drupal\page_cache\StackMiddleware\PageCache::fetch()

Fetches a response from the backend and stores it in the cache.

If page_compression is enabled, a gzipped version of the page is stored in the cache to avoid compressing the output on each request. The cache entry is unzipped in the relatively rare event that the page is requested by a client without gzip support.

Page compression requires the PHP zlib extension (http://php.net/manual/ref.zlib.php).

@returns \Symfony\Component\HttpFoundation\Response $response A response object.

Parameters

\Symfony\Component\HttpFoundation\Request $request: A request object.

int $type: The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)

bool $catch: Whether to catch exceptions or not

See also

drupal_page_header()

1 call to PageCache::fetch()
PageCache::lookup in core/modules/page_cache/src/StackMiddleware/PageCache.php
Retrieves a response from the cache or fetches it from the backend.

File

core/modules/page_cache/src/StackMiddleware/PageCache.php, line 209
Contains \Drupal\page_cache\StackMiddleware\PageCache.

Class

PageCache
Executes the page caching before the main kernel takes over the request.

Namespace

Drupal\page_cache\StackMiddleware

Code

protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {

  /** @var \Symfony\Component\HttpFoundation\Response $response */
  $response = $this->httpKernel
    ->handle($request, $type, $catch);

  // Drupal's primary cache invalidation architecture is cache tags: any
  // response that varies by a configuration value or data in a content
  // entity should have cache tags, to allow for instant cache invalidation
  // when that data is updated. However, HTTP does not standardize how to
  // encode cache tags in a response. Different CDNs implement their own
  // approaches, and configurable reverse proxies (e.g., Varnish) allow for
  // custom implementations. To keep Drupal's internal page cache simple, we
  // only cache CacheableResponseInterface responses, since those provide a
  // defined API for retrieving cache tags. For responses that do not
  // implement CacheableResponseInterface, there's no easy way to distinguish
  // responses that truly don't depend on any site data from responses that
  // contain invalidation information customized to a particular proxy or
  // CDN.
  // - Drupal modules are encouraged to use CacheableResponseInterface
  //   responses where possible and to leave the encoding of that information
  //   into response headers to the corresponding proxy/CDN integration
  //   modules.
  // - Custom applications that wish to provide internal page cache support
  //   for responses that do not implement CacheableResponseInterface may do
  //   so by replacing/extending this middleware service or adding another
  //   one.
  if (!$response instanceof CacheableResponseInterface) {
    return $response;
  }

  // Currently it is not possible to cache binary file or streamed responses:
  // https://github.com/symfony/symfony/issues/9128#issuecomment-25088678.
  // Therefore exclude them, even for subclasses that implement
  // CacheableResponseInterface.
  if ($response instanceof BinaryFileResponse || $response instanceof StreamedResponse) {
    return $response;
  }

  // Allow policy rules to further restrict which responses to cache.
  if ($this->responsePolicy
    ->check($response, $request) === ResponsePolicyInterface::DENY) {
    return $response;
  }

  // The response passes all of the above checks, so cache it.
  // - Get the tags from CacheableResponseInterface per the earlier comments.
  // - Get the time expiration from the Expires header, rather than the
  //   interface, but see https://www.drupal.org/node/2352009 about possibly
  //   changing that.
  $tags = $response
    ->getCacheableMetadata()
    ->getCacheTags();
  $date = $response
    ->getExpires()
    ->getTimestamp();
  $expire = $date > time() ? $date : Cache::PERMANENT;
  $this
    ->set($request, $response, $expire, $tags);

  // Mark response as a cache miss.
  $response->headers
    ->set('X-Drupal-Cache', 'MISS');
  return $response;
}