Browse Source

Don't double parse request body.

If the request only contains a parsed body don't re-parse it.
This lets the middleware and component play nicer together.
Mark Story 8 years ago
parent
commit
b036c58dec

+ 3 - 0
src/Controller/Component/RequestHandlerComponent.php

@@ -212,6 +212,9 @@ class RequestHandlerComponent extends Component
             return;
         }
 
+        if ($request->getParsedBody() !== []) {
+            return;
+        }
         foreach ($this->getConfig('inputTypeMap') as $type => $handler) {
             if (!is_callable($handler[0])) {
                 throw new RuntimeException(sprintf("Invalid callable for '%s' type.", $type));

+ 47 - 1
tests/TestCase/Controller/Component/RequestHandlerComponentTest.php

@@ -568,7 +568,7 @@ class RequestHandlerComponentTest extends TestCase
      * @return void
      * @triggers Controller.startup $this->Controller
      */
-    public function testStartupProcessData()
+    public function testStartupProcessDataInvalid()
     {
         $this->Controller->request = new ServerRequest([
             'environment' => [
@@ -586,10 +586,28 @@ class RequestHandlerComponentTest extends TestCase
         $this->Controller->request = $this->Controller->request->withBody($stream);
         $this->RequestHandler->startup($event);
         $this->assertEquals(['invalid'], $this->Controller->request->getData());
+    }
+
+    /**
+     * Test that processing data results in an array.
+     *
+     * @return void
+     * @triggers Controller.startup $this->Controller
+     */
+    public function testStartupProcessData()
+    {
+        $this->Controller->request = new ServerRequest([
+            'environment' => [
+                'REQUEST_METHOD' => 'POST',
+                'CONTENT_TYPE' => 'application/json'
+            ]
+        ]);
 
         $stream = new Stream('php://memory', 'w');
         $stream->write('{"valid":true}');
         $this->Controller->request = $this->Controller->request->withBody($stream);
+        $event = new Event('Controller.startup', $this->Controller);
+
         $this->RequestHandler->startup($event);
         $this->assertEquals(['valid' => true], $this->Controller->request->getData());
     }
@@ -738,6 +756,34 @@ XML;
     }
 
     /**
+     * Test that data isn't processed when parsed data already exists.
+     *
+     * @return void
+     * @triggers Controller.startup $this->Controller
+     */
+    public function testStartupSkipDataProcess()
+    {
+        $this->Controller->request = new ServerRequest([
+            'environment' => [
+                'REQUEST_METHOD' => 'POST',
+                'CONTENT_TYPE' => 'application/json'
+            ]
+        ]);
+
+        $event = new Event('Controller.startup', $this->Controller);
+        $this->RequestHandler->startup($event);
+        $this->assertEquals([], $this->Controller->request->getData());
+
+        $stream = new Stream('php://memory', 'w');
+        $stream->write('{"new": "data"}');
+        $this->Controller->request = $this->Controller->request
+            ->withBody($stream)
+            ->withParsedBody(['old' => 'news']);
+        $this->RequestHandler->startup($event);
+        $this->assertEquals(['old' => 'news'], $this->Controller->request->getData());
+    }
+
+    /**
      * test beforeRedirect when disabled.
      *
      * @return void