Skip to content
Permalink
Browse files

Start making Http\Client\Response PSR7 compatible.

Shuffle code and properties around to make client responses compatible
with PSR7.
  • Loading branch information...
markstory committed May 12, 2016
1 parent 010f727 commit 3f58c7d61d1c9e50bfe9918b3ef9f1555710fa26
Showing with 140 additions and 73 deletions.
  1. +1 −33 src/Http/Client/Message.php
  2. +111 −39 src/Http/Client/Response.php
  3. +28 −1 tests/TestCase/Network/Http/ResponseTest.php
@@ -127,34 +127,13 @@ class Message
*/
const METHOD_HEAD = 'HEAD';
/**
* The array of headers in the response.
*
* @var array
*/
protected $_headers = [];
/**
* The array of cookies in the response.
*
* @var array
*/
protected $_cookies = [];
/**
* Normalize header names to Camel-Case form.
*
* @param string $name The header name to normalize.
* @return string Normalized header name.
*/
protected function _normalizeHeader($name)
{
$parts = explode('-', trim($name));
$parts = array_map('strtolower', $parts);
$parts = array_map('ucfirst', $parts);
return implode('-', $parts);
}
/**
* Get all headers
*
@@ -163,7 +142,7 @@ protected function _normalizeHeader($name)
*/
public function headers()
{
return $this->_headers;
return $this->headers;
}
/**
@@ -176,17 +155,6 @@ public function cookies()
return $this->_cookies;
}
/**
* Get the HTTP version used.
*
* @return string
* @deprecated 3.3.0 Use getProtocolVersion()
*/
public function version()
{
return $this->protocol;
}
/**
* Get/set the body for the message.
*
@@ -13,7 +13,10 @@
*/
namespace Cake\Http\Client;
use Psr\Http\Message\ResponseInterface;
use RuntimeException;
use Zend\Diactoros\MessageTrait;
use Zend\Diactoros\Stream;
/**
* Implements methods for HTTP responses.
@@ -87,28 +90,23 @@
* $content = $response->code;
* ```
*/
class Response extends Message
class Response extends Message implements ResponseInterface
{
/**
* This is temporary until the response is made PSR7 compliant as well.
*
* @var string
*/
protected $protocol = '1.1';
use MessageTrait;
/**
* The status code of the response.
*
* @var int
*/
protected $_code;
protected $code;
/**
* The response body
* The reason phrase for the status code
*
* @var string
*/
protected $_body;
protected $reasonPhrase;
/**
* Cached decoded XML data.
@@ -131,11 +129,11 @@ class Response extends Message
*/
protected $_exposedProperties = [
'cookies' => '_cookies',
'headers' => '_headers',
'body' => '_body',
'code' => '_code',
'body' => '_getBody',
'code' => 'code',
'json' => '_getJson',
'xml' => '_getXml'
'xml' => '_getXml',
'headers' => '_getHeaders',
];
/**
@@ -147,10 +145,12 @@ class Response extends Message
public function __construct($headers = [], $body = '')
{
$this->_parseHeaders($headers);
if ($this->header('Content-Encoding') === 'gzip') {
if ($this->getHeaderLine('Content-Encoding') === 'gzip') {
$body = $this->_decodeGzipBody($body);
}
$this->_body = $body;
$stream = new Stream('php://memory', 'wb+');
$stream->write($body);
$this->stream = $stream;
}
/**
@@ -182,7 +182,7 @@ protected function _decodeGzipBody($body)
/**
* Parses headers if necessary.
*
* - Decodes the status code.
* - Decodes the status code and reasonphrase.
* - Parses and normalizes header names + values.
*
* @param array $headers Headers to parse.
@@ -192,22 +192,26 @@ protected function _parseHeaders($headers)
{
foreach ($headers as $key => $value) {
if (substr($value, 0, 5) === 'HTTP/') {
preg_match('/HTTP\/([\d.]+) ([0-9]+)/i', $value, $matches);
preg_match('/HTTP\/([\d.]+) ([0-9]+)(.*)/i', $value, $matches);
$this->protocol = $matches[1];
$this->_code = $matches[2];
$this->code = $matches[2];
$this->reasonPhrase = trim($matches[3]);
continue;
}
list($name, $value) = explode(':', $value, 2);
$value = trim($value);
$name = $this->_normalizeHeader($name);
if ($name === 'Set-Cookie') {
$name = trim($name);
$normalized = strtolower($name);
if ($normalized === 'set-cookie') {
$this->_parseCookie($value);
}
if (isset($this->_headers[$name])) {
$this->_headers[$name] = (array)$this->_headers[$name];
$this->_headers[$name][] = $value;
if (isset($this->headers[$name])) {
$this->headers[$name][] = $value;
} else {
$this->_headers[$name] = $value;
$this->headers[$name] = (array)$value;
$this->headerNames[$normalized] = $name;
}
}
}
@@ -264,7 +268,7 @@ public function isOk()
static::STATUS_CREATED,
static::STATUS_ACCEPTED
];
return in_array($this->_code, $codes);
return in_array($this->code, $codes);
}
/**
@@ -281,19 +285,47 @@ public function isRedirect()
static::STATUS_TEMPORARY_REDIRECT,
];
return (
in_array($this->_code, $codes) &&
$this->header('Location')
in_array($this->code, $codes) &&
$this->getHeaderLine('Location')
);
}
/**
* Get the status code from the response
*
* @return int
* @deprecated 3.3.0 Use getStatusCode() instead.
*/
public function statusCode()
{
return $this->_code;
return $this->code;
}
/**
* {@inheritdoc}
*/
public function getStatusCode()
{
return $this->code;
}
/**
* {@inheritdoc}
*/
public function withStatus($code, $reasonPhrase = '')
{
$new = clone $this;
$new->code = $code;
$new->reasonPhrase = $reasonPhrase;
return $new;
}
/**
* {@inheritdoc}
*/
public function getReasonPhrase()
{
return $this->reasonPhrase;
}
/**
@@ -303,7 +335,7 @@ public function statusCode()
*/
public function encoding()
{
$content = $this->header('content-type');
$content = $this->getHeaderLine('content-type');
if (!$content) {
return null;
}
@@ -323,17 +355,18 @@ public function encoding()
* will be returned when getting all headers or when getting
* a header that had multiple values set. Otherwise a string
* will be returned.
* @deprecated 3.3.0 Use getHeader() and getHeaderLine() instead.
*/
public function header($name = null)
{
if ($name === null) {
return $this->_headers;
return $this->_getHeaders();
}
$name = $this->_normalizeHeader($name);
if (!isset($this->_headers[$name])) {
return null;
$header = $this->getHeader($name);
if (count($header) === 1) {
return $header[0];
}
return $this->_headers[$name];
return $header;
}
/**
@@ -359,6 +392,17 @@ public function cookie($name = null, $all = false)
return $this->_cookies[$name]['value'];
}
/**
* Get the HTTP version used.
*
* @return string
* @deprecated 3.3.0 Use getProtocolVersion()
*/
public function version()
{
return $this->protocol;
}
/**
* Get the response body.
*
@@ -377,10 +421,12 @@ public function cookie($name = null, $all = false)
*/
public function body($parser = null)
{
$stream = $this->stream;
$stream->rewind();
if ($parser) {
return $parser($this->_body);
return $parser($stream->getContents());
}
return $this->_body;
return $stream->getContents();
}
/**
@@ -393,7 +439,7 @@ protected function _getJson()
if (!empty($this->_json)) {
return $this->_json;
}
return $this->_json = json_decode($this->_body, true);
return $this->_json = json_decode($this->_getBody(), true);
}
/**
@@ -407,14 +453,40 @@ protected function _getXml()
return $this->_xml;
}
libxml_use_internal_errors();
$data = simplexml_load_string($this->_body);
$data = simplexml_load_string($this->_getBody());
if ($data) {
$this->_xml = $data;
return $this->_xml;
}
return null;
}
/**
* Provides magic __get() support.
*
* @return array
*/
protected function _getHeaders()
{
$out = [];
foreach ($this->headers as $key => $values) {
$out[$key] = implode(',', $values);
}
return $out;
}
/**
* Provides magic __get() support.
*
* @return array
*/
protected function _getBody()
{
$this->stream->rewind();
return $this->stream->getContents();
}
/**
* Read values as properties.
*
Oops, something went wrong.

0 comments on commit 3f58c7d

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