Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.225 diff -u -F^f -r1.225 bootstrap.inc --- includes/bootstrap.inc 15 Sep 2008 15:18:59 -0000 1.225 +++ includes/bootstrap.inc 16 Sep 2008 05:02:48 -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,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($_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); + } + 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.921 diff -u -F^f -r1.921 user.module --- modules/user/user.module 15 Sep 2008 15:18:59 -0000 1.921 +++ modules/user/user.module 16 Sep 2008 05:02:49 -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); drupal_session_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 16 Sep 2008 05:02:50 -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 16 Sep 2008 05:02:50 -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. /**