Skip to content

Commit

Permalink
Move body serialization into the Request.
Browse files Browse the repository at this point in the history
When using the mutable body() method, an array based body should be
serialized. I think this makes more sense than doing it in the transport
adapter. This does change the semantics of the body() method but I think
in an acceptable way.
  • Loading branch information
markstory committed May 7, 2016
1 parent 11e6529 commit 2e52015
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 29 deletions.
25 changes: 7 additions & 18 deletions src/Http/Client/Adapter/Stream.php
Expand Up @@ -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 = [];
Expand All @@ -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();
}

/**
Expand Down
21 changes: 11 additions & 10 deletions src/Http/Client/Request.php
Expand Up @@ -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'
];
]);
}

/**
Expand Down Expand Up @@ -205,21 +201,26 @@ 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)
{
if ($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;
Expand Down
3 changes: 2 additions & 1 deletion tests/TestCase/Network/Http/ClientTest.php
Expand Up @@ -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.
Expand Down Expand Up @@ -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]));

Expand Down
22 changes: 22 additions & 0 deletions tests/TestCase/Network/Http/RequestTest.php
Expand Up @@ -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
*
Expand Down

0 comments on commit 2e52015

Please sign in to comment.