summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2009-08-16 18:39:45 +0000
committerDries Buytaert <dries@buytaert.net>2009-08-16 18:39:45 +0000
commita1593ab1c90a9433f6e9b4ae0eab8f3ccdaab40d (patch)
tree03581d6f78d77ab6e47f858f2e3aa2c510ecb236
parent46b9fe93b526546c55eee438220b5aa30795ec2d (diff)
downloadbrdo-a1593ab1c90a9433f6e9b4ae0eab8f3ccdaab40d.tar.gz
brdo-a1593ab1c90a9433f6e9b4ae0eab8f3ccdaab40d.tar.bz2
- Patch #370454 by chx, Damien Tournoud: simplify page caching.
-rw-r--r--includes/bootstrap.inc164
-rw-r--r--modules/simpletest/tests/bootstrap.test8
-rw-r--r--modules/system/system.admin.inc15
-rw-r--r--modules/system/system.install11
4 files changed, 97 insertions, 101 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 7164c40f5..ab7659c4c 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -28,13 +28,6 @@ define('CACHE_DISABLED', 0);
define('CACHE_NORMAL', 1);
/**
- * Indicates that page caching is using "aggressive" mode. This bypasses
- * loading any modules for additional speed, which may break functionality in
- * modules that expect to be run on each page load.
- */
-define('CACHE_AGGRESSIVE', 2);
-
-/**
* Log message severity -- Emergency: system is unusable.
*
* @see watchdog()
@@ -104,10 +97,9 @@ define('WATCHDOG_DEBUG', 7);
define('DRUPAL_BOOTSTRAP_CONFIGURATION', 0);
/**
- * Second bootstrap phase: try to call a non-database cache
- * fetch routine.
+ * Second bootstrap phase: try to serve a cached page.
*/
-define('DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE', 1);
+define('DRUPAL_BOOTSTRAP_PAGE_CACHE', 1);
/**
* Third bootstrap phase: initialize database layer.
@@ -120,20 +112,19 @@ define('DRUPAL_BOOTSTRAP_DATABASE', 2);
define('DRUPAL_BOOTSTRAP_ACCESS', 3);
/**
- * Fifth bootstrap phase: initialize session handling.
+ * Fifth bootstrap phase: initialize the variable system.
*/
-define('DRUPAL_BOOTSTRAP_SESSION', 4);
+define('DRUPAL_BOOTSTRAP_VARIABLES', 4);
/**
- * Sixth bootstrap phase: initialize the variable system.
+ * Sixth bootstrap phase: initialize session handling.
*/
-define('DRUPAL_BOOTSTRAP_VARIABLES', 5);
+define('DRUPAL_BOOTSTRAP_SESSION', 5);
/**
- * Seventh bootstrap phase: load bootstrap.inc and module.inc, start
- * the variable system and try to serve a page from the cache.
+ * Seventh bootstrap phase: set up the page header.
*/
-define('DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE', 6);
+define('DRUPAL_BOOTSTRAP_PAGE_HEADER', 6);
/**
* Eighth bootstrap phase: find out language of the page.
@@ -141,7 +132,7 @@ define('DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE', 6);
define('DRUPAL_BOOTSTRAP_LANGUAGE', 7);
/**
- * Nineth bootstrap phase: set $_GET['q'] to Drupal path of request.
+ * Ninth bootstrap phase: set $_GET['q'] to Drupal path of request.
*/
define('DRUPAL_BOOTSTRAP_PATH', 8);
@@ -1017,11 +1008,11 @@ function drupal_serve_page_from_cache(stdClass $cache) {
// If a cache is served from a HTTP proxy without hitting the web server,
// the boot and exit hooks cannot be fired, so only allow caching in
- // proxies with aggressive caching. If the client send a session cookie, do
- // not bother caching the page in a public proxy, because the cached copy
+ // proxies if boot hooks are disabled. If the client send a session cookie,
+ // do not bother caching the page in a public proxy, because the cached copy
// will only be served to that particular user due to Vary: Cookie, unless
// the Vary header has been replaced or unset in hook_boot() (see below).
- $max_age = variable_get('cache') == CACHE_AGGRESSIVE && (!isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary'])) ? variable_get('cache_lifetime', 0) : 0;
+ $max_age = !variable_get('page_cache_invoke_hooks', TRUE) && (!isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary'])) ? variable_get('cache_lifetime', 0) : 0;
$default_headers['Cache-Control'] = 'public, max-age=' . $max_age;
// Entity tag should change if the output changes.
@@ -1304,7 +1295,7 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
* to avoid querying the database at this critical stage of the bootstrap if
* an administrative interface for IP address blocking is not required.
*
- * @param $ip string
+ * @param $ip
* IP address to check.
* @return bool
* TRUE if access is denied, FALSE if access is allowed.
@@ -1314,11 +1305,29 @@ function drupal_is_denied($ip) {
// for an array of IP addresses in settings.php before querying the
// database.
$blocked_ips = variable_get('blocked_ips');
+ $denied = FALSE;
if (isset($blocked_ips) && is_array($blocked_ips)) {
- return in_array($ip, $blocked_ips);
+ $denied = in_array($ip, $blocked_ips);
}
- else {
- return (bool)db_query("SELECT 1 FROM {blocked_ips} WHERE ip = :ip", array(':ip' => $ip))->fetchField();
+ // Only check if database.inc is loaded already.
+ elseif (function_exists('db_is_active')) {
+ $denied = (bool)db_query("SELECT 1 FROM {blocked_ips} WHERE ip = :ip", array(':ip' => $ip))->fetchField();
+ }
+ return $denied;
+}
+
+/**
+ * Handle denied users.
+ *
+ * @param $ip
+ * IP address to check. Prints a message and exits if access is denied.
+ */
+function drupal_handle_denied($ip) {
+ // Deny access to blocked IP addresses - t() is not yet available.
+ if (drupal_is_denied($ip)) {
+ header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
+ print 'Sorry, ' . check_plain(ip_address()) . ' has been banned.';
+ exit();
}
}
@@ -1358,16 +1367,22 @@ function drupal_anonymous_user($session = '') {
* DRUPAL_BOOTSTRAP_LANGUAGE: identify the language used on the page.
* DRUPAL_BOOTSTRAP_PATH: set $_GET['q'] to Drupal path of request.
* DRUPAL_BOOTSTRAP_FULL: Drupal is fully loaded, validate and fix input data.
+ * @param $new_phase
+ * A boolean, set to FALSE if calling drupal_bootstrap from inside a
+ * function called from drupal_bootstrap (recursion).
*/
-function drupal_bootstrap($phase = NULL) {
+function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
+ $final_phase = &drupal_static(__FUNCTION__ . '_final_phase');
+ if ($new_phase) {
+ $final_phase = $phase;
+ }
$phases = &drupal_static(__FUNCTION__ . '_phases', array(
DRUPAL_BOOTSTRAP_CONFIGURATION,
- DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE,
+ DRUPAL_BOOTSTRAP_PAGE_CACHE,
DRUPAL_BOOTSTRAP_DATABASE,
- DRUPAL_BOOTSTRAP_ACCESS,
- DRUPAL_BOOTSTRAP_SESSION,
DRUPAL_BOOTSTRAP_VARIABLES,
- DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE,
+ DRUPAL_BOOTSTRAP_SESSION,
+ DRUPAL_BOOTSTRAP_PAGE_HEADER,
DRUPAL_BOOTSTRAP_LANGUAGE,
DRUPAL_BOOTSTRAP_PATH,
DRUPAL_BOOTSTRAP_FULL,
@@ -1375,10 +1390,14 @@ function drupal_bootstrap($phase = NULL) {
$completed_phase = &drupal_static(__FUNCTION__ . '_completed_phase', -1);
if (isset($phase)) {
- while ($phases && $phase > $completed_phase) {
+ while ($phases && $phase > $completed_phase && $final_phase > $completed_phase) {
$current_phase = array_shift($phases);
_drupal_bootstrap($current_phase);
- $completed_phase = $current_phase;
+ // This function is reentrant. Only update the completed phase when the
+ // current call actually resulted in a progress in the bootstrap process.
+ if ($current_phase > $completed_phase) {
+ $completed_phase = $current_phase;
+ }
}
}
return $completed_phase;
@@ -1397,6 +1416,7 @@ function drupal_get_bootstrap_phase() {
function _drupal_bootstrap($phase) {
global $conf, $user;
+ static $cache;
switch ($phase) {
@@ -1408,16 +1428,34 @@ function _drupal_bootstrap($phase) {
drupal_settings_initialize();
break;
- case DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE:
+ case DRUPAL_BOOTSTRAP_PAGE_CACHE:
// Allow specifying special cache handlers in settings.php, like
// using memcached or files for storing cache information.
require_once DRUPAL_ROOT . '/' . variable_get('cache_inc', 'includes/cache.inc');
- // If the page_cache_fastpath is set to TRUE in settings.php and
- // page_cache_fastpath (implemented in the special implementation of
- // cache.inc) printed the page and indicated this with a returned TRUE
- // then we are done.
- if (variable_get('page_cache_fastpath', FALSE) && page_cache_fastpath()) {
- exit;
+ // Check for a cache mode force from settings.php.
+ if (variable_get('page_cache_without_database')) {
+ $cache_mode = CACHE_NORMAL;
+ }
+ else {
+ drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE);
+ $cache_mode = variable_get('cache');
+ }
+ drupal_handle_denied(ip_address());
+ if (!isset($_COOKIE[session_name()]) && $cache_mode == CACHE_NORMAL) {
+ $user = drupal_anonymous_user();
+ $cache = drupal_page_get_cache();
+ if (is_object($cache)) {
+ if (variable_get('page_cache_invoke_hooks', TRUE)) {
+ require_once DRUPAL_ROOT . '/includes/module.inc';
+ module_invoke_all('boot');
+ }
+ header('X-Drupal-Cache: HIT');
+ drupal_serve_page_from_cache($cache);
+ if (variable_get('page_cache_invoke_hooks', TRUE)) {
+ module_invoke_all('exit');
+ }
+ exit;
+ }
}
break;
@@ -1437,13 +1475,9 @@ function _drupal_bootstrap($phase) {
spl_autoload_register('drupal_autoload_interface');
break;
- case DRUPAL_BOOTSTRAP_ACCESS:
- // Deny access to blocked IP addresses - t() is not yet available.
- if (drupal_is_denied(ip_address())) {
- header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
- print 'Sorry, ' . check_plain(ip_address()) . ' has been banned.';
- exit();
- }
+ case DRUPAL_BOOTSTRAP_VARIABLES:
+ // Load variables from the database, but do not overwrite variables set in settings.php.
+ $conf = variable_initialize(isset($conf) ? $conf : array());
break;
case DRUPAL_BOOTSTRAP_SESSION:
@@ -1451,41 +1485,9 @@ function _drupal_bootstrap($phase) {
drupal_session_initialize();
break;
- case DRUPAL_BOOTSTRAP_VARIABLES:
- // Load variables from the database, but do not overwrite variables set in settings.php.
- $conf = variable_initialize(isset($conf) ? $conf : array());
- break;
-
- case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE:
- $cache_mode = variable_get('cache', CACHE_DISABLED);
-
- // Get the page from the cache.
- if ($cache_mode != CACHE_DISABLED) {
- $cache = drupal_page_get_cache();
- }
- else {
- $cache = FALSE;
- }
-
- // If the skipping of the bootstrap hooks is not enforced, call hook_boot.
- if (!$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) {
- header('X-Drupal-Cache: HIT');
- drupal_serve_page_from_cache($cache);
- // If the skipping of the bootstrap hooks is not enforced, call hook_exit.
- if ($cache_mode != CACHE_AGGRESSIVE) {
- module_invoke_all('exit');
- }
- // We are done.
- exit;
- }
-
+ case DRUPAL_BOOTSTRAP_PAGE_HEADER:
+ require_once DRUPAL_ROOT . '/includes/module.inc';
+ module_invoke_all('boot');
if (!$cache && drupal_page_is_cacheable()) {
header('X-Drupal-Cache: MISS');
}
diff --git a/modules/simpletest/tests/bootstrap.test b/modules/simpletest/tests/bootstrap.test
index 14741e690..ed7faad9e 100644
--- a/modules/simpletest/tests/bootstrap.test
+++ b/modules/simpletest/tests/bootstrap.test
@@ -261,16 +261,14 @@ class HookBootExitTestCase extends DrupalWebTestCase {
$this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_boot'))->fetchField(), $calls, t('hook_boot called with normal cache.'));
$this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_exit'))->fetchField(), $calls, t('hook_exit called with normal cache.'));
- // Test with aggressive cache. Boot and exit should not fire since the
- // page is cached.
- variable_set('cache', CACHE_AGGRESSIVE);
+ // Boot and exit should not fire since the page is cached.
+ variable_set('page_cache_invoke_hooks', FALSE);
$this->assertTrue(cache_get(url('', array('absolute' => TRUE)), 'cache_page'), t('Page has been cached.'));
$this->drupalGet('');
$this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_boot'))->fetchField(), $calls, t('hook_boot not called with agressive cache and a cached page.'));
$this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_exit'))->fetchField(), $calls, t('hook_exit not called with agressive cache and a cached page.'));
- // Test with aggressive cache and page cache cleared. Boot and exit should
- // be called.
+ // Test with page cache cleared, boot and exit should be called.
$this->assertTrue(db_delete('cache_page')->execute(), t('Page cache cleared.'));
$this->drupalGet('');
$calls++;
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index cf2270937..84de67946 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -1363,21 +1363,6 @@ function system_performance_settings() {
);
$cache = variable_get('cache', CACHE_DISABLED);
- $js_hide = $cache != CACHE_AGGRESSIVE ? 'js-hide' : '';
- $problem_modules = array_unique(array_merge(module_implements('boot'), module_implements('exit')));
- if (count($problem_modules) > 0) {
- $module_names = array();
- foreach ($problem_modules as $module) {
- $info = drupal_parse_info_file(drupal_get_path('module', $module) . "/$module.info");
- $module_names[] = $info['name'];
- }
- sort($module_names);
- $message = format_plural(count($module_names), '%module may cause issues when using aggressive caching.', '%modules may cause issues when using aggressive caching.', array('%module' => $module_names[0], '%modules' => implode(', ', $module_names)));
- $description = ' <strong id="cache-error" class="error ' . $js_hide . '">' . $message . '</strong>';
- }
- else {
- $description = ' <strong class="' . $js_hide . '">' . t('Note: if you use aggressive page caching and enable new modules, you will need to check this setting again to ensure compatibility.') . '</strong>';
- }
$form['caching']['cache'] = array(
'#type' => 'radios',
'#title' => t('Page cache for anonymous users'),
diff --git a/modules/system/system.install b/modules/system/system.install
index 784f09776..16d7c6b73 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -2243,6 +2243,17 @@ function system_update_7032() {
}
/**
+ * Move CACHE_AGGRESSIVE to CACHE_NORMAL.
+ */
+function system_update_7033() {
+ if (variable_get('cache') == 2) {
+ variable_set('cache', CACHE_NORMAL);
+ $ret[] = array('success' => TRUE, 'query' => "Aggressive caching was disabled and replaced with normal caching, please read the page caching section in default.settings.php for more information on how to enable similar functionality.");
+ }
+ return array();
+}
+
+/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.
*/