From 66f7e4f7b1598db1ead16fd12c4c04775c5c10b0 Mon Sep 17 00:00:00 2001 From: smetdenis Date: Mon, 1 Aug 2016 01:51:15 +0700 Subject: [PATCH 1/2] add multiRequest --- src/Driver/Auto.php | 24 +++++++++++--- src/Driver/Driver.php | 6 ++++ src/Driver/Guzzle5.php | 74 +++++++++++++++++++++++++++++++++++++----- src/Driver/Guzzle6.php | 66 +++++++++++++++++++++++++++++++++---- src/Driver/Rmccue.php | 73 ++++++++++++++++++++++++++++++++++++----- src/HttpClient.php | 25 ++++++++++++++ tests/DriverTest.php | 30 +++++++++++++++++ 7 files changed, 270 insertions(+), 28 deletions(-) diff --git a/src/Driver/Auto.php b/src/Driver/Auto.php index a7c2bd5..a319435 100644 --- a/src/Driver/Auto.php +++ b/src/Driver/Auto.php @@ -27,22 +27,38 @@ class Auto extends Driver * @inheritdoc */ public function request($url, $args, $method, Options $options) + { + return $this->_getClient()->request($url, $args, $method, $options); + } + + /** + * @inheritdoc + */ + public function multiRequest(array $urls) + { + return $this->_getClient()->multiRequest($urls); + } + + /** + * @return Driver + */ + protected function _getClient() { if (class_exists('\GuzzleHttp\Client') && (version_compare(Env::getVersion(), '5.3', '>') || Env::isHHVM()) ) { if (method_exists('\GuzzleHttp\Client', 'request')) { - $client = new Guzzle6($options); + $client = new Guzzle6(); } elseif (method_exists('\GuzzleHttp\Client', 'createRequest')) { - $client = new Guzzle5($options); + $client = new Guzzle5(); } } if (!isset($client)) { // Fallback driver - $client = new Rmccue($options); + $client = new Rmccue(); } - return $client->request($url, $args, $method, $options); + return $client; } } diff --git a/src/Driver/Driver.php b/src/Driver/Driver.php index 7938945..a8ffd10 100644 --- a/src/Driver/Driver.php +++ b/src/Driver/Driver.php @@ -30,4 +30,10 @@ abstract class Driver * @return array */ abstract public function request($url, $args, $method, Options $options); + + /** + * @param array $urls + * @return array + */ + abstract public function multiRequest(array $urls); } diff --git a/src/Driver/Guzzle5.php b/src/Driver/Guzzle5.php index 501a55f..bbd7cb3 100644 --- a/src/Driver/Guzzle5.php +++ b/src/Driver/Guzzle5.php @@ -14,8 +14,11 @@ namespace JBZoo\HttpClient\Driver; +use GuzzleHttp\Message\Response; use GuzzleHttp\Client; +use GuzzleHttp\Pool; use JBZoo\HttpClient\Options; +use JBZoo\Utils\Url; /** * Class Guzzle5 @@ -30,10 +33,71 @@ public function request($url, $args, $method, Options $options) { $client = new Client(); + $httpRequest = $client->createRequest($method, $url, $this->_getClientOptions($options, $method, $args)); + + $httpResult = $client->send($httpRequest); + + return array( + $httpResult->getStatusCode(), + $httpResult->getHeaders(), + $httpResult->getBody()->getContents() + ); + } + + /** + * @inheritdoc + */ + public function multiRequest(array $urls) + { + $client = new Client(); + + $requests = array(); + foreach ($urls as $urlName => $urlData) { + $urlOptions = new Options($urlData[1]); + + $method = $urlOptions->get('method', 'GET', 'up'); + $args = $urlOptions->get('args'); + $url = 'GET' === $method ? Url::addArg((array)$args, $urlData[0]) : $urlData[0]; + + $requests[$urlName] = $client->createRequest( + $method, + $url, + $this->_getClientOptions($urlOptions, $method, $args) + ); + } + + $httpResults = Pool::batch($client, $requests); + + /** @var string $resName */ + /** @var Response $httpResult */ + $result = array(); + + $index = 0; + $keys = array_keys($urls); + foreach ($keys as $resName) { + $httpResult = $httpResults->offsetGet($index++); + $result[$resName] = array( + $httpResult->getStatusCode(), + $httpResult->getHeaders(), + $httpResult->getBody()->getContents() + ); + } + + return $result; + } + + /** + * @param Options $options + * @param string $method + * @param string|array $args + * @return array + */ + protected function _getClientOptions(Options $options, $method, $args) + { $headers = $options->getHeaders(); $headers['User-Agent'] = $options->getUserAgent('Guzzle5'); - $httpRequest = $client->createRequest($method, $url, array( + return array( 'body' => 'GET' !== $method ? $args : null, 'headers' => $headers, 'exceptions' => $options->isExceptions(), @@ -41,14 +105,6 @@ public function request($url, $args, $method, Options $options) 'verify' => $options->isVerify(), 'auth' => $options->getAuth(), 'allow_redirects' => $this->_getAllowRedirects($options) - )); - - $httpResult = $client->send($httpRequest); - - return array( - $httpResult->getStatusCode(), - $httpResult->getHeaders(), - $httpResult->getBody()->getContents() ); } } diff --git a/src/Driver/Guzzle6.php b/src/Driver/Guzzle6.php index 336f60a..76ec2cb 100644 --- a/src/Driver/Guzzle6.php +++ b/src/Driver/Guzzle6.php @@ -15,7 +15,10 @@ namespace JBZoo\HttpClient\Driver; use GuzzleHttp\Client; +use GuzzleHttp\Promise; +use GuzzleHttp\Psr7\Response; use JBZoo\HttpClient\Options; +use JBZoo\Utils\Url; /** * Class Guzzle6 @@ -30,6 +33,61 @@ public function request($url, $args, $method, Options $options) { $client = new Client(); + $httpResult = $client->request($method, $url, $this->_getClientOptions($options, $method, $args)); + + return array( + $httpResult->getStatusCode(), + $httpResult->getHeaders(), + $httpResult->getBody()->getContents() + ); + } + + /** + * @inheritdoc + */ + public function multiRequest(array $urls) + { + $client = new Client(); + + $promises = array(); + foreach ($urls as $urlName => $urlData) { + $urlOptions = new Options($urlData[1]); + + $method = $urlOptions->get('method', 'GET', 'up'); + $args = $urlOptions->get('args'); + $url = 'GET' === $method ? Url::addArg((array)$args, $urlData[0]) : $urlData[0]; + + $promises[$urlName] = $client->requestAsync( + $method, + $url, + $this->_getClientOptions($urlOptions, $method, $args) + ); + } + + $httpResults = Promise\unwrap($promises); + + /** @var string $resName */ + /** @var Response $httpResult */ + $result = array(); + foreach ($httpResults as $resName => $httpResult) { + $result[$resName] = array( + $httpResult->getStatusCode(), + $httpResult->getHeaders(), + $httpResult->getBody()->getContents() + ); + } + + return $result; + } + + /** + * @param Options $options + * @param string $method + * @param string|array $args + * @return array + */ + protected function _getClientOptions(Options $options, $method, $args) + { $headers = $options->getHeaders(); $headers['User-Agent'] = $options->getUserAgent('Guzzle6'); @@ -42,7 +100,7 @@ public function request($url, $args, $method, Options $options) } } - $httpResult = $client->request($method, $url, array( + return array( 'form_params' => $formParams, 'body' => $body, 'headers' => $headers, @@ -52,12 +110,6 @@ public function request($url, $args, $method, Options $options) 'exceptions' => $options->isExceptions(), 'auth' => $options->getAuth(), 'allow_redirects' => $this->_getAllowRedirects($options) - )); - - return array( - $httpResult->getStatusCode(), - $httpResult->getHeaders(), - $httpResult->getBody()->getContents() ); } } diff --git a/src/Driver/Rmccue.php b/src/Driver/Rmccue.php index 08d6eba..ed6a5fd 100644 --- a/src/Driver/Rmccue.php +++ b/src/Driver/Rmccue.php @@ -16,6 +16,8 @@ use JBZoo\HttpClient\Exception; use JBZoo\HttpClient\Options; +use JBZoo\Utils\Filter; +use JBZoo\Utils\Url; /** * Class Rmccue @@ -29,16 +31,16 @@ class Rmccue extends Driver public function request($url, $args, $method, Options $options) { $headers = $options->get('headers', array()); + $method = Filter::up($method); $args = 'GET' !== $method ? $args : array(); - $httpResult = \Requests::request($url, $headers, $args, $method, array( - 'timeout' => $options->getTimeout(), - 'verify' => $options->isVerify(), - 'follow_redirects' => $options->isAllowRedirects(), - 'redirects' => $options->getMaxRedirects(), - 'useragent' => $options->getUserAgent('Rmccue'), - 'auth' => $options->getAuth(), - )); + $httpResult = \Requests::request( + $url, + $headers, + $args, + $method, + $this->_getClientOptions($options) + ); if ($options->isExceptions() && $httpResult->status_code >= 400) { throw new Exception($httpResult->body, $httpResult->status_code); @@ -50,4 +52,59 @@ public function request($url, $args, $method, Options $options) $httpResult->body ); } + + /** + * @inheritdoc + */ + public function multiRequest(array $urls) + { + $requests = array(); + foreach ($urls as $urlName => $urlData) { + $urlOptions = new Options($urlData[1]); + + $method = $urlOptions->get('method', 'GET', 'up'); + $args = $urlOptions->get('args'); + $url = 'GET' === $method ? Url::addArg((array)$args, $urlData[0]) : $urlData[0]; + $args = 'GET' !== $method ? $args : array(); + + $requests[$urlName] = array( + 'url' => $url, + 'headers' => $urlOptions->getHeaders(), + 'data' => $args, + 'type' => $method, + 'options' => $this->_getClientOptions($urlOptions), + ); + } + + $httpResults = \Requests::request_multiple($requests); + + /** @var string $resName */ + /** @var \Requests_Response $httpResult */ + $result = array(); + foreach ($httpResults as $resName => $httpResult) { + $result[$resName] = array( + $httpResult->status_code, + $httpResult->headers->getAll(), + $httpResult->body + ); + } + + return $result; + } + + /** + * @param Options $options + * @return array + */ + protected function _getClientOptions(Options $options) + { + return array( + 'timeout' => $options->getTimeout(), + 'verify' => $options->isVerify(), + 'follow_redirects' => $options->isAllowRedirects(), + 'redirects' => $options->getMaxRedirects(), + 'useragent' => $options->getUserAgent('Rmccue'), + 'auth' => $options->getAuth(), + ); + } } diff --git a/src/HttpClient.php b/src/HttpClient.php index d7bf287..348dfa1 100644 --- a/src/HttpClient.php +++ b/src/HttpClient.php @@ -77,6 +77,31 @@ public function request($url, $args = null, $method = Options::DEFAULT_METHOD, a return $response; } + /** + * @param array $urls + * @param array $options + * @return array + */ + public function multiRequest(array $urls, array $options = array()) + { + $options = new Options(array_merge($this->_options->getArrayCopy(), $options)); + $client = $this->_getClient($options); + + $httpResults = $client->multiRequest($urls, $options); + + $results = array(); + foreach ($httpResults as $resKey => $resultRow) { + list($code, $headers, $body) = $resultRow; + + $results[$resKey] = new Response(); + $results[$resKey]->setCode($code); + $results[$resKey]->setHeaders($headers); + $results[$resKey]->setBody($body); + } + + return $results; + } + /** * @param Options $options * @return Driver diff --git a/tests/DriverTest.php b/tests/DriverTest.php index a62c349..1ead98d 100644 --- a/tests/DriverTest.php +++ b/tests/DriverTest.php @@ -16,6 +16,7 @@ use JBZoo\HttpClient\HttpClient; use JBZoo\HttpClient\Options; +use JBZoo\HttpClient\Response; use JBZoo\Utils\Env; use JBZoo\Utils\Url; @@ -310,4 +311,33 @@ public function testSSL() isSame(200, $result->code); isContain('google', $result->body); } + + public function testMultiRequest() + { + $results = $this->_getClient()->multiRequest(array( + 'request_1' => array( + 'http://mockbin.org/request', + array( + 'args' => array('key' => 'value') + ), + ), + 'request_2' => array( + 'http://mockbin.org/request', + array( + 'method' => 'post', + 'args' => array('key' => 'value') + ) + ) + )); + + /** @var Response $body1 */ + $body1 = $results['request_1']->getJSON(); + isSame('GET', $body1->find('method')); + isSame('value', $body1->find('queryString.key')); + + /** @var Response $body2 */ + $body2 = $results['request_2']->getJSON(); + isSame('POST', $body2->find('method')); + isSame('value', $body2->find('postData.params.key')); + } } From 0eb3b80c50e4ced766627ded77eb8c4d464e7c2d Mon Sep 17 00:00:00 2001 From: smetdenis Date: Mon, 1 Aug 2016 01:56:50 +0700 Subject: [PATCH 2/2] add multiRequest --- tests/DriverTest.php | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/DriverTest.php b/tests/DriverTest.php index 1ead98d..3154aba 100644 --- a/tests/DriverTest.php +++ b/tests/DriverTest.php @@ -315,19 +315,13 @@ public function testSSL() public function testMultiRequest() { $results = $this->_getClient()->multiRequest(array( - 'request_1' => array( - 'http://mockbin.org/request', - array( - 'args' => array('key' => 'value') - ), - ), - 'request_2' => array( - 'http://mockbin.org/request', - array( - 'method' => 'post', - 'args' => array('key' => 'value') - ) - ) + 'request_1' => array('http://mockbin.org/request', array( + 'args' => array('key' => 'value') + )), + 'request_2' => array('http://mockbin.org/request', array( + 'method' => 'post', + 'args' => array('key' => 'value') + )) )); /** @var Response $body1 */