Skip to content
Permalink
Browse files

Move body serialization into the Request.

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 2e5201523d914d2102b06015902272955bfc1d8b
@@ -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();
}
/**
@@ -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,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;
@@ -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]));
@@ -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
*

0 comments on commit 2e52015

Please sign in to comment.
You can’t perform that action at this time.