diff --git a/core/authorize.php b/core/authorize.php index 04c4e54f2ac0580875f23b512dbd3b7f881c9e92..5418007a76ff41bf4f17ae4fc5bdf11185b111c2 100644 --- a/core/authorize.php +++ b/core/authorize.php @@ -49,7 +49,7 @@ * TRUE if the current user can run authorize.php, and FALSE if not. */ function authorize_access_allowed() { - \Drupal::service('session_manager')->initialize(); + \Drupal::service('session_manager')->startLazy(); return Settings::get('allow_authorize_operations', TRUE) && user_access('administer software updates'); } diff --git a/core/core.services.yml b/core/core.services.yml index 022fa7e3525cf4388c74f5aa792b0e6dd37b8175..f30cee7aaeb96f13d60ec118ceff7aa3df49b422 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -800,8 +800,6 @@ services: session_manager: class: Drupal\Core\Session\SessionManager arguments: ['@request_stack', '@database', '@session_manager.metadata_bag', '@settings'] - tags: - - { name: persist } session_manager.metadata_bag: class: Drupal\Core\Session\MetadataBag arguments: ['@settings'] diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 158f8a9142dfd721338e7000803d5341d304a4f8..a6fa11dd25a55454302690fe42a0d4f38d28d330 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1451,7 +1451,7 @@ function install_load_profile(&$install_state) { * An array of information about the current installation state. */ function install_bootstrap_full() { - \Drupal::service('session_manager')->initialize(); + \Drupal::service('session_manager')->startLazy(); } /** diff --git a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php index 167a0b0747e52e4ce8a60c9a47131053ab395bc7..c5f23c865b7721bcee36bd6f18716f2f0e88c758 100644 --- a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php +++ b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php @@ -47,7 +47,8 @@ public function applies(Request $request) { public function authenticate(Request $request) { // Global $user is deprecated, but the session system is still based on it. global $user; - if ($this->sessionManager->initialize()->isStarted()) { + $this->sessionManager->startLazy(); + if ($this->sessionManager->isStarted()) { return $user; } return NULL; diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 49a4d02144ba6020291c282a50dc7bed5d81f4dc..6f2e398ab1de82c26d2bd5ef443df1b7d7b14d54 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -684,6 +684,7 @@ protected function initializeContainer($rebuild = FALSE) { // potentially scoped. $request_scope = FALSE; $request_stack = $request = NULL; + $session_manager_state = 0; if (isset($this->container)) { if ($this->container->isScopeActive('request')) { $request_scope = TRUE; @@ -694,6 +695,18 @@ protected function initializeContainer($rebuild = FALSE) { if ($this->container->initialized('request_stack')) { $request_stack = $this->container->get('request_stack'); } + // If there is a session manager, close and save the session. + if ($this->container->initialized('session_manager')) { + $session_manager = $this->container->get('session_manager'); + if ($session_manager->isStartedLazy()) { + $session_manager_state |= 0x1; + } + if ($session_manager->isStarted()) { + $session_manager_state |= 0x2; + } + $session_manager->save(); + unset($session_manager); + } } // If the module list hasn't already been set in updateModules and we are @@ -720,6 +733,12 @@ protected function initializeContainer($rebuild = FALSE) { $this->attachSynthetic($container, $request, $request_stack, $request_scope); $this->container = $container; + if ($session_manager_state & 0x1) { + $this->container->get('session_manager')->startLazy(); + } + if ($session_manager_state & 0x2) { + $this->container->get('session_manager')->start(); + } \Drupal::setContainer($this->container); return $this->container; } diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php index f656b2d7d83a21d6666bb634c49fed013257e031..e8dc572c6cdec565df5c5bef17a655378371f555 100644 --- a/core/lib/Drupal/Core/Session/SessionManager.php +++ b/core/lib/Drupal/Core/Session/SessionManager.php @@ -63,7 +63,7 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter * * @var bool */ - protected $lazySession; + protected $startedLazy; /** * Whether session management is enabled or temporarily disabled. @@ -89,10 +89,18 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter * The settings instance. */ public function __construct(RequestStack $request_stack, Connection $connection, SymfonyMetadataBag $metadata_bag, Settings $settings) { - parent::__construct(); + $options = array(); + $this->requestStack = $request_stack; $this->connection = $connection; - $this->setMetadataBag($metadata_bag); + + // Register the default session handler. + // @todo Extract session storage from session handler into a service. + $save_handler = new SessionHandler($this, $this->requestStack, $this->connection); + $write_check_handler = new WriteCheckSessionHandler($save_handler); + $this->setSaveHandler($write_check_handler); + + parent::__construct($options, $write_check_handler, $metadata_bag); $this->setMixedMode($settings->get('mixed_mode_sessions', FALSE)); @@ -108,14 +116,12 @@ public function __construct(RequestStack $request_stack, Connection $connection, /** * {@inheritdoc} */ - public function initialize() { + public function startLazy() { global $user; - // Register the default session handler. - // @todo Extract session storage from session handler into a service. - $save_handler = new SessionHandler($this, $this->requestStack, $this->connection); - $write_check_handler = new WriteCheckSessionHandler($save_handler); - $this->setSaveHandler($write_check_handler); + if (($this->started || $this->startedLazy) && !$this->closed) { + return $this->started; + } $is_https = $this->requestStack->getCurrentRequest()->isSecure(); $cookies = $this->requestStack->getCurrentRequest()->cookies; @@ -125,7 +131,7 @@ public function initialize() { // session is only started on demand in save(), making // anonymous users not use a session cookie unless something is stored in // $_SESSION. This allows HTTP proxies to cache anonymous pageviews. - $this->start(); + $result = $this->start(); if ($user->isAuthenticated() || !$this->isSessionObsolete()) { drupal_page_is_cacheable(FALSE); } @@ -135,17 +141,26 @@ public function initialize() { // we lazily start sessions at the end of this request, and some // processes (like drupal_get_token()) needs to know the future // session ID in advance. - $this->lazySession = TRUE; $user = new AnonymousUserSession(); $this->setId(Crypt::randomBytesBase64()); if ($is_https && $this->isMixedMode()) { $session_id = Crypt::randomBytesBase64(); $cookies->set($insecure_session_name, $session_id); } + $result = FALSE; } date_default_timezone_set(drupal_get_user_timezone()); - return $this; + $this->startedLazy = TRUE; + + return $result; + } + + /** + * {@inheritdoc} + */ + public function isStartedLazy() { + return $this->startedLazy; } /** @@ -174,7 +189,7 @@ public function start() { public function save() { global $user; - if (!$this->isEnabled()) { + if (!$this->isEnabled() || $this->isCli()) { // We don't have anything to do if we are not allowed to save the session. return; } @@ -189,7 +204,7 @@ public function save() { else { // There is session data to store. Start the session if it is not already // started. - if (!$this->isStarted()) { + if (!$this->getSaveHandler()->isActive()) { $this->start(); if ($this->requestStack->getCurrentRequest()->isSecure() && $this->isMixedMode()) { $insecure_session_name = $this->getInsecureName(); @@ -202,6 +217,8 @@ public function save() { // Write the session data. parent::save(); } + + $this->startedLazy = FALSE; } /** @@ -211,7 +228,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) { global $user; // Nothing to do if we are not allowed to change the session. - if (!$this->isEnabled()) { + if (!$this->isEnabled() || $this->isCli()) { return; } @@ -226,7 +243,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) { if ($is_https && $this->isMixedMode()) { $insecure_session_name = $this->getInsecureName(); - if (!isset($this->lazySession) && $cookies->has($insecure_session_name)) { + if ($this->isStarted() && $cookies->has($insecure_session_name)) { $old_insecure_session_id = $cookies->get($insecure_session_name); } $params = session_get_cookie_params(); @@ -294,7 +311,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) { */ public function delete($uid) { // Nothing to do if we are not allowed to change the session. - if (!$this->isEnabled()) { + if (!$this->isEnabled() || $this->isCli()) { return; } $this->connection->delete('sessions') diff --git a/core/lib/Drupal/Core/Session/SessionManagerInterface.php b/core/lib/Drupal/Core/Session/SessionManagerInterface.php index dc9aa4050ad28df98008bdf5288a609c1b60c6fb..e7ea14d3f58f43437ac9fd1e76bb26c27a534f07 100644 --- a/core/lib/Drupal/Core/Session/SessionManagerInterface.php +++ b/core/lib/Drupal/Core/Session/SessionManagerInterface.php @@ -15,11 +15,20 @@ interface SessionManagerInterface extends SessionStorageInterface { /** - * Initializes the session handler, starting a session if needed. + * Starts a session if appropriate cookies are on the request. * - * @return $this + * @return bool + * TRUE if the session was started. + */ + public function startLazy(); + + /** + * Determines whether the session was started lazily. + * + * @return bool + * TRUE if the session was started lazily. */ - public function initialize(); + public function isStartedLazy(); /** * Ends a specific user's session(s). diff --git a/core/update.php b/core/update.php index c7122d0035d606b49d1311ae1e36612bd76b16c4..f2be90de417f3e23d7723846187d497d2f560077 100644 --- a/core/update.php +++ b/core/update.php @@ -323,7 +323,7 @@ function update_task_list($active = NULL) { $kernel->prepareLegacyRequest($request); // Determine if the current user has access to run update.php. -\Drupal::service('session_manager')->initialize(); +\Drupal::service('session_manager')->startLazy(); // Ensure that URLs generated for the home and admin pages don't have 'update.php' // in them.