diff --git a/composer.json b/composer.json index a6044fa..dfac6eb 100644 --- a/composer.json +++ b/composer.json @@ -12,10 +12,13 @@ ], "require": { "php": ">=5.4", - "php-http/adapter-core": "dev-master" + "ext-curl": "*", + "php-http/adapter-core": "dev-initial_import", + "guzzlehttp/guzzle": "~5.0", + "guzzlehttp/ringphp": "^1.0.8@dev" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "php-http/adapter-integration-tests": "dev-master" }, "provide": { "php-http/adapter-implementation": "0.1" @@ -25,6 +28,11 @@ "Http\\Adapter\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Http\\Adapter\\Tests\\": "tests/" + } + }, "extra": { "branch-alias": { "dev-master": "0.1-dev" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index fd71e68..fe68fd5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,6 +5,9 @@ tests/ + + + src/ diff --git a/src/Guzzle5HttpAdapter.php b/src/Guzzle5HttpAdapter.php new file mode 100644 index 0000000..ece431e --- /dev/null +++ b/src/Guzzle5HttpAdapter.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter; + +use GuzzleHttp\Client; +use GuzzleHttp\ClientInterface; +use GuzzleHttp\Event\CompleteEvent; +use GuzzleHttp\Event\ErrorEvent; +use GuzzleHttp\Message\RequestInterface; +use GuzzleHttp\Pool; +use Http\Adapter\Message\InternalRequestInterface; +use Http\Adapter\Normalizer\BodyNormalizer; + +/** + * @author GeLo + */ +class Guzzle5HttpAdapter extends CurlHttpAdapter +{ + /** + * @var ClientInterface + */ + private $client; + + /** + * + * @param ClientInterface|null $client + * @param ConfigurationInterface|null $configuration + */ + public function __construct(ClientInterface $client = null, ConfigurationInterface $configuration = null) + { + parent::__construct($configuration); + + $this->client = $client ?: new Client(); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'guzzle5'; + } + + /** + * {@inheritdoc} + */ + protected function sendInternalRequest(InternalRequestInterface $internalRequest) + { + try { + $response = $this->client->send($this->createRequest($internalRequest)); + } catch (\Exception $e) { + var_dump($e); exit; + throw HttpAdapterException::cannotFetchUri( + $e->getRequest()->getUrl(), + $this->getName(), + $e->getMessage() + ); + } + + return $this->getConfiguration()->getMessageFactory()->createResponse( + (integer) $response->getStatusCode(), + $response->getProtocolVersion(), + $response->getHeaders(), + BodyNormalizer::normalize( + function () use ($response) { + return $response->getBody()->detach(); + }, + $internalRequest->getMethod() + ) + ); + } + + /** + * {@inheritdoc} + */ + protected function sendInternalRequests(array $internalRequests, $success, $error) + { + $requests = []; + foreach ($internalRequests as $internalRequest) { + $requests[] = $this->createRequest($internalRequest, $success, $error); + } + + Pool::batch($this->client, $requests); + } + + /** + * {@inheritdoc} + */ + protected function createFile($file) + { + return fopen($file, 'r'); + } + + /** + * Creates a request. + * + * @param InternalRequestInterface $internalRequest + * @param callable|null $success + * @param callable|null $error + * + * @return RequestInterface + */ + private function createRequest(InternalRequestInterface $internalRequest, callable $success = null, callable $error = null) + { + $request = $this->client->createRequest( + $internalRequest->getMethod(), + (string) $internalRequest->getUri(), + [ + 'exceptions' => false, + 'allow_redirects' => false, + 'timeout' => $this->getConfiguration()->getTimeout(), + 'connect_timeout' => $this->getConfiguration()->getTimeout(), + 'version' => $internalRequest->getProtocolVersion(), + 'headers' => $this->prepareHeaders($internalRequest), + 'body' => $this->prepareContent($internalRequest), + ] + ); + + if (isset($success)) { + $messageFactory = $this->getConfiguration()->getMessageFactory(); + + $request->getEmitter()->on( + 'complete', + function (CompleteEvent $event) use ($success, $internalRequest, $messageFactory) { + $response = $messageFactory->createResponse( + (integer) $event->getResponse()->getStatusCode(), + $event->getResponse()->getProtocolVersion(), + $event->getResponse()->getHeaders(), + BodyNormalizer::normalize( + function () use ($event) { + return $event->getResponse()->getBody()->detach(); + }, + $internalRequest->getMethod() + ) + ); + + $response = $response->withParameter('request', $internalRequest); + call_user_func($success, $response); + } + ); + } + + if (isset($error)) { + $httpAdapterName = $this->getName(); + + $request->getEmitter()->on( + 'error', + function (ErrorEvent $event) use ($error, $internalRequest, $httpAdapterName) { + $exception = HttpAdapterException::cannotFetchUri( + $event->getException()->getRequest()->getUrl(), + $httpAdapterName, + $event->getException()->getMessage() + ); + $exception->setRequest($internalRequest); + call_user_func($error, $exception); + } + ); + } + + return $request; + } +} diff --git a/tests/Guzzle5HttpAdapterTest.php b/tests/Guzzle5HttpAdapterTest.php new file mode 100644 index 0000000..209e44b --- /dev/null +++ b/tests/Guzzle5HttpAdapterTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter\Tests; + +use GuzzleHttp\Client; +use GuzzleHttp\Ring\Client\CurlHandler; +use Http\Adapter\Guzzle5HttpAdapter; + +/** + * @author GeLo + */ +class Guzzle5HttpAdapterTest extends HttpAdapterTest +{ + public function testGetName() + { + $this->assertSame('guzzle5', $this->httpAdapter->getName()); + } + + /** + * {@inheritdoc} + */ + protected function createHttpAdapter() + { + return new Guzzle5HttpAdapter(new Client(['handler' => $this->createHandler()])); + } + + /** + * Returns a handler for the client + */ + protected function createHandler() + { + return new CurlHandler(); + } +} diff --git a/tests/Guzzle5MultiHttpAdapterTest.php b/tests/Guzzle5MultiHttpAdapterTest.php new file mode 100644 index 0000000..ef0fd85 --- /dev/null +++ b/tests/Guzzle5MultiHttpAdapterTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please read the LICENSE + * file that was distributed with this source code. + */ + +namespace Http\Adapter\Tests; + +use GuzzleHttp\Ring\Client\CurlMultiHandler; + +/** + * @author GeLo + */ +class Guzzle5MultiHttpAdapterTest extends Guzzle5HttpAdapterTest +{ + /** + * Returns a handler for the client + */ + protected function createHandler() + { + return new CurlMultiHandler(); + } +}