ソースを参照

4.x - Explicit write & close of the session
- so that any exceptions in session write go through regular error handling process
- see #13581 for details

Ján Súkeník 6 年 前
コミット
6a2c9767d7
3 ファイル変更40 行追加7 行削除
  1. 0 4
      src/Http/ResponseEmitter.php
  2. 5 1
      src/Http/Server.php
  3. 35 2
      tests/TestCase/Http/ServerTest.php

+ 0 - 4
src/Http/ResponseEmitter.php

@@ -34,9 +34,6 @@ use Zend\HttpHandlerRunner\Emitter\EmitterInterface;
  *
  * - It logs headers sent using CakePHP's logging tools.
  * - Cookies are emitted using setcookie() to not conflict with ext/session
- * - For fastcgi servers with PHP-FPM session_write_close() is called just
- *   before fastcgi_finish_request() to make sure session data is saved
- *   correctly (especially on slower session backends).
  */
 class ResponseEmitter implements EmitterInterface
 {
@@ -87,7 +84,6 @@ class ResponseEmitter implements EmitterInterface
         }
 
         if (function_exists('fastcgi_finish_request')) {
-            session_write_close();
             fastcgi_finish_request();
         }
 

+ 5 - 1
src/Http/Server.php

@@ -87,7 +87,11 @@ class Server implements EventDispatcherInterface
 
         $this->dispatchEvent('Server.buildMiddleware', ['middleware' => $middleware]);
 
-        return $this->runner->run($middleware, $request, $this->app);
+        $response = $this->runner->run($middleware, $request, $this->app);
+
+        $request->getSession()->close();
+
+        return $response;
     }
 
     /**

+ 35 - 2
tests/TestCase/Http/ServerTest.php

@@ -24,6 +24,7 @@ use Cake\Http\CallbackStream;
 use Cake\Http\MiddlewareQueue;
 use Cake\Http\Server;
 use Cake\Http\ServerRequest;
+use Cake\Http\Session;
 use Cake\TestSuite\TestCase;
 use InvalidArgumentException;
 use TestApp\Http\MiddlewareApplication;
@@ -42,6 +43,11 @@ class ServerTest extends TestCase
     protected $config;
 
     /**
+     * @var array
+     */
+    private $server;
+
+    /**
      * Setup
      *
      * @return void
@@ -50,7 +56,7 @@ class ServerTest extends TestCase
     {
         parent::setUp();
         $this->server = $_SERVER;
-        $this->config = dirname(dirname(__DIR__));
+        $this->config = dirname(dirname(__DIR__)) . '/test_app/config';
         $GLOBALS['mockedHeaders'] = [];
         $GLOBALS['mockedHeadersSent'] = true;
     }
@@ -120,7 +126,6 @@ class ServerTest extends TestCase
      */
     public function testRunCallingPluginHooks()
     {
-        $response = new Response('php://memory', 200, ['X-testing' => 'source header']);
         $request = new ServerRequest();
         $request = $request->withHeader('X-pass', 'request header');
 
@@ -187,6 +192,34 @@ class ServerTest extends TestCase
     }
 
     /**
+     * Test that run closes session after invoking the application.
+     */
+    public function testRunClosesSession()
+    {
+        $sessionMock = $this->createMock(Session::class);
+
+        $sessionMock->expects($this->once())
+            ->method('close');
+
+        $app = new MiddlewareApplication($this->config);
+        $server = new Server($app);
+        $request = new ServerRequest(['session' => $sessionMock]);
+        $res = $server->run($request);
+
+        // assert that app was executed correctly
+        $this->assertSame(
+            200,
+            $res->getStatusCode(),
+            "Application was expected to be executed"
+        );
+        $this->assertSame(
+            'source header',
+            $res->getHeaderLine('X-testing'),
+            "Application was expected to be executed"
+        );
+    }
+
+    /**
      * Test that emit invokes the appropriate methods on the emitter.
      *
      * @return void