diff options
Diffstat (limited to 'includes/bootstrap.inc')
-rw-r--r-- | includes/bootstrap.inc | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 7eead8055..35a53b01d 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -671,23 +671,41 @@ function variable_del($name) { /** * Retrieve the current page from the cache. * - * Note: we do not serve cached pages when status messages are waiting (from - * a redirected form submission which was completed). + * Note: we do not serve cached pages to authenticated users, or to anonymous + * users when $_SESSION is non-empty. $_SESSION may contain status messages + * from a form submission, the contents of a shopping cart, or other user- + * specific content that should not be cached and displayed to other users. + * + * @param $retrieve + * If TRUE, look up and return the current page in the cache, or start output + * buffering if the conditions for caching are satisfied. If FALSE, only + * return a boolean value indicating whether the current request may be + * cached. + * @return + * The cache object, if the page was found in the cache; TRUE if the page was + * not found, but output buffering was started in order to possibly cache the + * current request; FALSE if the page was not found, and the current request + * may not be cached (e.g. because it belongs to an authenticated user). If + * $retrieve is TRUE, only return either TRUE or FALSE. */ -function page_get_cache() { +function page_get_cache($retrieve) { global $user, $base_root; + static $ob_started = FALSE; - $cache = NULL; - - if (!$user->uid && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && count(drupal_set_message()) == 0) { + if ($user->uid || ($_SERVER['REQUEST_METHOD'] != 'GET' && $_SERVER['REQUEST_METHOD'] != 'HEAD') || count(drupal_get_messages(NULL, FALSE))) { + return FALSE; + } + if ($retrieve) { $cache = cache_get($base_root . request_uri(), 'cache_page'); - - if (empty($cache)) { + if ($cache) { + return $cache; + } + else { ob_start(); + $ob_started = TRUE; } } - - return $cache; + return $ob_started; } /** @@ -956,7 +974,7 @@ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NO function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) { if ($message) { if (!isset($_SESSION['messages'])) { - $_SESSION['messages'] = array(); + drupal_set_session('messages', array()); } if (!isset($_SESSION['messages'][$type])) { @@ -1093,7 +1111,7 @@ function drupal_get_bootstrap_phase() { } function _drupal_bootstrap($phase) { - global $conf; + global $conf, $user; switch ($phase) { @@ -1139,7 +1157,16 @@ function _drupal_bootstrap($phase) { case DRUPAL_BOOTSTRAP_SESSION: require_once DRUPAL_ROOT . '/' . variable_get('session_inc', 'includes/session.inc'); session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy_sid', '_sess_gc'); - session_start(); + // If a session cookie exists, initialize the session. Otherwise the + // session is only started on demand in drupal_session_start(), making + // anonymous users not use a session cookie unless something is stored in + // $_SESSION. This allows HTTP proxies to cache anonymous pageviews. + if (isset($_COOKIE[session_name()])) { + drupal_session_start(); + } + else { + $user = drupal_anonymous_user(); + } break; case DRUPAL_BOOTSTRAP_VARIABLES: @@ -1150,15 +1177,19 @@ function _drupal_bootstrap($phase) { case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE: $cache_mode = variable_get('cache', CACHE_DISABLED); // Get the page from the cache. - $cache = $cache_mode == CACHE_DISABLED ? '' : page_get_cache(); + $cache = $cache_mode == CACHE_DISABLED ? FALSE : page_get_cache(TRUE); // If the skipping of the bootstrap hooks is not enforced, call hook_boot. - if (!$cache || $cache_mode != CACHE_AGGRESSIVE) { + if (!is_object($cache) || $cache_mode != CACHE_AGGRESSIVE) { // Load module handling. require_once DRUPAL_ROOT . '/includes/module.inc'; module_invoke_all('boot'); } // If there is a cached page, display it. - if ($cache) { + if (is_object($cache)) { + // Destroy empty anonymous sessions. + if (drupal_session_is_started() && empty($_SESSION)) { + session_destroy(); + } drupal_page_cache_header($cache); // If the skipping of the bootstrap hooks is not enforced, call hook_exit. if ($cache_mode != CACHE_AGGRESSIVE) { @@ -1169,6 +1200,13 @@ function _drupal_bootstrap($phase) { } // Prepare for non-cached page workflow. drupal_page_header(); + // If the session has not already been started and output buffering is + // not enabled, the session must be started now before the HTTP headers + // are sent. If output buffering is enabled, the session may be started + // at any time using drupal_session_start(). + if ($cache === FALSE) { + drupal_session_start(); + } break; case DRUPAL_BOOTSTRAP_LANGUAGE: |