Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.224
diff -u -F^f -r1.224 bootstrap.inc
--- includes/bootstrap.inc	8 Sep 2008 21:24:30 -0000	1.224
+++ includes/bootstrap.inc	10 Sep 2008 01:51:00 -0000
@@ -616,6 +616,15 @@ function drupal_load($type, $name) {
  * @see page_set_cache()
  */
 function drupal_page_header() {
+  global $user;
+
+  // Set a cookie if the user is logged in, so the reverse proxy would
+  // pass through the request. This requires a rule in the reverse proxy's
+  // configuration. See settings.php for details.
+  if ($user->uid && !isset($_COOKIE['DRUPAL_LOGGED_IN'])) {
+    setcookie('DRUPAL_LOGGED_IN', 'Y', $_SERVER['REQUEST_TIME'] + ini_get('session.cookie_lifetime'), '/');
+  }
+    
   header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
   header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
   header("Cache-Control: store, no-cache, must-revalidate");
@@ -636,27 +645,36 @@ function drupal_page_cache_header($cache
   $last_modified = gmdate('D, d M Y H:i:s', $cache->created) . ' GMT';
   $etag = '"' . md5($last_modified) . '"';
 
-  // See if the client has provided the required HTTP headers:
-  $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
-  $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
-
-  if ($if_modified_since && $if_none_match
-      && $if_none_match == $etag // etag must match
-      && $if_modified_since == $last_modified) {  // if-modified-since must match
-    header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
-    // All 304 responses must send an etag if the 200 response for the same object contained an etag
-    header("Etag: $etag");
-    exit();
+  if (variable_get('reverse_proxy', 0)) {
+    // Optimize the headers for anonymous users when we have a reverse proxy such as Squid
+    $lifetime = variable_get('cache_lifetime', 300);
+    header('Expires: ' . gmdate('D, d M Y H:i:s', $cache->created + $lifetime) . ' GMT');
+    $age = abs($_SERVER['REQUEST_TIME'] - $cache->created);
+    header('Cache-Control: public, max-age=' . $age);
+    header('Vary: Cookie');
+  }
+  else {
+    // See if the client has provided the required HTTP headers:
+    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
+    $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
+
+    if ($if_modified_since && $if_none_match
+        && $if_none_match == $etag // etag must match
+        && $if_modified_since == $last_modified) {  // if-modified-since must match
+      header('HTTP/1.1 304 Not Modified');
+      // All 304 responses must send an etag if the 200 response for the same object contained an etag
+      header("Etag: $etag");
+      exit();
+    }
+    // Use the old header which does not get cached
+    header('Expires: Sun, 19 Nov 1978 05:00:00 GMT');
+    header('Cache-Control: must-revalidate');
   }
 
   // Send appropriate response:
   header("Last-Modified: $last_modified");
   header("ETag: $etag");
 
-  // The following headers force validation of cache:
-  header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
-  header("Cache-Control: must-revalidate");
-
   if (variable_get('page_compression', TRUE)) {
     // Determine if the browser accepts gzipped data.
     if (@strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE && function_exists('gzencode')) {
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.919
diff -u -F^f -r1.919 user.module
--- modules/user/user.module	8 Sep 2008 15:44:57 -0000	1.919
+++ modules/user/user.module	10 Sep 2008 01:51:02 -0000
@@ -1345,6 +1345,10 @@ function user_authenticate_finalize(&$ed
   db_query("UPDATE {users} SET login = %d WHERE uid = %d", $user->login, $user->uid);
   user_module_invoke('login', $edit, $user);
   sess_regenerate();
+  if (variable_get('reverse_proxy', 0)) {
+    // If we have a reverse proxy, we set a special cookie so the proxy would pass through the requests
+    setcookie('DRUPAL_LOGGED_IN', 'Y', $_SERVER['REQUEST_TIME'] + ini_get('session.cookie_lifetime'), '/');
+  }
 }
 
 /**
Index: modules/user/user.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v
retrieving revision 1.16
diff -u -F^f -r1.16 user.pages.inc
--- modules/user/user.pages.inc	6 Sep 2008 08:36:22 -0000	1.16
+++ modules/user/user.pages.inc	10 Sep 2008 01:51:02 -0000
@@ -133,6 +133,12 @@ function user_logout() {
 
   watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
 
+  if (variable_get('reverse_proxy', 0)) {
+    // If we are behind a reverse proxy, unset the logged in cookie by giving it
+    // an empty value and a time in the past
+    setcookie('DRUPAL_LOGGED_IN', '', $_SERVER['REQUEST_TIME'] - 86400, '/');
+  }
+
   // Destroy the current session:
   session_destroy();
   module_invoke_all('user', 'logout', NULL, $user);
Index: sites/default/default.settings.php
===================================================================
RCS file: /cvs/drupal/drupal/sites/default/default.settings.php,v
retrieving revision 1.14
diff -u -F^f -r1.14 default.settings.php
--- sites/default/default.settings.php	21 Aug 2008 19:36:39 -0000	1.14
+++ sites/default/default.settings.php	10 Sep 2008 01:51:02 -0000
@@ -268,6 +268,25 @@
  * logging, statistics and access management systems; if you are unsure
  * about this setting, do not have a reverse proxy, or Drupal operates in
  * a shared hosting environment, this setting should remain commented out.
+ *
+ * Configuration for Squid
+ *   ...
+ *   acl cookie_logged_in_set rep_header Set-Cookie DRUPAL_LOGGED_IN=Y
+ *   cache deny cookie_logged_in
+ *   acl cookie_logged_in req_header Cookie DRUPAL_LOGGED_IN=Y
+ *   cache deny cookie_logged_in_set
+ *   ...
+ *
+ * Configuration for Varnish
+ *
+ *    sub vcl_recv {
+ *      ...
+ *      if (req.http.Cookie && req.http.Cookie ~ "DRUPAL_LOGGED_IN=Y") {
+ *        pass;
+ *      }
+ *      ...
+ *    }
+ *
  */
 #   'reverse_proxy' => TRUE, // Leave the comma here.
 /**
