From 6ec4a68830f5afa622e16c0e87b40f84df7f55bb Mon Sep 17 00:00:00 2001 From: Daniel Ziegenberg Date: Thu, 16 May 2024 16:39:50 +0200 Subject: [PATCH] feat: remove code for unsupported version v5 of Guzzle Signed-off-by: Daniel Ziegenberg --- .../nextrelease/remove-guzzlev5-support.json | 7 + CONTRIBUTING.md | 2 +- src/Handler/GuzzleV5/GuzzleHandler.php | 211 ----------------- src/Handler/GuzzleV5/GuzzleStream.php | 24 -- src/Handler/GuzzleV5/PsrStream.php | 34 --- src/functions.php | 13 -- tests/Handler/GuzzleV5/HandlerTest.php | 220 ------------------ tests/Handler/GuzzleV5/StreamTest.php | 48 ---- 8 files changed, 8 insertions(+), 551 deletions(-) create mode 100644 .changes/nextrelease/remove-guzzlev5-support.json delete mode 100644 src/Handler/GuzzleV5/GuzzleHandler.php delete mode 100644 src/Handler/GuzzleV5/GuzzleStream.php delete mode 100644 src/Handler/GuzzleV5/PsrStream.php delete mode 100644 tests/Handler/GuzzleV5/HandlerTest.php delete mode 100644 tests/Handler/GuzzleV5/StreamTest.php diff --git a/.changes/nextrelease/remove-guzzlev5-support.json b/.changes/nextrelease/remove-guzzlev5-support.json new file mode 100644 index 0000000000..a6e3baddd5 --- /dev/null +++ b/.changes/nextrelease/remove-guzzlev5-support.json @@ -0,0 +1,7 @@ +[ + { + "type": "enhancement", + "category": "Handler", + "description": "Remove code for unsupported version v5 of Guzzle" + } +] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fa93ad6c09..b2ac4a8d45 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -117,7 +117,7 @@ we ask the same of all community contributions as well: ### Changelog Documents A changelog document is a small JSON blob placed in the `.changes/nextrelease` -folder. It should be named a clearly and uniquely, akin to a branch name. It +folder. It should be named clearly and uniquely, akin to a branch name. It consists of a type, category, and description as follows: ```json diff --git a/src/Handler/GuzzleV5/GuzzleHandler.php b/src/Handler/GuzzleV5/GuzzleHandler.php deleted file mode 100644 index cbe78eb74d..0000000000 --- a/src/Handler/GuzzleV5/GuzzleHandler.php +++ /dev/null @@ -1,211 +0,0 @@ - true, - 'expect' => true, - 'cert' => true, - 'verify' => true, - 'timeout' => true, - 'debug' => true, - 'connect_timeout' => true, - 'stream' => true, - 'delay' => true, - 'sink' => true, - ]; - - /** @var ClientInterface */ - private $client; - - /** - * @param ClientInterface $client - */ - public function __construct(ClientInterface $client = null) - { - $this->client = $client ?: new Client(); - } - - /** - * @param Psr7Request $request - * @param array $options - * @return Promise\Promise|Promise\PromiseInterface - * @throws \GuzzleHttp\Exception\GuzzleException - */ - public function __invoke(Psr7Request $request, array $options = []) - { - // Create and send a Guzzle 5 request - $guzzlePromise = $this->client->send( - $this->createGuzzleRequest($request, $options) - ); - - $promise = new Promise\Promise( - function () use ($guzzlePromise) { - try { - $guzzlePromise->wait(); - } catch (\Exception $e) { - // The promise is already delivered when the exception is - // thrown, so don't rethrow it. - } - }, - [$guzzlePromise, 'cancel'] - ); - - $guzzlePromise->then([$promise, 'resolve'], [$promise, 'reject']); - - return $promise->then( - function (GuzzleResponse $response) { - // Adapt the Guzzle 5 Future to a Guzzle 6 ResponsePromise. - return $this->createPsr7Response($response); - }, - function (Exception $exception) use ($options) { - // If we got a 'sink' that's a path, set the response body to - // the contents of the file. This will build the resulting - // exception with more information. - if ($exception instanceof RequestException) { - if (isset($options['sink'])) { - if (!($options['sink'] instanceof Psr7StreamInterface)) { - $exception->getResponse()->setBody( - Stream::factory( - file_get_contents($options['sink']) - ) - ); - } - } - } - // Reject with information about the error. - return new Promise\RejectedPromise($this->prepareErrorData($exception)); - } - ); - } - - private function createGuzzleRequest(Psr7Request $psrRequest, array $options) - { - $ringConfig = []; - $statsCallback = isset($options['http_stats_receiver']) - ? $options['http_stats_receiver'] - : null; - unset($options['http_stats_receiver']); - - // Remove unsupported options. - foreach (array_keys($options) as $key) { - if (!isset(self::$validOptions[$key])) { - unset($options[$key]); - } - } - - // Handle delay option. - if (isset($options['delay'])) { - $ringConfig['delay'] = $options['delay']; - unset($options['delay']); - } - - // Prepare sink option. - if (isset($options['sink'])) { - $ringConfig['save_to'] = ($options['sink'] instanceof Psr7StreamInterface) - ? new GuzzleStream($options['sink']) - : $options['sink']; - unset($options['sink']); - } - - // Ensure that all requests are async and lazy like Guzzle 6. - $options['future'] = 'lazy'; - - // Create the Guzzle 5 request from the provided PSR7 request. - $request = $this->client->createRequest( - $psrRequest->getMethod(), - $psrRequest->getUri(), - $options - ); - - if (is_callable($statsCallback)) { - $request->getEmitter()->on( - 'end', - function (EndEvent $event) use ($statsCallback) { - $statsCallback($event->getTransferInfo()); - } - ); - } - - // For the request body, adapt the PSR stream to a Guzzle stream. - $body = $psrRequest->getBody(); - if ($body->getSize() === 0) { - $request->setBody(null); - } else { - $request->setBody(new GuzzleStream($body)); - } - - $request->setHeaders($psrRequest->getHeaders()); - - $request->setHeader( - 'User-Agent', - $request->getHeader('User-Agent') - . ' ' . Client::getDefaultUserAgent() - ); - - // Make sure the delay is configured, if provided. - if ($ringConfig) { - foreach ($ringConfig as $k => $v) { - $request->getConfig()->set($k, $v); - } - } - - return $request; - } - - private function createPsr7Response(GuzzleResponse $response) - { - if ($body = $response->getBody()) { - $body = new PsrStream($body); - } - - return new Psr7Response( - $response->getStatusCode(), - $response->getHeaders(), - $body, - $response->getReasonPhrase() - ); - } - - private function prepareErrorData(Exception $e) - { - $error = [ - 'exception' => $e, - 'connection_error' => false, - 'response' => null, - ]; - - if ($e instanceof ConnectException) { - $error['connection_error'] = true; - } - - if ($e instanceof RequestException && $e->getResponse()) { - $error['response'] = $this->createPsr7Response($e->getResponse()); - } - - return $error; - } -} diff --git a/src/Handler/GuzzleV5/GuzzleStream.php b/src/Handler/GuzzleV5/GuzzleStream.php deleted file mode 100644 index 5de00b5eed..0000000000 --- a/src/Handler/GuzzleV5/GuzzleStream.php +++ /dev/null @@ -1,24 +0,0 @@ -stream = $stream; - } -} diff --git a/src/Handler/GuzzleV5/PsrStream.php b/src/Handler/GuzzleV5/PsrStream.php deleted file mode 100644 index cc07613bb3..0000000000 --- a/src/Handler/GuzzleV5/PsrStream.php +++ /dev/null @@ -1,34 +0,0 @@ -stream = $stream; - } - - public function rewind() - { - $this->stream->seek(0); - } - - public function getContents() - { - return $this->stream->getContents(); - } -} diff --git a/src/functions.php b/src/functions.php index 4533728021..5e4b7df826 100644 --- a/src/functions.php +++ b/src/functions.php @@ -279,11 +279,6 @@ function default_http_handler() return new \Aws\Handler\GuzzleV6\GuzzleHandler(); } - // If Guzzle 5 installed - if ($version === 5) { - return new \Aws\Handler\GuzzleV5\GuzzleHandler(); - } - throw new \RuntimeException('Unknown Guzzle version: ' . $version); } @@ -300,11 +295,6 @@ function default_user_agent() return \GuzzleHttp\default_user_agent(); } - // If Guzzle 5 installed - if ($version === 5) { - return \GuzzleHttp\Client::getDefaultUserAgent(); - } - throw new \RuntimeException('Unknown Guzzle version: ' . $version); } @@ -327,9 +317,6 @@ function guzzle_major_version() if ($version[0] === '6') { return $cache = 6; } - if ($version[0] === '5') { - return $cache = 5; - } } elseif (defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) { return $cache = ClientInterface::MAJOR_VERSION; } diff --git a/tests/Handler/GuzzleV5/HandlerTest.php b/tests/Handler/GuzzleV5/HandlerTest.php deleted file mode 100644 index b8750ba500..0000000000 --- a/tests/Handler/GuzzleV5/HandlerTest.php +++ /dev/null @@ -1,220 +0,0 @@ -markTestSkipped(); - } - } - - public function testHandlerWorksWithSuccessfulRequest() - { - $deferred = new Deferred(); - $handler = $this->getHandler($deferred); - $request = new PsrRequest('PUT', 'http://example.com', [], '{}'); - $sink = Psr7\Utils::streamFor(); - - $promise = $handler($request, ['delay' => 500, 'sink' => $sink]); - $this->assertInstanceOf('GuzzleHttp\\Promise\\PromiseInterface', $promise); - $deferred->resolve(new GuzzleResponse(200, [], Stream::factory('foo'))); - - /** @var $response PsrResponse */ - $response = $promise->wait(); - $this->assertInstanceOf(PsrResponse::class, $response); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('foo', $response->getBody()->getContents()); - $this->assertSame('foo', (string) $sink); - } - - public function testHandlerWorksWithFailedRequest() - { - $deferred = new Deferred(); - $handler = $this->getHandler($deferred); - $wasRejected = false; - - $promise = $handler(new PsrRequest('PUT', 'http://example.com')); - $promise->then(null, function (array $error) use (&$wasRejected) { - $wasRejected = true; - }); - - $deferred->reject(new ConnectException( - 'message', - new GuzzleRequest('PUT', 'http://example.com'), - new GuzzleResponse('500') - )); - - try { - $promise->wait(); - $this->fail('An exception should have been thrown.'); - } catch (RejectionException $e) { - $error = $e->getReason(); - $this->assertInstanceOf(ConnectException::class, $error['exception']); - $this->assertTrue($error['connection_error']); - $this->assertInstanceOf(PsrResponse::class, $error['response']); - $this->assertSame(500, $error['response']->getStatusCode()); - } - - $this->assertTrue($wasRejected, 'Reject callback was not triggered.'); - } - - private function getErrorXml() - { - return << - - NoSuchKey - The specified key does not exist. - test.png - 656c76696e6727732072657175657374 - Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg== - -EOXML; - } - - public function testHandlerWorksWithFailedRequestFileSink() - { - $xml = $this->getErrorXml(); - $sink = sys_get_temp_dir() . '/test_error_sink.txt'; - $deferred = new Deferred(); - $handler = $this->getHandler($deferred, $xml); - $wasRejected = false; - - $promise = $handler( - new PsrRequest('GET', 'http://example.com'), - ['delay' => 500, 'sink' => $sink] - ); - $promise->then(null, function (array $error) use (&$wasRejected) { - $wasRejected = true; - }); - - $deferred->reject(new RequestException( - 'message', - new GuzzleRequest('GET', 'http://example.com'), - new GuzzleResponse('404') - )); - - try { - $promise->wait(); - unlink($sink); - $this->fail('An exception should have been thrown.'); - } catch (RejectionException $e) { - $error = $e->getReason(); - $this->assertInstanceOf(RequestException::class, $error['exception']); - $this->assertFalse($error['connection_error']); - $this->assertInstanceOf(PsrResponse::class, $error['response']); - $this->assertSame(404, $error['response']->getStatusCode()); - $this->assertEquals($xml, $error['response']->getBody()); - $this->assertStringEqualsFile($sink, $xml); - unlink($sink); - } - - $this->assertTrue($wasRejected, 'Reject callback was not triggered.'); - } - - public function testHandlerWorksWithFailedRequestStreamSink() - { - $xml = $this->getErrorXml(); - $sink = Psr7\Utils::streamFor(); - $deferred = new Deferred(); - $handler = $this->getHandler($deferred, $xml); - $wasRejected = false; - - $promise = $handler( - new PsrRequest('GET', 'http://example.com'), - ['delay' => 500, 'sink' => $sink] - ); - $promise->then(null, function (array $error) use (&$wasRejected) { - $wasRejected = true; - }); - - $deferred->reject(new RequestException( - 'message', - new GuzzleRequest('GET', 'http://example.com'), - new GuzzleResponse('404', [], Stream::factory($xml)) - )); - - try { - $promise->wait(); - $this->fail('An exception should have been thrown.'); - } catch (RejectionException $e) { - $error = $e->getReason(); - $this->assertInstanceOf(RequestException::class, $error['exception']); - $this->assertFalse($error['connection_error']); - $this->assertInstanceOf(PsrResponse::class, $error['response']); - $this->assertSame(404, $error['response']->getStatusCode()); - $this->assertEquals($xml, (string)$error['response']->getBody()); - $this->assertEquals($xml, (string)$sink); - } - - $this->assertTrue($wasRejected, 'Reject callback was not triggered.'); - } - - public function testHandlerWorksWithEmptyBody() - { - $deferred = new Deferred(); - $handler = $this->getHandler($deferred); - $promise = $handler(new PsrRequest('HEAD', 'http://example.com')); - $deferred->resolve(new GuzzleResponse(200)); - $this->assertInstanceOf(PsrResponse::class, $promise->wait()); - } - - public function testHandlerWillInvokeOnTransferStatsCallback() - { - $client = new Client(['handler' => new MockHandler(['status' => 200])]); - $handler = new GuzzleHandler($client); - - $request = new PsrRequest('PUT', 'http://example.com', [], '{}'); - $wasCalled = false; - $options = [ - 'http_stats_receiver' => function (array $stats) use (&$wasCalled) { - $wasCalled = true; - }, - ]; - $promise = $handler($request, $options); - $promise->wait(); - $this->assertTrue($wasCalled); - } - - private function getHandler(Deferred $deferred, $output = 'foo') - { - $client = $this->getMockBuilder('GuzzleHttp\Client')->setMethods(['send'])->getMock(); - $future = new FutureResponse($deferred->promise()); - $client->method('send')->willReturn($future); - - return function ($request, $options = []) use ($client, $output) { - /** @var $client \GuzzleHttp\Client */ - if (isset($options['sink'])) { - if ($options['sink'] instanceof PsrStream) { - $options['sink']->write($output); - } else { - file_put_contents($options['sink'], $output); - } - } - return call_user_func(new GuzzleHandler($client), $request, $options); - }; - } -} diff --git a/tests/Handler/GuzzleV5/StreamTest.php b/tests/Handler/GuzzleV5/StreamTest.php deleted file mode 100644 index de34540546..0000000000 --- a/tests/Handler/GuzzleV5/StreamTest.php +++ /dev/null @@ -1,48 +0,0 @@ -markTestSkipped(); - } - } - - public function testCanAdaptGuzzleStreamToPsr() - { - $stream = new PsrStreamAdapter(GuzzleStream::factory('foo')); - $this->verify($stream, 'foo'); - } - - public function testCanAdaptPsrStreamToGuzzle() - { - $stream = new GuzzleStreamAdapter(Psr7\Utils::streamFor('foo')); - $this->verify($stream, 'foo'); - } - - private function verify($stream, $expected) - { - $str1 = ''; - while (!$stream->eof()) { - $str1 .= $stream->read(1); - } - - $stream->rewind(); - $str2 = $stream->getContents(); - - $this->assertSame($expected, $str1); - $this->assertSame($expected, $str2); - } -}