From 60a9d34027d9ab1d822fb75bcefe2c87bac7e4cf Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 14 Dec 2010 01:07:25 -0200 Subject: [PATCH] Updated the HttpSocket to use the new HttpResponse. --- cake/libs/http_socket.php | 99 +++++++------------ cake/tests/cases/libs/http_socket.test.php | 110 +++++++++------------ 2 files changed, 81 insertions(+), 128 deletions(-) diff --git a/cake/libs/http_socket.php b/cake/libs/http_socket.php index 5c58745c604..aa4769319d0 100644 --- a/cake/libs/http_socket.php +++ b/cake/libs/http_socket.php @@ -19,6 +19,7 @@ */ App::import('Core', 'CakeSocket'); App::import('Core', 'Router'); +App::import('Lib', 'HttpResponse'); /** * Cake network socket connection class. @@ -73,22 +74,7 @@ class HttpSocket extends CakeSocket { * * @var array */ - public $response = array( - 'raw' => array( - 'status-line' => null, - 'header' => null, - 'body' => null, - 'response' => null - ), - 'status' => array( - 'http-version' => null, - 'code' => null, - 'reason-phrase' => null - ), - 'header' => array(), - 'body' => '', - 'cookies' => array() - ); + public $response = null; /** * Configuration settings for the HttpSocket and the requests @@ -238,16 +224,15 @@ public function setContentResource($resource) { * method and provide a more granular interface. * * @param mixed $request Either an URI string, or an array defining host/uri - * @return mixed null on error, reference to request body on success + * @return mixed false on error, HttpResponse on success */ - public function &request($request = array()) { + public function request($request = array()) { $this->reset(false); if (is_string($request)) { $request = array('uri' => $request); } elseif (!is_array($request)) { - $return = false; - return $return; + return false; } if (!isset($request['uri'])) { @@ -338,7 +323,7 @@ public function &request($request = array()) { } if ($this->quirksMode === false && $this->request['line'] === false) { - return $this->response = false; + return false; } $this->request['raw'] = ''; @@ -383,14 +368,14 @@ public function &request($request = array()) { } $this->response = $this->_parseResponse($response); - if (!empty($this->response['cookies'])) { + if (!empty($this->response->cookies)) { if (!isset($this->config['request']['cookies'][$Host])) { $this->config['request']['cookies'][$Host] = array(); } - $this->config['request']['cookies'][$Host] = array_merge($this->config['request']['cookies'][$Host], $this->response['cookies']); + $this->config['request']['cookies'][$Host] = array_merge($this->config['request']['cookies'][$Host], $this->response->cookies); } - return $this->response['body']; + return $this->response; } /** @@ -416,7 +401,7 @@ public function &request($request = array()) { * @param array $request An indexed array with indexes such as 'method' or uri * @return mixed Result of request, either false on failure or the response to the request. */ - public function &get($uri = null, $query = array(), $request = array()) { + public function get($uri = null, $query = array(), $request = array()) { if (!empty($query)) { $uri = $this->_parseUri($uri); if (isset($uri['query'])) { @@ -448,7 +433,7 @@ public function &get($uri = null, $query = array(), $request = array()) { * @param array $request An indexed array with indexes such as 'method' or uri * @return mixed Result of request, either false on failure or the response to the request. */ - public function &post($uri = null, $data = array(), $request = array()) { + public function post($uri = null, $data = array(), $request = array()) { $request = Set::merge(array('method' => 'POST', 'uri' => $uri, 'body' => $data), $request); return $this->request($request); } @@ -461,7 +446,7 @@ public function &post($uri = null, $data = array(), $request = array()) { * @param array $request An indexed array with indexes such as 'method' or uri * @return mixed Result of request */ - public function &put($uri = null, $data = array(), $request = array()) { + public function put($uri = null, $data = array(), $request = array()) { $request = Set::merge(array('method' => 'PUT', 'uri' => $uri, 'body' => $data), $request); return $this->request($request); } @@ -474,7 +459,7 @@ public function &put($uri = null, $data = array(), $request = array()) { * @param array $request An indexed array with indexes such as 'method' or uri * @return mixed Result of request */ - public function &delete($uri = null, $data = array(), $request = array()) { + public function delete($uri = null, $data = array(), $request = array()) { $request = Set::merge(array('method' => 'DELETE', 'uri' => $uri, 'body' => $data), $request); return $this->request($request); } @@ -585,58 +570,40 @@ protected function _setProxy() { * Parses the given message and breaks it down in parts. * * @param string $message Message to parse - * @return array Parsed message (with indexed elements such as raw, status, header, body) + * @return object Parsed message as HttpResponse */ protected function _parseResponse($message) { - if (is_array($message)) { - return $message; - } elseif (!is_string($message)) { - return false; - } - - static $responseTemplate; - - if (empty($responseTemplate)) { - $classVars = get_class_vars(__CLASS__); - $responseTemplate = $classVars['response']; + if (!is_string($message)) { + throw new Exception(__('Invalid response.')); } - $response = $responseTemplate; - if (!preg_match("/^(.+\r\n)(.*)(?<=\r\n)\r\n/Us", $message, $match)) { - return false; + throw new Exception(__('Invalid HTTP response.')); } - list($null, $response['raw']['status-line'], $response['raw']['header']) = $match; - $response['raw']['response'] = $message; - $response['raw']['body'] = substr($message, strlen($match[0])); + $response = new HttpResponse(); - if (preg_match("/(.+) ([0-9]{3}) (.+)\r\n/DU", $response['raw']['status-line'], $match)) { - $response['status']['http-version'] = $match[1]; - $response['status']['code'] = (int)$match[2]; - $response['status']['reason-phrase'] = $match[3]; - } + list(, $statusLine, $header) = $match; + $response->raw = $message; + $response->body = (string)substr($message, strlen($match[0])); - $response['header'] = $this->_parseHeader($response['raw']['header']); - $transferEncoding = null; - if (isset($response['header']['Transfer-Encoding'])) { - $transferEncoding = $response['header']['Transfer-Encoding']; + if (preg_match("/(.+) ([0-9]{3}) (.+)\r\n/DU", $statusLine, $match)) { + $response->httpVersion = $match[1]; + $response->code = $match[2]; + $response->reasonPhrase = $match[3]; } - $decoded = $this->_decodeBody($response['raw']['body'], $transferEncoding); - $response['body'] = $decoded['body']; - if (!empty($decoded['header'])) { - $response['header'] = $this->_parseHeader($this->_buildHeader($response['header']) . $this->_buildHeader($decoded['header'])); - } + $response->headers = $this->_parseHeader($header); + $transferEncoding = $response->getHeader('Transfer-Encoding'); + $decoded = $this->_decodeBody($response->body, $transferEncoding); + $response->body = $decoded['body']; - if (!empty($response['header'])) { - $response['cookies'] = $this->parseCookies($response['header']); + if (!empty($decoded['header'])) { + $response->headers = $this->_parseHeader($this->_buildHeader($response->headers) . $this->_buildHeader($decoded['header'])); } - foreach ($response['raw'] as $field => $val) { - if ($val === '') { - $response['raw'][$field] = null; - } + if (!empty($response->headers)) { + $response->cookies = $this->parseCookies($response->headers); } return $response; diff --git a/cake/tests/cases/libs/http_socket.test.php b/cake/tests/cases/libs/http_socket.test.php index 73c44fe6203..9dff42b8f13 100644 --- a/cake/tests/cases/libs/http_socket.test.php +++ b/cake/tests/cases/libs/http_socket.test.php @@ -190,6 +190,19 @@ public function EscapeToken($token, $chars = null) { public function unescapeToken($token, $chars = null) { return parent::_unescapeToken($token, $chars); } + +/** + * Convenience method for testing protected method + * + * @param string $message + * @return object HttpResponse + */ + protected function _parseResponse($message) { + if (!is_string($message)) { + return false; + } + return parent::_parseResponse($message); + } } /** @@ -596,7 +609,7 @@ public function testRequest2() { $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse)); $this->Socket->expects($this->once())->method('write') ->with("GET / HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n"); - $response = $this->Socket->request($request); + $response = (string)$this->Socket->request($request); $this->assertEquals($response, "

Hello, your lucky number is " . $number . "

"); } @@ -622,22 +635,6 @@ public function testRequest3() { $this->assertFalse($this->Socket->connected); } -/** - * testRequestResultAsReference method - * - * @return void - */ - public function testRequestResultAsReference() { - $request = array('uri' => 'htpp://www.cakephp.org/'); - $serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: foo=bar\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n

This is a cookie test!

"; - $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse)); - $this->Socket->connected = true; - $data =& $this->Socket->request($request); - $this->assertEqual($data, $this->Socket->response['body']); - $data = 'new data'; - $this->assertEqual($data, $this->Socket->response['body']); - } - /** * testRequestWithResource * @@ -654,7 +651,7 @@ public function testRequestWithResource() { $this->skipUnless($f, 'Can not write in TMP directory.'); $this->Socket->setContentResource($f); - $result = $this->Socket->request('http://www.cakephp.org/'); + $result = (string)$this->Socket->request('http://www.cakephp.org/'); $this->assertEqual($result, ''); $this->assertEqual($this->Socket->response['header']['Server'], 'CakeHttp Server'); fclose($f); @@ -662,7 +659,7 @@ public function testRequestWithResource() { unlink(TMP . 'download.txt'); $this->Socket->setContentResource(false); - $result = $this->Socket->request('http://www.cakephp.org/'); + $result = (string)$this->Socket->request('http://www.cakephp.org/'); $this->assertEqual($result, '

This is a test!

'); } @@ -987,15 +984,6 @@ public function testDelete() { public function testParseResponse() { $this->Socket->reset(); - $r = $this->Socket->parseResponse(array('foo' => 'bar')); - $this->assertEquals($r, array('foo' => 'bar')); - - $r = $this->Socket->parseResponse(true); - $this->assertEquals($r, false); - - $r = $this->Socket->parseResponse("HTTP Foo\r\nBar: La"); - $this->assertEquals($r, false); - $tests = array( 'simple-request' => array( 'response' => array( @@ -1004,10 +992,10 @@ public function testParseResponse() { 'body' => "

Hello World

\r\n

It's good to be html

" ), 'expectations' => array( - 'status.http-version' => 'HTTP/1.x', - 'status.code' => 200, - 'status.reason-phrase' => 'OK', - 'header' => $this->Socket->parseHeader("Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n"), + 'httpVersion' => 'HTTP/1.x', + 'code' => 200, + 'reasonPhrase' => 'OK', + 'headers' => array('Date' => 'Mon, 16 Apr 2007 04:14:16 GMT', 'Server' => 'CakeHttp Server'), 'body' => "

Hello World

\r\n

It's good to be html

" ) ), @@ -1017,34 +1005,8 @@ public function testParseResponse() { 'header' => null ), 'expectations' => array( - 'status.code' => 404, - 'header' => array() - ) - ), - 'chunked' => array( - 'response' => array( - 'header' => "Transfer-Encoding: chunked\r\n", - 'body' => "19\r\nThis is a chunked message\r\n0\r\n" - ), - 'expectations' => array( - 'body' => "This is a chunked message", - 'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\n") - ) - ), - 'enitity-header' => array( - 'response' => array( - 'body' => "19\r\nThis is a chunked message\r\n0\r\nFoo: Bar\r\n" - ), - 'expectations' => array( - 'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\nFoo: Bar\r\n") - ) - ), - 'enitity-header-combine' => array( - 'response' => array( - 'header' => "Transfer-Encoding: chunked\r\nFoo: Foobar\r\n" - ), - 'expectations' => array( - 'header' => $this->Socket->parseHeader("Transfer-Encoding: chunked\r\nFoo: Foobar\r\nFoo: Bar\r\n") + 'code' => 404, + 'headers' => array() ) ) ); @@ -1059,8 +1021,7 @@ public function testParseResponse() { $expectations = array_merge($expectations, $test['expectations']); foreach ($expectations as $property => $expectedVal) { - $val = Set::extract($r, $property); - $this->assertEquals($val, $expectedVal, 'Test "' . $name . '": response.' . $property . ' - %s'); + $this->assertEquals($r->{$property}, $expectedVal, 'Test "' . $name . '": response.' . $property . ' - %s'); } foreach (array('status-line', 'header', 'body', 'response') as $field) { @@ -1069,6 +1030,31 @@ public function testParseResponse() { } } +/** + * data provider function for testInvalidParseResponseData + * + * @return array + */ + public static function invalidParseResponseDataProvider() { + return array( + array(array('foo' => 'bar')), + array(true), + array("HTTP Foo\r\nBar: La"), + array('HTTP/1.1 TEST ERROR') + ); + } + +/** + * testInvalidParseResponseData + * + * @dataProvider invalidParseResponseDataProvider + * @expectedException Exception + * return void + */ + public function testInvalidParseResponseData($value) { + $this->Socket->parseResponse($value); + } + /** * testDecodeBody method *