Problem/Motivation
Persistent workers such as FrankenPHP worker mode can reuse the session_manager service across requests. SessionManager::destroy() calls session_destroy() but leaves started set to TRUE and closed set to FALSE. On the next request, SessionManager::start() returns early: it does not apply the new request's session options, reinitialize $_SESSION, or reattach the session bags. NativeSessionStorage::start() also returns early because started is TRUE, so session_start() never runs. This silently breaks logging in.
Steps to reproduce
- Start a session using an incoming session cookie.
- Destroy the session directly, or leave it empty and save it to trigger obsolete-session destruction.
- Unset
$_SESSIONand reuse the same session storage for another request. - Start the session, set a value, and save it.
Expected: after step 2, isStarted() returns FALSE. In step 4, the value is written through the session handler.
Actual: after step 2, isStarted() returns TRUE although no PHP session is active. In step 4, the value is not written to $_SESSION and the handler's write() is never called.
Proposed resolution
After session_destroy(), set started and startedLazy to FALSE and closed to TRUE. started and closed match the state NativeSessionStorage::save() leaves after closing a session. startedLazy is Drupal's own flag and must also be reset.
User interface changes
None.
API changes
None.
Data model changes
None.
AI disclosure: I used AI to help prepare the IS and MR (Astra and Opus 5.5).
Issue fork drupal-3626371
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
ptmkenny commentedComment #4
ptmkenny commented