Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.206.2.4
diff -u -F^f -r1.206.2.4 bootstrap.inc
--- includes/bootstrap.inc	18 Aug 2008 18:56:30 -0000	1.206.2.4
+++ includes/bootstrap.inc	11 Sep 2008 15:48:05 -0000
@@ -588,6 +588,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");
@@ -608,27 +617,35 @@ 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('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();
+  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);
+  }
+  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.892.2.7
diff -u -F^f -r1.892.2.7 user.module
--- modules/user/user.module	17 Aug 2008 10:49:02 -0000	1.892.2.7
+++ modules/user/user.module	11 Sep 2008 15:48:07 -0000
@@ -1362,6 +1362,12 @@ function user_authenticate_finalize(&$ed
 
   // Regenerate the session ID to prevent against session fixation attacks.
   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'), '/');
+  }
+
   user_module_invoke('login', $edit, $user);
 }
 
Index: modules/user/user.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v
retrieving revision 1.11
diff -u -F^f -r1.11 user.pages.inc
--- modules/user/user.pages.inc	8 Jan 2008 10:35:43 -0000	1.11
+++ modules/user/user.pages.inc	11 Sep 2008 15:48:07 -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);
