? log_node.txt
? modules/simpletest/tests/343502.test
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.257
diff -u -p -r1.257 bootstrap.inc
--- includes/bootstrap.inc	3 Dec 2008 14:51:53 -0000	1.257
+++ includes/bootstrap.inc	13 Dec 2008 21:53:37 -0000
@@ -654,19 +654,23 @@ function variable_del($name) {
 /**
  * Retrieve the current page from the cache.
  *
- * Note: we do not serve cached pages when status messages are waiting (from
- * a redirected form submission which was completed).
+ * @return
+ *   A string of the saved page from the cache, or NULL if the page has not
+ *   been cached or is not allowed to be cached.
+ *
+ * @see page_cache_allowed
  */
 function page_get_cache() {
-  global $user, $base_root;
+  global $base_root;
 
   $cache = NULL;
 
-  if (!$user->uid && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && count(drupal_set_message()) == 0) {
+  if (page_cache_allowed()) {
     $cache = cache_get($base_root . request_uri(), 'cache_page');
 
     if (empty($cache)) {
       ob_start();
+      page_cache_allowed(TRUE);
     }
   }
 
@@ -674,6 +678,36 @@ function page_get_cache() {
 }
 
 /**
+ * Retrieves and optionally sets the current page caching status.
+ *
+ * This function is useful if page caching has been started but needs to be
+ * disabled for the current page if something unique is being displayed on the
+ * page, like a message with drupal_set_message().
+ *
+ * @param $cache_status
+ *   (optional) A boolean that sets the current page caching status.
+ * @return
+ *   TRUE if the current page should be cached, FALSE if otherwise.
+ */
+function page_cache_allowed($cache_status = NULL) {
+  global $user;
+  static $status = NULL;
+
+  if (!isset($status)) {
+    // Do not allow caching when status messages are waiting (from a redirected
+    // form submission which was completed).
+    $status = count(drupal_set_message()) == 0;
+  }
+
+  if (isset($cache_status)) {
+    $status = $cache_status;
+  }
+
+  // Always check the request method and that the user is logged out.
+  return $status && !$user->uid && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
+}
+
+/**
  * Includes a file with the provided type and name. This prevents
  * including a theme, engine, module, etc., more than once.
  *
@@ -947,6 +981,8 @@ function drupal_set_message($message = N
 
     if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
       $_SESSION['messages'][$type][] = $message;
+      // Disable the current request from being cached.
+      page_cache_allowed(FALSE);
     }
   }
 
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.837
diff -u -p -r1.837 common.inc
--- includes/common.inc	12 Dec 2008 16:07:13 -0000	1.837
+++ includes/common.inc	13 Dec 2008 21:53:41 -0000
@@ -2907,30 +2907,27 @@ function _drupal_bootstrap_full() {
  * the browser does not accept gzip encoding.
  *
  * @see drupal_page_header
+ * @see page_cache_allowed
  */
 function page_set_cache() {
-  global $user, $base_root;
+  global $base_root;
 
-  if (!$user->uid && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && count(drupal_get_messages(NULL, FALSE)) == 0) {
-    // This will fail in some cases, see page_get_cache() for the explanation.
-    if ($data = ob_get_contents()) {
-      $cache = TRUE;
-      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 = FALSE;
-        }
-        elseif (zlib_get_coding_type() == FALSE) {
-          $data = gzencode($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 (ob_get_level() && $data = ob_get_contents()) {
+    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') {
+        page_cache_allowed(FALSE);
       }
-      ob_end_flush();
-      if ($cache && $data) {
-        cache_set($base_root . request_uri(), $data, 'cache_page', CACHE_TEMPORARY, drupal_get_headers());
+      elseif (zlib_get_coding_type() == FALSE) {
+        $data = gzencode($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.
+    }
+    ob_end_flush();
+    if (page_cache_allowed() && $data) {
+      cache_set($base_root . request_uri(), $data, 'cache_page', CACHE_TEMPORARY, drupal_get_headers());
     }
   }
 }
Index: modules/simpletest/tests/cache.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/cache.test,v
retrieving revision 1.3
diff -u -p -r1.3 cache.test
--- modules/simpletest/tests/cache.test	8 Dec 2008 21:41:54 -0000	1.3
+++ modules/simpletest/tests/cache.test	13 Dec 2008 21:53:41 -0000
@@ -101,6 +101,86 @@ class CacheTestCase extends DrupalWebTes
   }
 }
 
+/**
+ * Test page caching.
+ */
+class CachePageCase extends CacheTestCase {
+
+  function getInfo() {
+    return array(
+      'name' => t('Cache page test'),
+      'description' => t('Check caching of pages and conditions for not caching pages.'),
+      'group' => t('Cache'),
+    );
+  }
+
+  function setUp() {
+    parent::setUp('system_test');
+
+    // Enable caching and clear the page cache.
+    variable_set('cache', CACHE_NORMAL);
+    cache_clear_all('*', 'cache_page');
+  }
+
+  /**
+   * Test that pages with messages are not cached.
+   */
+  function testNoCacheMessages() {
+    // View the front page with a message on it and test it was not cached.
+    variable_set('front_page_output', 1);
+    $this->drupalGet('');
+    $this->assertText(t('On front page.'), t('Message found.'));
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertFalse($cache, t('Page has not been cached.'));
+
+    // View the front page without a message on it and test it was cached.
+    variable_set('front_page_output', 0);
+    $this->drupalGet('');
+    $this->assertNoText(t('On front page.'), t('Message not found.'));
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertTrue($cache, t('Page has been cached.'));
+  }
+
+  /**
+   * Test that pages viewed by logged in users are not cached.
+   */
+  function testNoCacheLoggedIn() {
+    // Create a user, log in, and test that the request was not cached.
+    $this->user = $this->drupalCreateUser(array('access content'));
+    $this->drupalLogin($this->user);
+    $this->drupalGet('');
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertFalse($cache, t('Page has not been cached.'));
+
+    // Logout and check that the next request is cached.
+    $this->drupalLogout();
+    $this->drupalGet('');
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertTrue($cache, t('Page has been cached.'));
+  }
+
+  /**
+   * Test that GET AND HEAD requests are cached, but not POST requests.
+   */
+  function testNoCachePost() {
+    // Make a POST request and test it was not cached.
+    $this->drupalPost(NULL, array(), t('Log in'));
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertFalse($cache, t('Page has not been cached.'));
+
+    // Make a HEAD request and test it was cached.
+    $this->drupalHead('');
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertTrue($cache, t('Page has been cached.'));
+    cache_clear_all('*', 'cache_page');
+
+    // Make a GET request and test it was cached.
+    $this->drupalGet('');
+    $cache = cache_get(url('', array('absolute' => TRUE)), 'cache_page');
+    $this->assertTrue($cache, t('Page has been cached.'));
+  }
+}
+
 class CacheSavingCase extends CacheTestCase {
   function getInfo() {
     return array(
@@ -224,4 +304,4 @@ class CacheClearCase extends CacheTestCa
                       || $this->checkCacheExists('test_cid_clear2', $this->default_value),
                       t('Two caches removed after clearing cid substring with wildcard true.'));
   }
-}
\ No newline at end of file
+}
