diff --git a/src/Http/Client/Adapter/Stream.php b/src/Http/Client/Adapter/Stream.php index 1b2ddce0873..9619429c923 100644 --- a/src/Http/Client/Adapter/Stream.php +++ b/src/Http/Client/Adapter/Stream.php @@ -145,8 +145,8 @@ protected function _buildContext(Request $request, $options) protected function _buildHeaders(Request $request, $options) { $headers = []; - foreach ($request->headers() as $name => $value) { - $headers[] = "$name: $value"; + foreach ($request->getHeaders() as $name => $values) { + $headers[] = sprintf('%s: %s', $name, implode(", ", $values)); } $cookies = []; @@ -171,23 +171,12 @@ protected function _buildHeaders(Request $request, $options) */ protected function _buildContent(Request $request, $options) { - $content = $request->body(); - if (empty($content)) { - return; + $body = $request->getBody(); + if (empty($body)) { + return $this->_contextOptions['content'] = ''; } - if (is_string($content)) { - $this->_contextOptions['content'] = $content; - return; - } - if (is_array($content)) { - $formData = new FormData(); - $formData->addMany($content); - $type = $formData->contentType(); - $request->header('Content-Type', $type); - $this->_contextOptions['content'] = (string)$formData; - return; - } - $this->_contextOptions['content'] = $content; + $body->rewind(); + $this->_contextOptions['content'] = $body->getContents(); } /** diff --git a/src/Http/Client/Request.php b/src/Http/Client/Request.php index 9edcd23ffda..398158b27f9 100644 --- a/src/Http/Client/Request.php +++ b/src/Http/Client/Request.php @@ -39,14 +39,10 @@ public function __construct() { $this->method = static::METHOD_GET; - $this->headerNames = [ - 'connection' => 'Connection', - 'user-agent' => 'User-Agent', - ]; - $this->headers = [ + $this->header([ 'Connection' => 'close', 'User-Agent' => 'CakePHP' - ]; + ]); } /** @@ -205,14 +201,13 @@ public function version($version = null) } /** - * Get/set the body for the message. + * Get/set the body/payload for the message. * - * *Warning* This method mutates the request in-place for backwards - * compatibility reasons, and is not part of the PSR7 interface. + * Array data will be serialized with Cake\Http\FormData, + * and the content-type will be set. * * @param string|null $body The body for the request. Leave null for get * @return mixed Either $this or the body value. - * @deprecated 3.3.0 use getBody() and withBody() instead. */ public function body($body = null) { @@ -220,6 +215,12 @@ public function body($body = null) $body = $this->getBody(); return $body ? $body->__toString() : ''; } + if (is_array($body)) { + $formData = new FormData(); + $formData->addMany($body); + $this->header('Content-Type', $formData->contentType()); + $body = (string)$formData; + } $stream = new Stream('php://memory', 'rw'); $stream->write($body); $this->stream = $stream; diff --git a/tests/TestCase/Network/Http/ClientTest.php b/tests/TestCase/Network/Http/ClientTest.php index e2092dc2583..5a0568efb76 100644 --- a/tests/TestCase/Network/Http/ClientTest.php +++ b/tests/TestCase/Network/Http/ClientTest.php @@ -17,6 +17,7 @@ use Cake\Network\Http\Request; use Cake\Network\Http\Response; use Cake\TestSuite\TestCase; +use Zend\Diactoros\Uri; /** * HTTP client test. @@ -369,7 +370,7 @@ public function testMethodsSimple($method) ->with($this->logicalAnd( $this->isInstanceOf('Cake\Network\Http\Request'), $this->attributeEqualTo('method', $method), - $this->attributeEqualTo('_url', 'http://cakephp.org/projects/add') + $this->attributeEqualTo('url', new Uri('http://cakephp.org/projects/add')) )) ->will($this->returnValue([$response])); diff --git a/tests/TestCase/Network/Http/RequestTest.php b/tests/TestCase/Network/Http/RequestTest.php index b4f44ac56a3..07b4e75f92c 100644 --- a/tests/TestCase/Network/Http/RequestTest.php +++ b/tests/TestCase/Network/Http/RequestTest.php @@ -111,6 +111,28 @@ public function testBody() $this->assertEquals($data, $request->body()); } + /** + * test body method with array payload + * + * @return void + */ + public function testBodyArray() + { + $request = new Request(); + $data = [ + 'a' => 'b', + 'c' => 'd', + 'e' => ['f', 'g'] + ]; + $request->body($data); + $this->assertEquals('application/x-www-form-urlencoded', $request->getHeaderLine('content-type')); + $this->assertEquals( + 'a=b&c=d&e%5B0%5D=f&e%5B1%5D=g', + $request->body(), + 'Body should be serialized' + ); + } + /** * Test that body() modifies the PSR7 stream *