You are here

protected function PageCache::lookup 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::lookup()

Retrieves a response from the cache or fetches it from the backend.

@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

1 call to PageCache::lookup()
PageCache::handle in core/modules/page_cache/src/StackMiddleware/PageCache.php
Handles a Request to convert it to a Response.

File

core/modules/page_cache/src/StackMiddleware/PageCache.php, line 120
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 lookup(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
  if ($response = $this
    ->get($request)) {
    $response->headers
      ->set('X-Drupal-Cache', 'HIT');
  }
  else {
    $response = $this
      ->fetch($request, $type, $catch);
  }

  // Only allow caching in the browser and prevent that the response is stored
  // by an external proxy server when the following conditions apply:
  // 1. There is a session cookie on the request.
  // 2. The Vary: Cookie header is on the response.
  // 3. The Cache-Control header does not contain the no-cache directive.
  if ($request->cookies
    ->has(session_name()) && in_array('Cookie', $response
    ->getVary()) && !$response->headers
    ->hasCacheControlDirective('no-cache')) {
    $response
      ->setPrivate();
  }

  // Negotiate whether to use compression.
  if (extension_loaded('zlib') && $response->headers
    ->get('Content-Encoding') === 'gzip') {
    if (strpos($request->headers
      ->get('Accept-Encoding'), 'gzip') !== FALSE) {

      // The response content is already gzip'ed, so make sure
      // zlib.output_compression does not compress it once more.
      ini_set('zlib.output_compression', '0');
    }
    else {

      // The client does not support compression. Decompress the content and
      // remove the Content-Encoding header.
      $content = $response
        ->getContent();
      $content = gzinflate(substr(substr($content, 10), 0, -8));
      $response
        ->setContent($content);
      $response->headers
        ->remove('Content-Encoding');
    }
  }

  // Perform HTTP revalidation.
  // @todo Use Response::isNotModified() as
  //   per https://www.drupal.org/node/2259489.
  $last_modified = $response
    ->getLastModified();
  if ($last_modified) {

    // See if the client has provided the required HTTP headers.
    $if_modified_since = $request->server
      ->has('HTTP_IF_MODIFIED_SINCE') ? strtotime($request->server
      ->get('HTTP_IF_MODIFIED_SINCE')) : FALSE;
    $if_none_match = $request->server
      ->has('HTTP_IF_NONE_MATCH') ? stripslashes($request->server
      ->get('HTTP_IF_NONE_MATCH')) : FALSE;
    if ($if_modified_since && $if_none_match && $if_none_match == $response
      ->getEtag() && $if_modified_since == $last_modified
      ->getTimestamp()) {

      // if-modified-since must match
      $response
        ->setStatusCode(304);
      $response
        ->setContent(NULL);

      // In the case of a 304 response, certain headers must be sent, and the
      // remaining may not (see RFC 2616, section 10.3.5).
      foreach (array_keys($response->headers
        ->all()) as $name) {
        if (!in_array($name, array(
          'content-location',
          'expires',
          'cache-control',
          'vary',
        ))) {
          $response->headers
            ->remove($name);
        }
      }
    }
  }
  return $response;
}