You are here

function drupal_page_header in Drupal 4

Same name and namespace in other branches
  1. 5 includes/bootstrap.inc \drupal_page_header()
  2. 6 includes/bootstrap.inc \drupal_page_header()
  3. 7 includes/bootstrap.inc \drupal_page_header()

Set HTTP headers in preparation for a page response.

The general approach here is that anonymous users can keep a local cache of the page, but must revalidate it on every request. Then, they are given a '304 Not Modified' response as long as they stay logged out and the page has not been modified. This prevents authenticated users seeing locally cached pages that show them as logged out. Authenticated users are always given a 'no-cache' header set, and will fetch a fresh page on every request.

See also

page_set_cache

1 call to drupal_page_header()
_drupal_bootstrap in includes/bootstrap.inc

File

includes/bootstrap.inc, line 515
Functions that need to be loaded on every Drupal request.

Code

function drupal_page_header() {
  if (variable_get('cache', 0) && ($cache = page_get_cache())) {
    bootstrap_invoke_all('init');

    // Set default values:
    $date = gmdate('D, d M Y H:i:s', $cache->created) . ' GMT';
    $etag = '"' . md5($date) . '"';

    // Check http headers:
    $modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $date : NULL;
    if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($timestamp = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) > 0) {
      $modified_since = $cache->created <= $timestamp;
    }
    else {
      $modified_since = NULL;
    }
    $none_match = !empty($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] == $etag : NULL;

    // The type checking here is very important, be careful when changing entries.
    if (($modified_since !== NULL || $none_match !== NULL) && $modified_since !== false && $none_match !== false) {
      header('HTTP/1.0 304 Not Modified');
      exit;
    }

    // Send appropriate response:
    header("Last-Modified: {$date}");
    header("ETag: {$etag}");

    // The following headers force validation of cache
    header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
    header("Cache-Control: must-revalidate");

    // Determine if the browser accepts gzipped data.
    if (@strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === false && function_exists('gzencode')) {

      // Strip the gzip header and run uncompress.
      $cache->data = gzinflate(substr(substr($cache->data, 10), 0, -8));
    }
    elseif (function_exists('gzencode')) {
      header('Content-Encoding: gzip');
    }

    // Send the original request's headers.  We send them one after
    // another so PHP's header() function can deal with duplicate
    // headers.
    $headers = explode("\n", $cache->headers);
    foreach ($headers as $header) {
      header($header);
    }
    print $cache->data;
    bootstrap_invoke_all('exit');
    exit;
  }
  else {
    header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
  }
}