Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.285
diff -u -9 -p -r1.285 bootstrap.inc
--- includes/bootstrap.inc	2 Jun 2009 06:58:15 -0000	1.285
+++ includes/bootstrap.inc	6 Jun 2009 18:48:10 -0000
@@ -981,18 +981,21 @@ function drupal_serve_page_from_cache(st
   // 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.919
diff -u -9 -p -r1.919 common.inc
--- includes/common.inc	6 Jun 2009 16:05:26 -0000	1.919
+++ includes/common.inc	6 Jun 2009 18:48:10 -0000
@@ -3288,62 +3288,51 @@ 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 drupal_page_set_cache() {
   global $base_root;
 
   if (drupal_page_is_cacheable()) {
-    $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);
     }
     return $cache;
   }
 }
 
 /**
  * Executes a cron run when called
  * @return
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.113
diff -u -9 -p -r1.113 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	4 Jun 2009 03:33:28 -0000	1.113
+++ modules/simpletest/drupal_web_test_case.php	6 Jun 2009 18:48:11 -0000
@@ -1392,19 +1392,19 @@ class DrupalWebTestCase extends DrupalTe
   /**
    * 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(), '<meta ') && $this->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<url>.*)/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.17
diff -u -9 -p -r1.17 bootstrap.test
--- modules/simpletest/tests/bootstrap.test	30 May 2009 11:17:32 -0000	1.17
+++ modules/simpletest/tests/bootstrap.test	6 Jun 2009 18:48:11 -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,49 @@ 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->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('Foo'), 'bar', t('Custom header was sent.'));
 
   }
+
+  /**
+   * Test page compression.
+   * 
+   * 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);
+
+    // Fill the cache and verify that output is compressed.
+    $this->drupalGet('', array(), array('Accept-Encoding: gzip,deflate'));
+    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', t('Page was not cached.'));
+    $this->drupalSetContent(gzinflate(substr($this->drupalGetContent(), 10, -8)));
+    $this->assertRaw('</html>', t('Page was gzip compressed.'));
+
+    // 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->drupalSetContent(gzinflate(substr($this->drupalGetContent(), 10, -8)));
+    $this->assertRaw('</html>', t('Page was gzip compressed.'));
+
+    // Verify that a client without 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->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), t('Site title matches.'));
+    $this->assertRaw('</html>', t('Page was not compressed.'));
+  }
 }
 
 class BootstrapVariableTestCase extends DrupalWebTestCase {
 
   function setUp() {
     parent::setUp('system_test');
   }
 
   public static function getInfo() {
