Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#10 Forward port external cache #23

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions includes/bootstrap.inc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ define('CACHE_PERMANENT', 0);
*/
define('CACHE_TEMPORARY', -1);

/**
* Indicates that page caching is disabled.
*/
define('CACHE_MODE_DISABLED', 0);

/**
* Indicates that page caching is enabled.
*/
define('CACHE_MODE_NORMAL', 1);

/**
* Indicates that page caching is using "external" mode. This disables the
* internal page cache but returns headers allowing downstream caches (such
* as Squid, Varnish, and other reverse proxies) to cache full pages.
*/
define('CACHE_MODE_EXTERNAL', 3);

/**
* @defgroup logging_severity_levels Logging severity levels
* @{
Expand Down Expand Up @@ -1295,10 +1312,17 @@ function drupal_page_header() {
}
$headers_sent = TRUE;

// If an external cache is being used and there isn't a session cookie allow
// the page to be cached.
$cache_control = 'no-cache, must-revalidate, post-check=0, pre-check=0';
if (!isset($_COOKIE[session_name()]) && variable_get('cache') == CACHE_MODE_EXTERNAL) {
$cache_control = 'public, max-age=' . variable_get('page_cache_maximum_age', 0);
}

$default_headers = array(
'Expires' => 'Sun, 19 Nov 1978 05:00:00 GMT',
'Expires' => 'Sun, 11 Mar 1984 12:00:00 GMT',
'Last-Modified' => gmdate(DATE_RFC1123, REQUEST_TIME),
'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
'Cache-Control' => $cache_control,
'ETag' => '"' . REQUEST_TIME . '"',
);
drupal_send_headers($default_headers);
Expand Down Expand Up @@ -1373,7 +1397,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
// by sending an Expires date in the past. HTTP/1.1 clients ignores the
// Expires header if a Cache-Control: max-age= directive is specified (see RFC
// 2616, section 14.9.3).
$default_headers['Expires'] = 'Sun, 19 Nov 1978 05:00:00 GMT';
$default_headers['Expires'] = 'Sun, 11 Mar 1984 12:00:00 GMT';

drupal_send_headers($default_headers);

Expand Down Expand Up @@ -2318,12 +2342,12 @@ function _drupal_bootstrap_page_cache() {
}
else {
drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE);
$cache_enabled = variable_get('cache');
$cache_enabled = variable_get('cache', CACHE_MODE_DISABLED);
}
drupal_block_denied(ip_address());
// If there is no session cookie and cache is enabled (or forced), try
// to serve a cached page.
if (!isset($_COOKIE[session_name()]) && $cache_enabled) {
if (!isset($_COOKIE[session_name()]) && $cache_enabled && $cache_enabled != CACHE_MODE_EXTERNAL) {
// Make sure there is a user object because its timestamp will be
// checked, hook_boot might check for anonymous user etc.
$user = drupal_anonymous_user();
Expand All @@ -2350,7 +2374,7 @@ function _drupal_bootstrap_page_cache() {
// We are done.
exit;
}
else {
elseif ($cache_enabled != CACHE_MODE_EXTERNAL) {
header('X-Drupal-Cache: MISS');
}
}
Expand Down
4 changes: 3 additions & 1 deletion includes/common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,9 @@ function drupal_page_footer() {
// Commit the user session, if needed.
drupal_session_commit();

if (variable_get('cache', 0) && ($cache = drupal_page_set_cache())) {
// Do not cache if cache is disabled or external.
$cache_mode = variable_get('cache', CACHE_MODE_DISABLED);
if (($cache_mode && $cache_mode != CACHE_MODE_EXTERNAL) && ($cache = drupal_page_set_cache())) {
drupal_serve_page_from_cache($cache);
}
else {
Expand Down
2 changes: 1 addition & 1 deletion includes/form.inc
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ function drupal_process_form($form_id, &$form, &$form_state) {
// We'll clear out the cached copies of the form and its stored data
// here, as we've finished with them. The in-memory copies are still
// here, though.
if (!variable_get('cache', 0) && !empty($form_state['values']['form_build_id'])) {
if (!variable_get('cache', CACHE_MODE_DISABLED) && !empty($form_state['values']['form_build_id'])) {
cache_clear_all('form_' . $form_state['values']['form_build_id'], 'cache_form');
cache_clear_all('form_state_' . $form_state['values']['form_build_id'], 'cache_form');
}
Expand Down
2 changes: 1 addition & 1 deletion includes/language.inc
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ function language_provider_invoke($provider_id, $provider = NULL) {

// If the language provider has no cache preference or this is satisfied
// we can execute the callback.
$cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', 0);
$cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', CACHE_MODE_DISABLED);
$callback = isset($provider['callbacks']['language']) ? $provider['callbacks']['language'] : FALSE;
$langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE;
$results[$provider_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
Expand Down
6 changes: 3 additions & 3 deletions modules/simpletest/tests/bootstrap.test
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,15 @@ class BootstrapPageCacheTestCase extends DrupalWebTestCase {
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', t('Page was not cached.'));
$this->assertEqual($this->drupalGetHeader('Vary'), 'Cookie,Accept-Encoding', t('Vary header was sent.'));
$this->assertEqual($this->drupalGetHeader('Cache-Control'), 'public, max-age=0', t('Cache-Control header was sent.'));
$this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', t('Expires header was sent.'));
$this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 11 Mar 1984 12:00:00 GMT', t('Expires header was sent.'));
$this->assertEqual($this->drupalGetHeader('Foo'), 'bar', t('Custom header was sent.'));

// Check cache.
$this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')));
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.'));
$this->assertEqual($this->drupalGetHeader('Vary'), 'Cookie,Accept-Encoding', t('Vary: Cookie header was sent.'));
$this->assertEqual($this->drupalGetHeader('Cache-Control'), 'public, max-age=0', t('Cache-Control header was sent.'));
$this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', t('Expires header was sent.'));
$this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 11 Mar 1984 12:00:00 GMT', t('Expires header was sent.'));
$this->assertEqual($this->drupalGetHeader('Foo'), 'bar', t('Custom header was sent.'));

// Check replacing default headers.
Expand All @@ -185,7 +185,7 @@ class BootstrapPageCacheTestCase extends DrupalWebTestCase {
$this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), t('Caching was bypassed.'));
$this->assertTrue(strpos($this->drupalGetHeader('Vary'), 'Cookie') === FALSE, t('Vary: Cookie header was not sent.'));
$this->assertEqual($this->drupalGetHeader('Cache-Control'), 'no-cache, must-revalidate, post-check=0, pre-check=0', t('Cache-Control header was sent.'));
$this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', t('Expires header was sent.'));
$this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 11 Mar 1984 12:00:00 GMT', t('Expires header was sent.'));
$this->assertEqual($this->drupalGetHeader('Foo'), 'bar', t('Custom header was sent.'));

}
Expand Down
29 changes: 26 additions & 3 deletions modules/system/system.admin.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1678,12 +1678,35 @@ function system_performance_settings() {
'#title' => t('Caching'),
);

$cache = variable_get('cache', 0);
$cache = variable_get('cache', CACHE_MODE_DISABLED);
$description = '<p>' . t('The normal cache mode is suitable for most sites and does not cause any side effects. The external cache mode allows Pressflow to set appropriate cache headers for use with an external caching system. Pages served from an external cache will skip the loading (boot) and unloading (exit) of enabled modules and may cause unwanted side effects.') . '</p>';

$problem_modules = array_unique(array_merge(module_implements('boot'), module_implements('exit')));
sort($problem_modules);

if (count($problem_modules) > 0) {
$description .= '<p>' . t('<strong class="error">The following enabled modules are potentially incompatible with and external-mode caching and may not function properly: %modules</strong>', array('%modules' => implode(', ', $problem_modules))) . '.</p>';
}
else {
$description .= '<p>' . t('<strong class="ok">Currently, all enabled modules are compatible with an external caching policy.</strong> Please note, if you use external caching and enable new modules, you will need to check this page again to ensure compatibility.') . '</p>';
}

$form['page_cache'] = array(
'#type' => 'fieldset',
'#title' => t('Page cache'),
'#description' => t('Enabling the page cache will offer a significant performance boost. Pressflow can store and send compressed cached pages requested by <em>anonymous</em> users. By caching a web page, Pressflow does not have to construct the page each time it is viewed.'),
);
$form['caching']['cache'] = array(
'#type' => 'checkbox',
'#title' => t('Cache pages for anonymous users'),
'#type' => 'radios',
'#title' => t('Caching mode'),
'#default_value' => $cache,
'#options' => array(
CACHE_MODE_DISABLED => t('Disabled'),
CACHE_MODE_NORMAL => t('Normal (reccomended for production sites, no side effects)'),
CACHE_MODE_EXTERNAL => t('External (experts only, possible side effects)'),
),
'#weight' => -2,
'#description' => $description,
);
$period = drupal_map_assoc(array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400), 'format_interval');
$period[0] = '<' . t('none') . '>';
Expand Down
4 changes: 2 additions & 2 deletions modules/system/system.install
Original file line number Diff line number Diff line change
Expand Up @@ -2128,8 +2128,8 @@ function system_update_7032() {
* Move CACHE_AGGRESSIVE to CACHE_NORMAL.
*/
function system_update_7033() {
if (variable_get('cache') == 2) {
variable_set('cache', 1);
if (variable_get('cache', CACHE_MODE_DISABLED) == 2) {
variable_set('cache', CACHE_MODE_NORMAL);
return t('Aggressive caching was disabled and replaced with normal caching. Read the page caching section in default.settings.php for more information on how to enable similar functionality.');
}
}
Expand Down