Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Reopen sessions if we need to write to them instead of keeping them open
Sessions are a locking operation until we write close them, so close
them early and reopen later in case we want to write to them

Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Aug 17, 2022
commit 9b4b72826ade5ab1bc7fb06048e62910ef607cd8
1 change: 1 addition & 0 deletions lib/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ public static function initSession() {
}

$session->set('LAST_ACTIVITY', time());
$session->close();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions lib/private/AppFramework/Middleware/SessionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ public function __construct(ControllerMethodReflector $reflector,
*/
public function beforeController($controller, $methodName) {
$useSession = $this->reflector->hasAnnotation('UseSession');
if (!$useSession) {
$this->session->close();
if ($useSession) {
$this->session->reopen();
}
}

Expand Down
17 changes: 17 additions & 0 deletions lib/private/Session/CryptoSessionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,17 @@ protected function initializeSession() {
* @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();
}
}

/**
Expand Down Expand Up @@ -131,9 +140,13 @@ public function exists(string $key): bool {
* @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();
}
}

/**
Expand All @@ -149,6 +162,10 @@ public function clear() {
$this->session->clear();
}

public function reopen(): bool {
return $this->session->reopen();
}

/**
* Wrapper around session_regenerate_id
*
Expand Down
17 changes: 14 additions & 3 deletions lib/private/Session/Internal.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,11 @@ public function __construct(string $name) {
* @param integer $value
*/
public function set(string $key, $value) {
$this->validateSession();
$reopened = $this->reopen();
$_SESSION[$key] = $value;
if ($reopened) {
$this->close();
}
}

/**
Expand Down Expand Up @@ -101,6 +104,7 @@ public function remove(string $key) {
}

public function clear() {
$this->reopen();
$this->invoke('session_unset');
$this->regenerateId();
$this->startSession(true);
Expand All @@ -120,6 +124,7 @@ public function close() {
* @return void
*/
public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) {
$this->reopen();
$oldId = null;

if ($updateToken) {
Expand Down Expand Up @@ -171,8 +176,14 @@ public function getId(): string {
/**
* @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;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions lib/private/Session/Memory.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public function __construct(string $name) {
* @param integer $value
*/
public function set(string $key, $value) {
$this->validateSession();
$this->data[$key] = $value;
}

Expand All @@ -80,7 +79,6 @@ public function exists(string $key): bool {
* @param string $key
*/
public function remove(string $key) {
$this->validateSession();
unset($this->data[$key]);
}

Expand Down Expand Up @@ -110,8 +108,10 @@ public function getId(): string {
/**
* 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;
}

/**
Expand Down
8 changes: 8 additions & 0 deletions lib/public/ISession.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ public function remove(string $key);
*/
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
Expand Down