From 8048b9abb2968f0cf22525928800b8b4b939c589 Mon Sep 17 00:00:00 2001 From: Scott Shambarger 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)