Browse Source

Don't eagerly call callback responses.

Don't eagerly evaluate callback/streaming responses. This can result in
allocating a pile of memory too soon in the request. Instead it is
preferrable to allocate that memory when we're flushing to the SAPI.
Mark Story 9 years ago
parent
commit
4fc472d9a7
2 changed files with 11 additions and 15 deletions
  1. 11 14
      src/Network/Response.php
  2. 0 1
      tests/TestCase/Network/ResponseTest.php

+ 11 - 14
src/Network/Response.php

@@ -16,6 +16,7 @@ namespace Cake\Network;
 
 use Cake\Core\Configure;
 use Cake\Filesystem\File;
+use Cake\Http\CallbackStream;
 use Cake\Log\Log;
 use Cake\Network\Exception\NotFoundException;
 use DateTime;
@@ -739,30 +740,26 @@ class Response implements ResponseInterface
     public function body($content = null)
     {
         if ($content === null) {
-            $this->stream->rewind();
+            if ($this->stream->isSeekable()) {
+                $this->stream->rewind();
+            }
             $result = $this->stream->getContents();
-            if (empty($result) && strlen($result) === 0) {
+            if (strlen($result) === 0) {
                 return null;
             }
 
             return $result;
         }
 
-        // BC compatibility
+        // Compatibility with closure/streaming responses
         if (is_callable($content)) {
-            $content = $this->_handleCallableBody($content);
-        }
-
-        $this->_createStream();
-        $this->stream->write($content);
-        $this->stream->rewind();
-        $result = $this->stream->getContents();
-
-        if (empty($result) && strlen($result) === 0) {
-            return null;
+            $this->stream = new CallbackStream($content);
+        } else {
+            $this->_createStream();
+            $this->stream->write($content);
         }
 
-        return $result;
+        return $content;
     }
 
     /**

+ 0 - 1
tests/TestCase/Network/ResponseTest.php

@@ -2350,5 +2350,4 @@ class ResponseTest extends TestCase
         $this->assertFalse($response->hasHeader('Accept'));
         $this->assertFalse($response->hasHeader('accept'));
     }
-
 }