From 8f2323909aa1740a3d689568d369a583c6c54f70 Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Sun, 19 Aug 2012 01:28:27 -0500 Subject: [PATCH 1/7] Set cache headers when using external cache. --- includes/bootstrap.inc | 55 ++++++++++++++++++++++++++++++------------ includes/common.inc | 4 ++- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 2d97c4bcb26..428f3936a44 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -37,6 +37,13 @@ define('CACHE_PERMANENT', 0); */ define('CACHE_TEMPORARY', -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_EXTERNAL', 3); + /** * @defgroup logging_severity_levels Logging severity levels * @{ @@ -1315,7 +1322,7 @@ function drupal_page_header() { * and the conditions match those currently in the cache, a 304 Not Modified * response is sent. */ -function drupal_serve_page_from_cache(stdClass $cache) { +function drupal_page_cache_headers(stdClass $cache = NULL) { // Negotiate whether to use compression. $page_compression = variable_get('page_compression', TRUE) && extension_loaded('zlib'); $return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE; @@ -1327,14 +1334,16 @@ function drupal_serve_page_from_cache(stdClass $cache) { // drupal_add_http_headers(). Keys are mixed-case. $default_headers = array(); - foreach ($cache->data['headers'] as $name => $value) { - // In the case of a 304 response, certain headers must be sent, and the - // remaining may not (see RFC 2616, section 10.3.5). Do not override - // headers set in hook_boot(). - $name_lower = strtolower($name); - if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) { - drupal_add_http_header($name, $value); - unset($cache->data['headers'][$name]); + if ($cache) { + foreach ($cache->data['headers'] as $name => $value) { + // In the case of a 304 response, certain headers must be sent, and the + // remaining may not (see RFC 2616, section 10.3.5). Do not override + // headers set in hook_boot(). + $name_lower = strtolower($name); + if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) { + drupal_add_http_header($name, $value); + unset($cache->data['headers'][$name]); + } } } @@ -1346,9 +1355,12 @@ function drupal_serve_page_from_cache(stdClass $cache) { $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? variable_get('page_cache_maximum_age', 0) : 0; $default_headers['Cache-Control'] = 'public, max-age=' . $max_age; - // Entity tag should change if the output changes. - $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"'; - header('Etag: ' . $etag); + $etag = FALSE; + if ($cache) { + // Entity tag should change if the output changes. + $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"'; + header('Etag: ' . $etag); + } // See if the client has provided the required HTTP headers. $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE; @@ -1367,13 +1379,14 @@ function drupal_serve_page_from_cache(stdClass $cache) { drupal_add_http_header($name, $value); } - $default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $cache->created); + $last_modified_date = isset($cache->created) ? $cache->created : REQUEST_TIME; + $default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $last_modified_date); // HTTP/1.0 proxies does not support the Vary header, so prevent any caching // 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); @@ -1403,6 +1416,15 @@ function drupal_serve_page_from_cache(stdClass $cache) { } } +} + +/** + * Sets HTTP headers in preparation for a cached page response and prints the + * cached page data. + */ +function drupal_serve_page_from_cache(stdClass $cache) { + drupal_page_cache_headers($cache); + // Print the page. print $cache->data['body']; } @@ -2323,7 +2345,7 @@ function _drupal_bootstrap_page_cache() { 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_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(); @@ -2350,6 +2372,9 @@ function _drupal_bootstrap_page_cache() { // We are done. exit; } + elseif (!isset($_COOKIE[session_name()]) && $cache_enabled == CACHE_EXTERNAL) { + drupal_page_cache_headers(); + } else { header('X-Drupal-Cache: MISS'); } diff --git a/includes/common.inc b/includes/common.inc index e6ed202d35a..ec93d846751 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -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_DISABLED); + if (($cache_mode && $cache_mode != CACHE_EXTERNAL) && ($cache = drupal_page_set_cache())) { drupal_serve_page_from_cache($cache); } else { From 8f0068d708de7dfd88c4002f73093b3a052a4a64 Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Sun, 19 Aug 2012 02:30:46 -0500 Subject: [PATCH 2/7] Updating admin form for caching mode and setting cache mode constants more consistently. --- includes/bootstrap.inc | 18 ++++++++++++++---- includes/common.inc | 4 ++-- includes/form.inc | 2 +- includes/language.inc | 2 +- modules/system/system.admin.inc | 29 ++++++++++++++++++++++++++--- modules/system/system.install | 4 ++-- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 428f3936a44..ea7ae9ed83f 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -37,12 +37,22 @@ 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_EXTERNAL', 3); +define('CACHE_MODE_EXTERNAL', 3); /** * @defgroup logging_severity_levels Logging severity levels @@ -2340,12 +2350,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 && $cache_enabled != CACHE_EXTERNAL) { + 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(); @@ -2372,7 +2382,7 @@ function _drupal_bootstrap_page_cache() { // We are done. exit; } - elseif (!isset($_COOKIE[session_name()]) && $cache_enabled == CACHE_EXTERNAL) { + elseif (!isset($_COOKIE[session_name()]) && $cache_enabled == CACHE_MODE_EXTERNAL) { drupal_page_cache_headers(); } else { diff --git a/includes/common.inc b/includes/common.inc index ec93d846751..7f2f5d31484 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2607,8 +2607,8 @@ function drupal_page_footer() { drupal_session_commit(); // Do not cache if cache is disabled or external. - $cache_mode = variable_get('cache', CACHE_DISABLED); - if (($cache_mode && $cache_mode != CACHE_EXTERNAL) && ($cache = drupal_page_set_cache())) { + $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 { diff --git a/includes/form.inc b/includes/form.inc index d7350b3e2b5..df667228977 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -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'); } diff --git a/includes/language.inc b/includes/language.inc index 20909f5a6f4..9b652e5508a 100644 --- a/includes/language.inc +++ b/includes/language.inc @@ -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; diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index 23a975b0cf5..9814aaa960b 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1678,12 +1678,35 @@ function system_performance_settings() { '#title' => t('Caching'), ); - $cache = variable_get('cache', 0); + $cache = variable_get('cache', CACHE_DISABLED); + $description = '

' . 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.') . '

'; + + $problem_modules = array_unique(array_merge(module_implements('boot'), module_implements('exit'))); + sort($problem_modules); + + if (count($problem_modules) > 0) { + $description .= '

' . t('The following enabled modules are potentially incompatible with and external-mode caching and may not function properly: %modules', array('%modules' => implode(', ', $problem_modules))) . '.

'; + } + else { + $description .= '

' . t('Currently, all enabled modules are compatible with an external caching policy. Please note, if you use external caching and enable new modules, you will need to check this page again to ensure compatibility.') . '

'; + } + + $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 anonymous 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_DISABLED => t('Disabled'), + CACHE_NORMAL => t('Normal (reccomended for production sites, no side effects)'), + CACHE_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') . '>'; diff --git a/modules/system/system.install b/modules/system/system.install index 1161d6cddf1..1f7e7ac6180 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -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.'); } } From 833899cdebaf137dcf6791bef6b759fc989873b0 Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Sun, 19 Aug 2012 03:32:35 -0500 Subject: [PATCH 3/7] Fixing variable references. --- modules/system/system.admin.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index 9814aaa960b..8edf37ad9ae 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1678,7 +1678,7 @@ function system_performance_settings() { '#title' => t('Caching'), ); - $cache = variable_get('cache', CACHE_DISABLED); + $cache = variable_get('cache', CACHE_MODE_DISABLED); $description = '

' . 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.') . '

'; $problem_modules = array_unique(array_merge(module_implements('boot'), module_implements('exit'))); @@ -1701,9 +1701,9 @@ function system_performance_settings() { '#title' => t('Caching mode'), '#default_value' => $cache, '#options' => array( - CACHE_DISABLED => t('Disabled'), - CACHE_NORMAL => t('Normal (reccomended for production sites, no side effects)'), - CACHE_EXTERNAL => t('External (experts only, possible side effects)'), + 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, From b0f78256f04eead5d4b784231ea914f897557385 Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Sun, 19 Aug 2012 06:44:41 -0500 Subject: [PATCH 4/7] Simplified (and working :-S) external cache handling. --- includes/bootstrap.inc | 56 +++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index ea7ae9ed83f..55186871940 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -1312,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', '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); @@ -1332,7 +1339,7 @@ function drupal_page_header() { * and the conditions match those currently in the cache, a 304 Not Modified * response is sent. */ -function drupal_page_cache_headers(stdClass $cache = NULL) { +function drupal_serve_page_from_cache(stdClass $cache) { // Negotiate whether to use compression. $page_compression = variable_get('page_compression', TRUE) && extension_loaded('zlib'); $return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE; @@ -1344,16 +1351,14 @@ function drupal_page_cache_headers(stdClass $cache = NULL) { // drupal_add_http_headers(). Keys are mixed-case. $default_headers = array(); - if ($cache) { - foreach ($cache->data['headers'] as $name => $value) { - // In the case of a 304 response, certain headers must be sent, and the - // remaining may not (see RFC 2616, section 10.3.5). Do not override - // headers set in hook_boot(). - $name_lower = strtolower($name); - if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) { - drupal_add_http_header($name, $value); - unset($cache->data['headers'][$name]); - } + foreach ($cache->data['headers'] as $name => $value) { + // In the case of a 304 response, certain headers must be sent, and the + // remaining may not (see RFC 2616, section 10.3.5). Do not override + // headers set in hook_boot(). + $name_lower = strtolower($name); + if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) { + drupal_add_http_header($name, $value); + unset($cache->data['headers'][$name]); } } @@ -1365,12 +1370,9 @@ function drupal_page_cache_headers(stdClass $cache = NULL) { $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? variable_get('page_cache_maximum_age', 0) : 0; $default_headers['Cache-Control'] = 'public, max-age=' . $max_age; - $etag = FALSE; - if ($cache) { - // Entity tag should change if the output changes. - $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"'; - header('Etag: ' . $etag); - } + // Entity tag should change if the output changes. + $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"'; + header('Etag: ' . $etag); // See if the client has provided the required HTTP headers. $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE; @@ -1389,8 +1391,7 @@ function drupal_page_cache_headers(stdClass $cache = NULL) { drupal_add_http_header($name, $value); } - $last_modified_date = isset($cache->created) ? $cache->created : REQUEST_TIME; - $default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $last_modified_date); + $default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $cache->created); // HTTP/1.0 proxies does not support the Vary header, so prevent any caching // by sending an Expires date in the past. HTTP/1.1 clients ignores the @@ -1426,15 +1427,6 @@ function drupal_page_cache_headers(stdClass $cache = NULL) { } } -} - -/** - * Sets HTTP headers in preparation for a cached page response and prints the - * cached page data. - */ -function drupal_serve_page_from_cache(stdClass $cache) { - drupal_page_cache_headers($cache); - // Print the page. print $cache->data['body']; } @@ -2382,10 +2374,7 @@ function _drupal_bootstrap_page_cache() { // We are done. exit; } - elseif (!isset($_COOKIE[session_name()]) && $cache_enabled == CACHE_MODE_EXTERNAL) { - drupal_page_cache_headers(); - } - else { + elseif ($cache_enabled != CACHE_MODE_EXTERNAL) { header('X-Drupal-Cache: MISS'); } } @@ -2480,6 +2469,7 @@ function _drupal_bootstrap_page_header() { if (!drupal_is_cli()) { ob_start(); drupal_page_header(); + $header = drupal_get_http_header(); } } From c39b1c3c9d6c51efa79c3f64a8303563a6adeb8f Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Sun, 19 Aug 2012 06:47:11 -0500 Subject: [PATCH 5/7] Make the expires headers consistent with eachother. --- includes/bootstrap.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 55186871940..4262166fc1e 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -1320,7 +1320,7 @@ function drupal_page_header() { } $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' => $cache_control, 'ETag' => '"' . REQUEST_TIME . '"', From 437939226200f4acf65c1d726ca1057f0f89e7c9 Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Sun, 19 Aug 2012 06:48:22 -0500 Subject: [PATCH 6/7] Removing debug code. --- includes/bootstrap.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 4262166fc1e..0345c336bfa 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -2469,7 +2469,6 @@ function _drupal_bootstrap_page_header() { if (!drupal_is_cli()) { ob_start(); drupal_page_header(); - $header = drupal_get_http_header(); } } From 7806c4c1a7917e2692b9554664b923ea6f823c1a Mon Sep 17 00:00:00 2001 From: Elliott Foster Date: Tue, 21 Aug 2012 16:48:17 -0500 Subject: [PATCH 7/7] Update bootstrap test to avoid page cache failure. --- modules/simpletest/tests/bootstrap.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/simpletest/tests/bootstrap.test b/modules/simpletest/tests/bootstrap.test index 014fc94883c..09c10610702 100644 --- a/modules/simpletest/tests/bootstrap.test +++ b/modules/simpletest/tests/bootstrap.test @@ -161,7 +161,7 @@ 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. @@ -169,7 +169,7 @@ class BootstrapPageCacheTestCase extends DrupalWebTestCase { $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. @@ -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.')); }