Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.277
diff -u -9 -p -r1.277 bootstrap.inc
--- includes/bootstrap.inc 24 Apr 2009 08:15:50 -0000 1.277
+++ includes/bootstrap.inc 26 Apr 2009 21:22:03 -0000
@@ -985,18 +985,21 @@ function drupal_page_cache_header(stdCla
// that the module knows how to cache the page.
if (!isset($hook_boot_headers['vary']) && !variable_get('omit_vary_cookie')) {
header('Vary: Cookie');
}
if ($page_compression) {
header('Vary: Accept-Encoding', FALSE);
// If page_compression is enabled, the cache contains gzipped data.
if ($return_compressed) {
+ // $cache->data is already gzip'ed, so make sure zlib.output_compression
+ // does not compress it once more.
+ ini_set('zlib.output_compression', '0');
header('Content-Encoding: gzip');
}
else {
// The client does not support compression, so unzip the data in the
// cache. Strip the gzip header and run uncompress.
$cache->data = gzinflate(substr(substr($cache->data, 10), 0, -8));
}
}
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.887
diff -u -9 -p -r1.887 common.inc
--- includes/common.inc 26 Apr 2009 19:44:37 -0000 1.887
+++ includes/common.inc 26 Apr 2009 21:22:03 -0000
@@ -3024,59 +3024,49 @@ function _drupal_bootstrap_full() {
// We do not want this while running update.php.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
module_invoke_all('init');
}
}
/**
* Store the current page in the cache.
*
- * We try to store a gzipped version of the cache. This requires the
- * PHP zlib extension (http://php.net/manual/en/ref.zlib.php).
- * Presence of the extension is checked by testing for the function
- * gzencode. There are two compression algorithms: gzip and deflate.
- * The majority of all modern browsers support gzip or both of them.
- * We thus only deal with the gzip variant and unzip the cache in case
- * the browser does not accept gzip encoding.
+ * If page_compression is enabled, a gzipped version of the page is stored in
+ * the cache to avoid compressing the output on each request. The cache entry
+ * is unzipped in the relatively rare event that the page is requested by a
+ * client without gzip support.
+ *
+ * Page compression requires the PHP zlib extension
+ * (http://php.net/manual/en/ref.zlib.php).
*
* @see drupal_page_header
*/
function page_set_cache() {
- global $user, $base_root;
+ global $base_root;
if (page_get_cache(FALSE)) {
- $cache_page = TRUE;
$cache = (object) array(
'cid' => $base_root . request_uri(),
'data' => ob_get_clean(),
'expire' => CACHE_TEMPORARY,
'created' => REQUEST_TIME,
'headers' => array(),
);
// Restore preferred header names based on the lower-case names returned
// by drupal_get_header().
$header_names = _drupal_set_preferred_header_name();
foreach (drupal_get_header() as $name_lower => $value) {
$cache->headers[$header_names[$name_lower]] = $value;
}
- if (variable_get('page_compression', TRUE) && function_exists('gzencode')) {
- // We do not store the data in case the zlib mode is deflate. This should
- // be rarely happening.
- if (zlib_get_coding_type() == 'deflate') {
- $cache_page = FALSE;
- }
- elseif (zlib_get_coding_type() == FALSE) {
+ if ($cache->data) {
+ if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
$cache->data = gzencode($cache->data, 9, FORCE_GZIP);
}
- // The remaining case is 'gzip' which means the data is already
- // compressed and nothing left to do but to store it.
- }
- if ($cache_page && $cache->data) {
cache_set($cache->cid, $cache->data, 'cache_page', $cache->expire, $cache->headers);
}
drupal_page_cache_header($cache);
}
else {
// If output buffering was enabled during bootstrap, and the headers were
// not sent in the DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE phase, send them now.
drupal_page_header();
}
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.98
diff -u -9 -p -r1.98 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php 25 Apr 2009 22:35:49 -0000 1.98
+++ modules/simpletest/drupal_web_test_case.php 26 Apr 2009 21:22:04 -0000
@@ -1215,19 +1215,19 @@ class DrupalWebTestCase {
/**
* Check for meta refresh tag and if found call drupalGet() recursively. This
* function looks for the http-equiv attribute to be set to "Refresh"
* and is case-sensitive.
*
* @return
* Either the new page content or FALSE.
*/
protected function checkForMetaRefresh() {
- if ($this->drupalGetContent() != '' && $this->parse()) {
+ if (strpos($this->drupalGetContent(), 'parse()) {
$refresh = $this->xpath('//meta[@http-equiv="Refresh"]');
if (!empty($refresh)) {
// Parse the content attribute of the meta tag for the format:
// "[delay]: URL=[page_to_redirect_to]".
if (preg_match('/\d+;\s*URL=(?P.*)/i', $refresh[0]['content'], $match)) {
return $this->drupalGet($this->getAbsoluteUrl(decode_entities($match['url'])));
}
}
}
Index: modules/simpletest/tests/bootstrap.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/bootstrap.test,v
retrieving revision 1.15
diff -u -9 -p -r1.15 bootstrap.test
--- modules/simpletest/tests/bootstrap.test 22 Apr 2009 09:45:03 -0000 1.15
+++ modules/simpletest/tests/bootstrap.test 26 Apr 2009 21:22:04 -0000
@@ -85,19 +85,19 @@ class BootstrapIPAddressTestCase extends
$this->assertTrue(drupal_valid_http_host('[::1]:80'), t('HTTP_HOST containing IPv6 loopback is valid'));
}
}
class BootstrapPageCacheTestCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => t('Page cache test'),
- 'description' => t('Enable the page cache and test it with conditional HTTP requests.'),
+ 'description' => t('Enable the page cache and test it with various HTTP requests.'),
'group' => t('Bootstrap')
);
}
function setUp() {
parent::setUp('system_test');
}
/**
@@ -171,18 +171,81 @@ class BootstrapPageCacheTestCase extends
$this->drupalLogin($user);
$this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')));
$this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), t('Caching was bypassed.'));
$this->assertFalse($this->drupalGetHeader('Vary'), t('Vary 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('Foo'), 'bar', t('Custom header was sent.'));
}
+
+ /**
+ * Test page compression when zlib.output_compression is disabled.
+ *
+ * The test should pass even if zlib.output_compression is enabled in php.ini,
+ * .htaccess or similar, or if compression is done outside PHP, e.g. by the
+ * mod_deflate Apache module.
+ */
+ function testPageCompression() {
+ variable_set('cache', CACHE_NORMAL);
+ // Disable zlib.output_compression in system_test_boot().
+ variable_set('zlib_output_compression', 'O');
+
+ // Fill the cache. The response is not compressed, unless compression is
+ // done outside PHP, e.g. by the mod_deflate Apache module.
+ $this->drupalGet('', array(), array('Accept-Encoding: gzip,deflate'));
+ $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', t('Page was cached.'));
+
+ // Verify that cached output is compressed.
+ $this->drupalGet('', array(), array('Accept-Encoding: gzip,deflate'));
+ $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.'));
+ $this->assertEqual($this->drupalGetHeader('Content-Encoding'), 'gzip', t('A Content-Encoding header was sent.'));
+ $this->assertTrue(strpos(gzinflate(substr($this->drupalGetContent(), 10, -8)), t('Welcome to your new Drupal website!')), t('Page was gzip compressed.'));
+
+ // Verify that a client with compression support gets an uncompressed page.
+ $this->drupalGet('');
+ $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.'));
+ $this->assertFalse($this->drupalGetHeader('Content-Encoding'), t('A Content-Encoding header was not sent.'));
+ $this->assertText(t('Welcome to your new Drupal website!'), t('Page was not compressed.'));
+
+ // Verify that a client without gzip support gets an uncompressed page.
+ $this->drupalGet('', array(), array('Accept-Encoding: deflate'));
+ $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.'));
+ $this->assertFalse($this->drupalGetHeader('Content-Encoding'), t('A Content-Encoding header was not sent.'));
+ $this->assertText(t('Welcome to your new Drupal website!'), t('Page was not compressed.'));
+ }
+
+ /**
+ * Test page compression when zlib.output_compression is enabled.
+ *
+ * Requires that zlib.output_compression is enabled in php.ini, .htaccess or
+ * similar.
+ */
+ function testPageCompressionWithZlibOutputCompression() {
+ // zlib.output_compression cannot be enabled at runtime, so this test can
+ // only run, if it has been enabled in php.ini, .htaccess or similar. See
+ // http://bugs.php.net/bug.php?id=33653
+ if (!ini_get('zlib.output_compression')) {
+ return;
+ }
+
+ variable_set('cache', CACHE_NORMAL);
+
+ // Fill the cache. Compression is done by zlib.output_compression.
+ $this->drupalGet('', array(), array('Accept-Encoding: deflate'));
+ $this->assertEqual($this->drupalGetHeader('Content-Encoding'), 'deflate', t('A Content-Encoding header was sent.'));
+
+ // Verify that output is gzip'ed, even though the cache was filled when
+ // zlib.output_compression was doing deflate compression.
+ $this->drupalGet('', array(), array('Accept-Encoding: gzip'));
+ $this->assertEqual($this->drupalGetHeader('Content-Encoding'), 'gzip', t('Page was compressed.'));
+ $this->assertTrue(strpos(gzinflate(substr($this->drupalGetContent(), 10, -8)), t('Welcome to your new Drupal website!')), t('Page was compressed.'));
+ }
}
class BootstrapVariableTestCase extends DrupalWebTestCase {
function setUp() {
parent::setUp('system_test');
}
public static function getInfo() {
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.34
diff -u -9 -p -r1.34 common.test
--- modules/simpletest/tests/common.test 25 Apr 2009 13:56:06 -0000 1.34
+++ modules/simpletest/tests/common.test 26 Apr 2009 21:22:04 -0000
@@ -647,33 +647,33 @@ class DrupalErrorHandlerUnitTest extends
/**
* Test the error handler.
*/
function testErrorHandler() {
$error_notice = array(
'%type' => 'Notice',
'%message' => 'Undefined variable: bananas',
'%function' => 'system_test_generate_warnings()',
- '%line' => 194,
+ '%line' => 199,
'%file' => realpath('modules/simpletest/tests/system_test.module'),
);
$error_warning = array(
'%type' => 'Warning',
'%message' => 'Division by zero',
'%function' => 'system_test_generate_warnings()',
- '%line' => 196,
+ '%line' => 201,
'%file' => realpath('modules/simpletest/tests/system_test.module'),
);
$error_user_notice = array(
'%type' => 'User notice',
'%message' => 'Drupal is awesome',
'%function' => 'system_test_generate_warnings()',
- '%line' => 198,
+ '%line' => 203,
'%file' => realpath('modules/simpletest/tests/system_test.module'),
);
// Set error reporting to collect notices.
variable_set('error_level', 2);
$this->drupalGet('system-test/generate-warnings');
$this->assertErrorMessage($error_notice);
$this->assertErrorMessage($error_warning);
$this->assertErrorMessage($error_user_notice);
@@ -695,26 +695,26 @@ class DrupalErrorHandlerUnitTest extends
/**
* Test the exception handler.
*/
function testExceptionHandler() {
$error_exception = array(
'%type' => 'Exception',
'%message' => 'Drupal is awesome',
'%function' => 'system_test_trigger_exception()',
- '%line' => 207,
+ '%line' => 212,
'%file' => realpath('modules/simpletest/tests/system_test.module'),
);
$error_pdo_exception = array(
'%type' => 'PDOException',
'%message' => 'SQLSTATE',
'%function' => 'system_test_trigger_pdo_exception()',
- '%line' => 215,
+ '%line' => 220,
'%file' => realpath('modules/simpletest/tests/system_test.module'),
);
$this->drupalGet('system-test/trigger-exception');
$this->assertErrorMessage($error_exception);
$this->drupalGet('system-test/trigger-pdo-exception');
// We cannot use assertErrorMessage() since the extact error reported
// varies from database to database. Check for the error keyword 'SQLSTATE'.
Index: modules/simpletest/tests/system_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/system_test.module,v
retrieving revision 1.9
diff -u -9 -p -r1.9 system_test.module
--- modules/simpletest/tests/system_test.module 22 Apr 2009 09:45:03 -0000 1.9
+++ modules/simpletest/tests/system_test.module 26 Apr 2009 21:22:04 -0000
@@ -159,18 +159,23 @@ function system_test_modules_uninstalled
drupal_set_message(t('hook_modules_uninstalled fired for aggregator'));
}
}
/**
* Implementation of hook_boot().
*/
function system_test_boot() {
watchdog('system_test', 'hook_boot');
+
+ $zlib_output_compression = variable_get('zlib_output_compression', NULL);
+ if ($zlib_output_compression !== NULL) {
+ ini_set('zlib.output_compression', $zlib_output_compression);
+ }
}
/**
* Implementation of hook_init().
*/
function system_test_init() {
// Used by FrontPageTestCase to get the results of drupal_is_front_page().
if (variable_get('front_page_output', 0) && drupal_is_front_page()) {
drupal_set_message(t('On front page.'));