From 8048b9abb2968f0cf22525928800b8b4b939c589 Mon Sep 17 00:00:00 2001
From: Scott Shambarger <sshambar@2956739.no-reply.drupal.org>
Date: Tue, 22 Jul 2014 10:06:54 +0200
Subject: [PATCH] Added cache busting handling to hook_boot

---
 webserver_auth.module | 62 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/webserver_auth.module b/webserver_auth.module
index 4c9b423..04e932d 100644
--- a/webserver_auth.module
+++ b/webserver_auth.module
@@ -49,26 +49,52 @@ function webserver_auth_menu_get_item_alter(&$router_item, $path, $original_map)
  /**
  * Implements hook_boot().
  *
- * Adds a minimal check to see if webserver has stored a remote user in the
- * $_SERVER variable, and if so, turn off caching for the page request. The idea
- * is to use hook_boot to speculate about the forthcoming authentication
- * inspection in hook_menu_get_item_alter and prevent page caching from
- * happening before it gets to that point (page caching occurs in hook_exit,
- * which happens before hook_menu_get_item_alter).
+ * We need to check if a cached page is being served to an authenticated user,
+ * and if so, force the start of a session and reload the page.
  */
 function webserver_auth_boot() {
-  global $conf;
-  // Only run if hook_boot is called from _drupal_bootstrap_page_cache() and
-  // not _drupal_bootstrap_page_header().
-  if (!isset($_COOKIE[session_name()])) {
-    $authname = webserver_auth_retrieve_remote_user();
-    if (!empty($authname)) {
-      // Disable caching for this page request.
-      $conf['cache'] = FALSE;
-      // Then resume the bootstrap phase.
-      drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-    }
+
+  /* Get authname from environment */
+  $authname = webserver_auth_retrieve_remote_user();
+  if (! $authname) {
+    return;
+  }
+
+  /* authenticated pages are never cacheable... */
+  drupal_page_is_cacheable(FALSE);
+
+  /* We only care if hook_boot called on cached pages */
+  if (! drupal_page_get_cache(TRUE)) {
+    return;
+  }
+
+  /* Cache busting only relevant in BOOTSTRAP_PAGE_CACHE
+     NOTE: drupal_get_bootstrap_phase() resets the bootstrap phase (bug?) */
+  if (drupal_bootstrap(NULL, FALSE) >= DRUPAL_BOOTSTRAP_PAGE_HEADER) {
+    return;
+  }
+
+  /* Use hash to check if we've already attempted to verify this user
+     recently (to avoid redirect loops, and regular users in maintenance) */
+  $authhash = hash('md5', $authname);
+  if (isset($_COOKIE['webserver_auth'])
+      && ($authhash == $_COOKIE['webserver_auth'])) {
+    return;
   }
+
+  /* We have an authenticated cached page during early boot.
+     Finish bootstrap so drupal_goto is available */
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+
+  /* Set our hash cookie so we only attempt to force authentication
+     every minute or so (in case of maintenance or some other force logout
+     condition) */
+  $params = session_get_cookie_params();
+  setcookie('webserver_auth', $authhash, REQUEST_TIME + 60, $params['path'], $params['domain'], FALSE, $params['httponly']);
+  _webserver_auth_route();
+
+  /* Now, with session and hash cookie set, attempt to reload the page */
+  drupal_goto(request_path());
 }
 
 /**
@@ -325,4 +351,4 @@ function webserver_auth_webserver_auth_authname_alter(&$username) {
     $fields = explode ('@', $username);
     $username = $fields [0];
   }
-}
\ No newline at end of file
+}
-- 
1.8.5.2 (Apple Git-48)

