public function FinishResponseSubscriber::onRespond

Sets extra headers on successful responses.

Parameters

Symfony\Component\HttpKernel\Event\FilterResponseEvent $event: The event to process.

File

drupal/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php, line 45
Definition of Drupal\Core\EventSubscriber\FinishResponseSubscriber.

Class

FinishResponseSubscriber
Response subscriber to handle finished responses.

Namespace

Drupal\Core\EventSubscriber

Code

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
    ->getLanguage(Language::TYPE_INTERFACE)->langcode);

  // Because pages are highly dynamic, set the last-modified time to now
  // since the page is in fact being regenerated right now.
  // @todo Remove this and use a more intelligent default so that HTTP
  // caching can function properly.
  $response
    ->setLastModified(new \DateTime(gmdate(DATE_RFC1123, REQUEST_TIME)));

  // Also give each page a unique ETag. This will force clients to include
  // both an If-Modified-Since header and an If-None-Match header when doing
  // conditional requests for the page (required by RFC 2616, section 13.3.4),
  // making the validation more robust. This is a workaround for a bug in
  // Mozilla Firefox that is triggered when Drupal's caching is enabled and
  // the user accesses Drupal via an HTTP proxy (see
  // https://bugzilla.mozilla.org/show_bug.cgi?id=269303): When an
  // authenticated user requests a page, and then logs out and requests the
  // same page again, Firefox may send a conditional request based on the
  // page that was cached locally when the user was logged in. If this page
  // did not have an ETag header, the request only contains an
  // If-Modified-Since header. The date will be recent, because with
  // authenticated users the Last-Modified header always refers to the time
  // of the request. If the user accesses Drupal via a proxy server, and the
  // proxy already has a cached copy of the anonymous page with an older
  // Last-Modified date, the proxy may respond with 304 Not Modified, making
  // the client think that the anonymous and authenticated pageviews are
  // identical.
  // @todo Remove this line as no longer necessary per
  //   http://drupal.org/node/1573064
  $response
    ->setEtag(REQUEST_TIME);

  // Authenticated users are always given a 'no-cache' header, and will fetch
  // a fresh page on every request. This prevents authenticated users from
  // seeing locally cached pages.
  // @todo Revisit whether or not this is still appropriate now that the
  //   Response object does its own cache control processing and we intend to
  //   use partial page caching more extensively.
  // Commit the user session, if needed.
  drupal_session_commit();

  // Attach globally-declared headers to the response object so that Symfony
  // can send them for us correctly.
  // @todo remove this once we have removed all drupal_add_http_header() calls
  $headers = drupal_get_http_header();
  foreach ($headers as $name => $value) {
    $response->headers
      ->set($name, $value, FALSE);
  }
  $max_age = config('system.performance')
    ->get('cache.page.max_age');
  if ($max_age > 0 && ($cache = drupal_page_set_cache($response, $request))) {
    drupal_serve_page_from_cache($cache, $response, $request);
  }
  else {
    $response
      ->setExpires(\DateTime::createFromFormat('j-M-Y H:i:s T', '19-Nov-1978 05:00:00 GMT'));
    $response->headers
      ->set('Cache-Control', 'no-cache, must-revalidate, post-check=0, pre-check=0');
  }
}