From 0be8403272913c4cee85350f70d4e56bd49283ef Mon Sep 17 00:00:00 2001 From: Natan Felles <natanfelles@gmail.com> Date: Sat, 17 Nov 2018 21:40:31 -0200 Subject: [PATCH 1/2] Add CURLRequest helper methods --- system/HTTP/CURLRequest.php | 64 ++++++++++- tests/system/HTTP/CURLRequestTest.php | 155 +++++++++++++++++++------- 2 files changed, 177 insertions(+), 42 deletions(-) diff --git a/system/HTTP/CURLRequest.php b/system/HTTP/CURLRequest.php index 6cbbc17459ef..5aa1665fa27b 100644 --- a/system/HTTP/CURLRequest.php +++ b/system/HTTP/CURLRequest.php @@ -47,8 +47,6 @@ * A lightweight HTTP client for sending synchronous HTTP requests * via cURL. * - * @todo Add a few helpers for dealing with JSON, forms, files, etc. - * * @package CodeIgniter\HTTP */ class CURLRequest extends Request @@ -267,6 +265,68 @@ public function put(string $url, array $options = []): ResponseInterface //-------------------------------------------------------------------- + /** + * Set the HTTP Authentication. + * + * @param string $username + * @param string $password + * @param string $type basic or digest + * + * @return $this + */ + public function setAuth(string $username, string $password, string $type = 'basic') + { + $this->config['auth'] = [ + $username, + $password, + $type, + ]; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Set form data to be sent. + * + * @param array $params + * @param boolean $multipart Set TRUE if you are sending CURLFiles + * + * @return $this + */ + public function setForm(array $params, bool $multipart = false) + { + if ($multipart) + { + $this->config['multipart'] = $params; + } + else + { + $this->config['form_params'] = $params; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Set JSON data to be sent. + * + * @param mixed $data + * + * @return $this + */ + public function setJSON($data) + { + $this->config['json'] = $data; + + return $this; + } + + //-------------------------------------------------------------------- + /** * Sets the correct settings based on the options array * passed in. diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php index 1b50fb4c3e94..7ee3506b6383 100644 --- a/tests/system/HTTP/CURLRequestTest.php +++ b/tests/system/HTTP/CURLRequestTest.php @@ -8,7 +8,9 @@ class CURLRequestTest extends \CIUnitTestCase { - + /** + * @var MockCURLRequest + */ protected $request; public function setUp() @@ -23,7 +25,7 @@ protected function getRequest(array $options = []) { $uri = isset($options['base_uri']) ? new URI($options['base_uri']) : new URI(); - return new MockCURLRequest(new App(), $uri, new Response(new \Config\App()), $options); + return new MockCURLRequest(($app = new App()), $uri, new Response($app), $options); } //-------------------------------------------------------------------- @@ -37,7 +39,7 @@ public function testGetRemembersBaseURI() 'base_uri' => 'http://www.foo.com/api/v1/', ]); - $response = $request->get('products'); + $request->get('products'); $options = $request->curl_options; @@ -75,7 +77,7 @@ public function testSendReturnsResponse() public function testGetSetsCorrectMethod() { - $response = $this->request->get('http://example.com'); + $this->request->get('http://example.com'); $this->assertEquals('get', $this->request->getMethod()); @@ -89,7 +91,7 @@ public function testGetSetsCorrectMethod() public function testDeleteSetsCorrectMethod() { - $response = $this->request->delete('http://example.com'); + $this->request->delete('http://example.com'); $this->assertEquals('delete', $this->request->getMethod()); @@ -103,7 +105,7 @@ public function testDeleteSetsCorrectMethod() public function testHeadSetsCorrectMethod() { - $response = $this->request->head('http://example.com'); + $this->request->head('http://example.com'); $this->assertEquals('head', $this->request->getMethod()); @@ -117,7 +119,7 @@ public function testHeadSetsCorrectMethod() public function testOptionsSetsCorrectMethod() { - $response = $this->request->options('http://example.com'); + $this->request->options('http://example.com'); $this->assertEquals('options', $this->request->getMethod()); @@ -184,7 +186,7 @@ public function testOptionsDelay() public function testPatchSetsCorrectMethod() { - $response = $this->request->patch('http://example.com'); + $this->request->patch('http://example.com'); $this->assertEquals('patch', $this->request->getMethod()); @@ -198,7 +200,7 @@ public function testPatchSetsCorrectMethod() public function testPostSetsCorrectMethod() { - $response = $this->request->post('http://example.com'); + $this->request->post('http://example.com'); $this->assertEquals('post', $this->request->getMethod()); @@ -212,7 +214,7 @@ public function testPostSetsCorrectMethod() public function testPutSetsCorrectMethod() { - $response = $this->request->put('http://example.com'); + $this->request->put('http://example.com'); $this->assertEquals('put', $this->request->getMethod()); @@ -226,7 +228,7 @@ public function testPutSetsCorrectMethod() public function testCustomMethodSetsCorrectMethod() { - $response = $this->request->request('custom', 'http://example.com'); + $this->request->request('custom', 'http://example.com'); $this->assertEquals('custom', $this->request->getMethod()); @@ -240,7 +242,7 @@ public function testCustomMethodSetsCorrectMethod() public function testRequestMethodGetsSanitized() { - $response = $this->request->request('<script>Custom</script>', 'http://example.com'); + $this->request->request('<script>Custom</script>', 'http://example.com'); $this->assertEquals('custom', $this->request->getMethod()); @@ -254,7 +256,7 @@ public function testRequestMethodGetsSanitized() public function testRequestSetsBasicCurlOptions() { - $response = $this->request->request('get', 'http://example.com'); + $this->request->request('get', 'http://example.com'); $options = $this->request->curl_options; @@ -281,7 +283,7 @@ public function testRequestSetsBasicCurlOptions() public function testAuthBasicOption() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'auth' => [ 'username', 'password', @@ -301,7 +303,7 @@ public function testAuthBasicOption() public function testAuthBasicOptionExplicit() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'auth' => [ 'username', 'password', @@ -322,7 +324,7 @@ public function testAuthBasicOptionExplicit() public function testAuthDigestOption() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'auth' => [ 'username', 'password', @@ -341,11 +343,39 @@ public function testAuthDigestOption() //-------------------------------------------------------------------- + public function testSetAuthBasic() + { + $this->request->setAuth('username', 'password')->get('http://example.com'); + + $options = $this->request->curl_options; + + $this->assertArrayHasKey(CURLOPT_USERPWD, $options); + $this->assertEquals('username:password', $options[CURLOPT_USERPWD]); + + $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options); + $this->assertEquals(CURLAUTH_BASIC, $options[CURLOPT_HTTPAUTH]); + } + + public function testSetAuthDigest() + { + $this->request->setAuth('username', 'password', 'digest')->get('http://example.com'); + + $options = $this->request->curl_options; + + $this->assertArrayHasKey(CURLOPT_USERPWD, $options); + $this->assertEquals('username:password', $options[CURLOPT_USERPWD]); + + $this->assertArrayHasKey(CURLOPT_HTTPAUTH, $options); + $this->assertEquals(CURLAUTH_DIGEST, $options[CURLOPT_HTTPAUTH]); + } + + //-------------------------------------------------------------------- + public function testCertOption() { $file = __FILE__; - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'cert' => $file, ]); @@ -359,7 +389,7 @@ public function testCertOptionWithPassword() { $file = __FILE__; - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'cert' => [ $file, 'password', @@ -380,7 +410,7 @@ public function testMissingCertOption() $file = 'something_obviously_bogus'; $this->expectException(Exceptions\HTTPException::class); - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'cert' => $file, ]); } @@ -391,7 +421,7 @@ public function testSSLVerification() { $file = __FILE__; - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'verify' => 'yes', 'ssl_key' => $file, ]); @@ -410,7 +440,7 @@ public function testSSLWithBadKey() $file = 'something_obviously_bogus'; $this->expectException(Exceptions\HTTPException::class); - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'verify' => 'yes', 'ssl_key' => $file, ]); @@ -420,7 +450,7 @@ public function testSSLWithBadKey() public function testDebugOption() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'debug' => true, ]); @@ -437,7 +467,7 @@ public function testDebugOption() public function testDecodeContent() { $this->request->setHeader('Accept-Encoding', 'cobol'); - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'decode_content' => true, ]); @@ -450,7 +480,7 @@ public function testDecodeContent() public function testDecodeContentWithoutAccept() { // $this->request->setHeader('Accept-Encoding', 'cobol'); - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'decode_content' => true, ]); @@ -466,7 +496,7 @@ public function testDecodeContentWithoutAccept() public function testAllowRedirectsOptionFalse() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'allow_redirects' => false, ]); @@ -481,7 +511,7 @@ public function testAllowRedirectsOptionFalse() public function testAllowRedirectsOptionTrue() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'allow_redirects' => true, ]); @@ -498,7 +528,7 @@ public function testAllowRedirectsOptionTrue() public function testAllowRedirectsOptionDefaults() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'allow_redirects' => true, ]); @@ -513,7 +543,7 @@ public function testAllowRedirectsOptionDefaults() public function testAllowRedirectsArray() { - $response = $this->request->request('get', 'http://example.com', [ + $this->request->request('get', 'http://example.com', [ 'allow_redirects' => ['max' => 2], ]); @@ -535,7 +565,7 @@ public function testSendWithQuery() 'query' => ['name' => 'Henry'], ]); - $response = $request->get('products'); + $request->get('products'); $options = $request->curl_options; @@ -550,7 +580,7 @@ public function testSendWithDelay() 'delay' => 1000, ]); - $response = $request->get('products'); + $request->get('products'); // we still need to check the code coverage to make sure this was done $this->assertEquals(1.0, $request->getDelay()); @@ -617,14 +647,14 @@ public function testResponseHeaders() public function testPostFormEncoded() { - $params = [ + $params = [ 'foo' => 'bar', 'baz' => [ 'hi', 'there', ], ]; - $response = $this->request->request('POST', '/post', [ + $this->request->request('POST', '/post', [ 'form_params' => $params, ]); @@ -639,7 +669,7 @@ public function testPostFormEncoded() public function testPostFormMultipart() { - $params = [ + $params = [ 'foo' => 'bar', 'baz' => [ 'hi', @@ -647,7 +677,7 @@ public function testPostFormMultipart() ], 'afile' => new \CURLFile(__FILE__), ]; - $response = $this->request->request('POST', '/post', [ + $this->request->request('POST', '/post', [ 'multipart' => $params, ]); @@ -661,16 +691,45 @@ public function testPostFormMultipart() //-------------------------------------------------------------------- + public function testSetForm() + { + $params = [ + 'foo' => 'bar', + 'baz' => [ + 'hi', + 'there', + ], + ]; + + $this->request->setForm($params)->post('/post'); + + $this->assertEquals( + http_build_query($params), + $this->request->curl_options[CURLOPT_POSTFIELDS] + ); + + $params['afile'] = new \CURLFile(__FILE__); + + $this->request->setForm($params, true)->post('/post'); + + $this->assertEquals( + $params, + $this->request->curl_options[CURLOPT_POSTFIELDS] + ); + } + + //-------------------------------------------------------------------- + public function testJSONData() { - $params = [ + $params = [ 'foo' => 'bar', 'baz' => [ 'hi', 'there', ], ]; - $response = $this->request->request('POST', '/post', [ + $this->request->request('POST', '/post', [ 'json' => $params, ]); @@ -682,9 +741,25 @@ public function testJSONData() //-------------------------------------------------------------------- + public function testSetJSON() + { + $params = [ + 'foo' => 'bar', + 'baz' => [ + 'hi', + 'there', + ], + ]; + $this->request->setJSON($params)->post('/post'); + + $this->assertEquals(json_encode($params), $this->request->getBody()); + } + + //-------------------------------------------------------------------- + public function testHTTPv1() { - $response = $this->request->request('POST', '/post', [ + $this->request->request('POST', '/post', [ 'version' => 1.0, ]); @@ -696,7 +771,7 @@ public function testHTTPv1() public function testHTTPv11() { - $response = $this->request->request('POST', '/post', [ + $this->request->request('POST', '/post', [ 'version' => 1.1, ]); @@ -710,8 +785,8 @@ public function testHTTPv11() public function testCookieOption() { - $holder = SUPPORTPATH . 'HTTP/Files/CookiesHolder.txt'; - $response = $this->request->request('POST', '/post', [ + $holder = SUPPORTPATH . 'HTTP/Files/CookiesHolder.txt'; + $this->request->request('POST', '/post', [ 'cookie' => $holder, ]); From 42605e9ac3784b52f5b0c20825a39d0664795fd0 Mon Sep 17 00:00:00 2001 From: Natan Felles <natanfelles@gmail.com> Date: Wed, 28 Nov 2018 21:05:51 -0200 Subject: [PATCH 2/2] Test json content-type header --- tests/system/HTTP/CURLRequestTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system/HTTP/CURLRequestTest.php b/tests/system/HTTP/CURLRequestTest.php index 7ee3506b6383..5eeb75930872 100644 --- a/tests/system/HTTP/CURLRequestTest.php +++ b/tests/system/HTTP/CURLRequestTest.php @@ -753,6 +753,7 @@ public function testSetJSON() $this->request->setJSON($params)->post('/post'); $this->assertEquals(json_encode($params), $this->request->getBody()); + $this->assertEquals('application/json', $this->request->getHeaderLine('Content-Type')); } //--------------------------------------------------------------------