diff options
-rw-r--r-- | lib/base.php | 1 | ||||
-rw-r--r-- | lib/private/AppFramework/Middleware/SessionMiddleware.php | 4 | ||||
-rw-r--r-- | lib/private/Session/CryptoSessionData.php | 17 | ||||
-rw-r--r-- | lib/private/Session/Internal.php | 17 | ||||
-rw-r--r-- | lib/private/Session/Memory.php | 6 | ||||
-rw-r--r-- | lib/public/ISession.php | 8 |
6 files changed, 45 insertions, 8 deletions
diff --git a/lib/base.php b/lib/base.php index 54b7a5e3629..e787559c4c1 100644 --- a/lib/base.php +++ b/lib/base.php @@ -456,6 +456,7 @@ class OC { } $session->set('LAST_ACTIVITY', time()); + $session->close(); } /** diff --git a/lib/private/AppFramework/Middleware/SessionMiddleware.php b/lib/private/AppFramework/Middleware/SessionMiddleware.php index f3fd2c99173..32ac2b17ae5 100644 --- a/lib/private/AppFramework/Middleware/SessionMiddleware.php +++ b/lib/private/AppFramework/Middleware/SessionMiddleware.php @@ -51,8 +51,8 @@ class SessionMiddleware extends Middleware { */ public function beforeController($controller, $methodName) { $useSession = $this->reflector->hasAnnotation('UseSession'); - if (!$useSession) { - $this->session->close(); + if ($useSession) { + $this->session->reopen(); } } diff --git a/lib/private/Session/CryptoSessionData.php b/lib/private/Session/CryptoSessionData.php index 2e3bd46da5b..b01887e39e2 100644 --- a/lib/private/Session/CryptoSessionData.php +++ b/lib/private/Session/CryptoSessionData.php @@ -97,8 +97,17 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @param mixed $value */ public function set(string $key, $value) { + if ($this->get($key) === $value) { + // Do not write the session if the value hasn't changed to avoid reopening + return; + } + + $reopened = $this->reopen(); $this->sessionValues[$key] = $value; $this->isModified = true; + if ($reopened) { + $this->close(); + } } /** @@ -131,9 +140,13 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @param string $key */ public function remove(string $key) { + $reopened = $this->reopen(); $this->isModified = true; unset($this->sessionValues[$key]); $this->session->remove(self::encryptedSessionName); + if ($reopened) { + $this->close(); + } } /** @@ -149,6 +162,10 @@ class CryptoSessionData implements \ArrayAccess, ISession { $this->session->clear(); } + public function reopen(): bool { + return $this->session->reopen(); + } + /** * Wrapper around session_regenerate_id * diff --git a/lib/private/Session/Internal.php b/lib/private/Session/Internal.php index 6e0c54c6fab..f192b20cc95 100644 --- a/lib/private/Session/Internal.php +++ b/lib/private/Session/Internal.php @@ -68,8 +68,11 @@ class Internal extends Session { * @param integer $value */ public function set(string $key, $value) { - $this->validateSession(); + $reopened = $this->reopen(); $_SESSION[$key] = $value; + if ($reopened) { + $this->close(); + } } /** @@ -101,6 +104,7 @@ class Internal extends Session { } public function clear() { + $this->reopen(); $this->invoke('session_unset'); $this->regenerateId(); $this->startSession(true); @@ -120,6 +124,7 @@ class Internal extends Session { * @return void */ public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) { + $this->reopen(); $oldId = null; if ($updateToken) { @@ -171,8 +176,14 @@ class Internal extends Session { /** * @throws \Exception */ - public function reopen() { - throw new \Exception('The session cannot be reopened - reopen() is only to be used in unit testing.'); + public function reopen(): bool { + if ($this->sessionClosed) { + $this->startSession(); + $this->sessionClosed = false; + return true; + } + + return false; } /** diff --git a/lib/private/Session/Memory.php b/lib/private/Session/Memory.php index 0afd3703366..b9b3dba54b7 100644 --- a/lib/private/Session/Memory.php +++ b/lib/private/Session/Memory.php @@ -53,7 +53,6 @@ class Memory extends Session { * @param integer $value */ public function set(string $key, $value) { - $this->validateSession(); $this->data[$key] = $value; } @@ -80,7 +79,6 @@ class Memory extends Session { * @param string $key */ public function remove(string $key) { - $this->validateSession(); unset($this->data[$key]); } @@ -110,8 +108,10 @@ class Memory extends Session { /** * Helper function for PHPUnit execution - don't use in non-test code */ - public function reopen() { + public function reopen(): bool { + $reopened = $this->sessionClosed; $this->sessionClosed = false; + return $reopened; } /** diff --git a/lib/public/ISession.php b/lib/public/ISession.php index 2709e09d4ca..12cd716ec3f 100644 --- a/lib/public/ISession.php +++ b/lib/public/ISession.php @@ -84,6 +84,14 @@ interface ISession { public function clear(); /** + * Reopen a session for writing again + * + * @return bool true if the session was actually reopened, otherwise false + * @since 25.0.0 + */ + public function reopen(): bool; + + /** * Close the session and release the lock * @since 7.0.0 */ |