diff options
Diffstat (limited to 'vendor/php-http/guzzle7-adapter/src')
3 files changed, 216 insertions, 0 deletions
diff --git a/vendor/php-http/guzzle7-adapter/src/Client.php b/vendor/php-http/guzzle7-adapter/src/Client.php new file mode 100644 index 000000000..a92ab06bd --- /dev/null +++ b/vendor/php-http/guzzle7-adapter/src/Client.php @@ -0,0 +1,75 @@ +<?php + +declare(strict_types=1); + +namespace Http\Adapter\Guzzle7; + +use GuzzleHttp\Client as GuzzleClient; +use GuzzleHttp\ClientInterface; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Middleware; +use GuzzleHttp\Utils; +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * HTTP Adapter for Guzzle 7. + * + * @author Tobias Nyholm <[email protected]> + */ +final class Client implements HttpClient, HttpAsyncClient +{ + /** + * @var ClientInterface + */ + private $guzzle; + + public function __construct(?ClientInterface $guzzle = null) + { + if (!$guzzle) { + $guzzle = self::buildClient(); + } + + $this->guzzle = $guzzle; + } + + /** + * Factory method to create the Guzzle 7 adapter with custom Guzzle configuration. + */ + public static function createWithConfig(array $config): Client + { + return new self(self::buildClient($config)); + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request): ResponseInterface + { + return $this->sendAsyncRequest($request)->wait(); + } + + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + $promise = $this->guzzle->sendAsync($request); + + return new Promise($promise, $request); + } + + /** + * Build the Guzzle client instance. + */ + private static function buildClient(array $config = []): GuzzleClient + { + $handlerStack = new HandlerStack(Utils::chooseHandler()); + $handlerStack->push(Middleware::prepareBody(), 'prepare_body'); + $config = array_merge(['handler' => $handlerStack], $config); + + return new GuzzleClient($config); + } +} diff --git a/vendor/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php b/vendor/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php new file mode 100644 index 000000000..f4731be07 --- /dev/null +++ b/vendor/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php @@ -0,0 +1,9 @@ +<?php + +namespace Http\Adapter\Guzzle7\Exception; + +use Http\Client\Exception; + +final class UnexpectedValueException extends \UnexpectedValueException implements Exception +{ +} diff --git a/vendor/php-http/guzzle7-adapter/src/Promise.php b/vendor/php-http/guzzle7-adapter/src/Promise.php new file mode 100644 index 000000000..b83021688 --- /dev/null +++ b/vendor/php-http/guzzle7-adapter/src/Promise.php @@ -0,0 +1,132 @@ +<?php + +declare(strict_types=1); + +namespace Http\Adapter\Guzzle7; + +use GuzzleHttp\Exception as GuzzleExceptions; +use GuzzleHttp\Promise\PromiseInterface; +use Http\Adapter\Guzzle7\Exception\UnexpectedValueException; +use Http\Client\Exception as HttplugException; +use Http\Promise\Promise as HttpPromise; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Wrapper around Guzzle promises. + * + * @author Joel Wurtz <[email protected]> + */ +final class Promise implements HttpPromise +{ + /** + * @var PromiseInterface + */ + private $promise; + + /** + * @var string State of the promise + */ + private $state; + + /** + * @var ResponseInterface + */ + private $response; + + /** + * @var HttplugException + */ + private $exception; + + /** + * @var RequestInterface + */ + private $request; + + public function __construct(PromiseInterface $promise, RequestInterface $request) + { + $this->request = $request; + $this->state = self::PENDING; + $this->promise = $promise->then(function ($response) { + $this->response = $response; + $this->state = self::FULFILLED; + + return $response; + }, function ($reason) use ($request) { + $this->state = self::REJECTED; + + if ($reason instanceof HttplugException) { + $this->exception = $reason; + } elseif ($reason instanceof GuzzleExceptions\GuzzleException) { + $this->exception = $this->handleException($reason, $request); + } elseif ($reason instanceof \Throwable) { + $this->exception = new HttplugException\TransferException('Invalid exception returned from Guzzle7', 0, $reason); + } else { + $this->exception = new UnexpectedValueException('Reason returned from Guzzle7 must be an Exception'); + } + + throw $this->exception; + }); + } + + /** + * {@inheritdoc} + */ + public function then(callable $onFulfilled = null, callable $onRejected = null) + { + return new static($this->promise->then($onFulfilled, $onRejected), $this->request); + } + + /** + * {@inheritdoc} + */ + public function getState() + { + return $this->state; + } + + /** + * {@inheritdoc} + */ + public function wait($unwrap = true) + { + $this->promise->wait(false); + + if ($unwrap) { + if (self::REJECTED == $this->getState()) { + throw $this->exception; + } + + return $this->response; + } + } + + /** + * Converts a Guzzle exception into an Httplug exception. + * + * @return HttplugException + */ + private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request) + { + if ($exception instanceof GuzzleExceptions\ConnectException) { + return new HttplugException\NetworkException($exception->getMessage(), $exception->getRequest(), $exception); + } + + if ($exception instanceof GuzzleExceptions\RequestException) { + // Make sure we have a response for the HttpException + if ($exception->hasResponse()) { + return new HttplugException\HttpException( + $exception->getMessage(), + $exception->getRequest(), + $exception->getResponse(), + $exception + ); + } + + return new HttplugException\RequestException($exception->getMessage(), $exception->getRequest(), $exception); + } + + return new HttplugException\TransferException($exception->getMessage(), 0, $exception); + } +} |