Browse Source

Increase session gc lifetime

When sessions have serverside timeouts disabled we should set a longer
session.gc_maxlifetime option as using 0 could result in all sessions
being reaped when a GC sweep is done.

Refs #17513
Mark Story 2 years ago
parent
commit
eaa3c74f5f
2 changed files with 27 additions and 2 deletions
  1. 8 2
      src/Http/Session.php
  2. 19 0
      tests/TestCase/Http/SessionTest.php

+ 8 - 2
src/Http/Session.php

@@ -220,8 +220,14 @@ class Session
             'handler' => [],
         ];
 
-        if ($config['timeout']) {
-            $config['ini']['session.gc_maxlifetime'] = 60 * $config['timeout'];
+        if (isset($config['timeout']) && !isset($config['ini']['session.gc_maxlifetime'])) {
+            $maxlifetime = $config['timeout'] * 60;
+            if ($maxlifetime === 0) {
+                // If sessions are set to have no idle timeout, extend the
+                // gc_maxlifetime to 30 days so that sessions don't get reaped immediately
+                $maxlifetime = 60 * 60 * 24 * 30;
+            }
+            $config['ini']['session.gc_maxlifetime'] = $maxlifetime;
         }
 
         if ($config['cookie']) {

+ 19 - 0
tests/TestCase/Http/SessionTest.php

@@ -65,6 +65,25 @@ class SessionTest extends TestCase
     }
 
     /**
+     * test setting ini properties with Session configuration.
+     *
+     * @preserveGlobalState disabled
+     * @runInSeparateProcess
+     */
+    public function testSessionConfigTimeout(): void
+    {
+        $_SESSION = null;
+
+        $config = [
+            'defaults' => 'php',
+            'timeout' => 0,
+        ];
+
+        Session::create($config);
+        $this->assertEquals(60 * 60 * 24 * 30, ini_get('session.gc_maxlifetime'), 'Ini value is incorrect');
+    }
+
+    /**
      * test session cookie path setting
      *
      * @preserveGlobalState disabled