diff --git a/lib/Cake/Network/Http/Client.php b/lib/Cake/Network/Http/Client.php index ae521c7b851..a65b8533733 100644 --- a/lib/Cake/Network/Http/Client.php +++ b/lib/Cake/Network/Http/Client.php @@ -102,7 +102,13 @@ public function config($config = null) { */ public function get($url, $data = [], $options = []) { $options = $this->_mergeOptions($options); - $request = $this->_createRequest(Request::METHOD_GET, $url, $data, $options); + $url = $this->buildUrl($url, $data, $options); + $request = $this->_createRequest( + Request::METHOD_GET, + $url, + [], + $options + ); return $this->send($request, $options); } @@ -173,13 +179,17 @@ public function send(Request $request, $options = []) { * Generate a URL based on the scoped client options. * * @param string $url Either a full URL or just the path. + * @param array $query The query data for the URL. * @param array $options The config options stored with Client::config() * @return string A complete url with scheme, port, host, path. */ - public function buildUrl($url, $options = []) { - if (empty($options)) { + public function buildUrl($url, $query = [], $options = []) { + if (empty($options) && empty($query)) { return $url; } + if ($query) { + $url .= '?' . http_build_query($query); + } if (preg_match('#^https?://#', $url)) { return $url; } @@ -204,11 +214,13 @@ public function buildUrl($url, $options = []) { /** * Creates a new request object based on the parameters. * - * + * @param string $method HTTP method name. + * @param string $url The url including query string. + * @param mixed $data The request body content. + * @param array $options The options to use. Contains auth, proxy etc. * @return Cake\Network\Http\Request */ protected function _createRequest($method, $url, $data, $options) { - $url = $this->buildUrl($url, $options); $request = new Request(); $request->method($method) ->url($url) diff --git a/lib/Cake/Test/TestCase/Network/Http/ClientTest.php b/lib/Cake/Test/TestCase/Network/Http/ClientTest.php index 45bf82f41ec..aa5a8af6eaa 100644 --- a/lib/Cake/Test/TestCase/Network/Http/ClientTest.php +++ b/lib/Cake/Test/TestCase/Network/Http/ClientTest.php @@ -60,6 +60,7 @@ public static function urlProvider() { [ 'http://example.com/test.html', 'http://example.com/test.html', + [], null, 'Null options' ], @@ -67,54 +68,68 @@ public static function urlProvider() { 'http://example.com/test.html', 'http://example.com/test.html', [], + [], 'Simple string' ], [ 'http://example.com/test.html', '/test.html', + [], ['host' => 'example.com'], 'host name option', ], [ 'https://example.com/test.html', '/test.html', + [], ['host' => 'example.com', 'scheme' => 'https'], 'HTTPS', ], [ 'http://example.com:8080/test.html', '/test.html', + [], ['host' => 'example.com', 'port' => '8080'], 'Non standard port', ], [ 'http://example.com/test.html', '/test.html', + [], ['host' => 'example.com', 'port' => '80'], 'standard port, does not display' ], [ 'https://example.com/test.html', '/test.html', + [], ['host' => 'example.com', 'scheme' => 'https', 'port' => '443'], 'standard port, does not display' ], [ 'http://example.com/test.html', 'http://example.com/test.html', + [], ['host' => 'example.com', 'scheme' => 'https'], 'options do not duplicate' ], + [ + 'http://example.com/search?q=hi+there&cat%5Bid%5D%5B0%5D=2&cat%5Bid%5D%5B1%5D=3', + 'http://example.com/search', + ['q' => 'hi there', 'cat' => ['id' => [2, 3]]], + [], + 'query string data.' + ], ]; } /** * @dataProvider urlProvider */ - public function testBuildUrl($expected, $url, $opts) { + public function testBuildUrl($expected, $url, $query, $opts) { $http = new Client(); - $result = $http->buildUrl($url, $opts); + $result = $http->buildUrl($url, $query, $opts); $this->assertEquals($expected, $result); } @@ -179,4 +194,31 @@ public function testGetSimpleWithHeadersAndCookies() { $this->assertSame($result, $response); } +/** + * test get request with querystring data + * + * @return void + */ + public function testGetQuerystring() { + $response = new Response(); + + $mock = $this->getMock('Cake\Network\Http\Adapter\Stream', ['send']); + $mock->expects($this->once()) + ->method('send') + ->with($this->logicalAnd( + $this->isInstanceOf('Cake\Network\Http\Request'), + $this->attributeEqualTo('_url', 'http://cakephp.org/search?q=hi+there&Category%5Bid%5D%5B0%5D=2&Category%5Bid%5D%5B1%5D=3') + )) + ->will($this->returnValue($response)); + + $http = new Client([ + 'host' => 'cakephp.org', + 'adapter' => $mock + ]); + $result = $http->get('/search', [ + 'q' => 'hi there', + 'Category' => ['id' => [2, 3]] + ]); + $this->assertSame($result, $response); + } }