summaryrefslogtreecommitdiff
path: root/includes/bootstrap.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/bootstrap.inc')
-rw-r--r--includes/bootstrap.inc70
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: