Skip to content

Commit df3253e

Browse files
Add support for Guzzle 8
1 parent f745b31 commit df3253e

7 files changed

Lines changed: 60 additions & 10 deletions

File tree

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"google/apiclient-services": "~0.350",
1414
"firebase/php-jwt": "^6.0||^7.0",
1515
"monolog/monolog": "^2.9||^3.0",
16-
"guzzlehttp/guzzle": "^7.4.5",
17-
"guzzlehttp/psr7": "^2.6"
16+
"guzzlehttp/guzzle": "^7.8.2||^8.0",
17+
"guzzlehttp/psr7": "^2.6.3||^3.0"
1818
},
1919
"require-dev": {
2020
"squizlabs/php_codesniffer": "^3.8",

phpstan.neon.dist

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,16 @@ parameters:
33
level: 5
44
paths:
55
- src
6+
ignoreErrors:
7+
# Guzzle 7 always has RequestException::getResponse(); Guzzle 8 only has
8+
# it on the ResponseException subclass, hence the runtime check.
9+
-
10+
message: '#^Call to function method_exists\(\) with GuzzleHttp\\Exception\\RequestException and ''getResponse'' will always evaluate to true\.$#'
11+
path: src/Http/REST.php
12+
reportUnmatched: false
13+
# Guzzle 8 removes getConfig() from ClientInterface; the concrete
14+
# Client::getConfig() remains and is what is used at runtime.
15+
-
16+
message: '#^Call to an undefined method GuzzleHttp\\ClientInterface::getConfig\(\)\.$#'
17+
path: src/AuthHandler/Guzzle6AuthHandler.php
18+
reportUnmatched: false

src/AuthHandler/AuthHandlerFactory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static function build($cache = null, array $cacheConfig = [])
4141
case 6:
4242
return new Guzzle6AuthHandler($cache, $cacheConfig);
4343
case 7:
44+
case 8:
4445
return new Guzzle7AuthHandler($cache, $cacheConfig);
4546
default:
4647
throw new Exception('Version not supported');

src/Client.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,8 +1258,8 @@ protected function createDefaultHttpClient()
12581258
$options['defaults']['verify'] = '/etc/ca-certificates.crt';
12591259
}
12601260
}
1261-
} elseif (6 === $guzzleVersion || 7 === $guzzleVersion) {
1262-
// guzzle 6 or 7
1261+
} elseif (6 === $guzzleVersion || 7 === $guzzleVersion || 8 === $guzzleVersion) {
1262+
// guzzle 6, 7 or 8
12631263
$options = [
12641264
'base_uri' => $this->config['base_path'],
12651265
'http_errors' => false,

src/Http/REST.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,12 @@ public static function doExecute(ClientInterface $client, RequestInterface $requ
8484
$response = $httpHandler($request);
8585
} catch (RequestException $e) {
8686
// if Guzzle throws an exception, catch it and handle the response
87-
if (!$e->hasResponse()) {
87+
// (on Guzzle 7 the response is on RequestException, but on Guzzle 8
88+
// it is only on its ResponseException subclass)
89+
$response = method_exists($e, 'getResponse') ? $e->getResponse() : null;
90+
if (null === $response) {
8891
throw $e;
8992
}
90-
91-
$response = $e->getResponse();
9293
}
9394

9495
return self::decodeHttpResponse($response, $request, $expectedClass);

tests/Google/ClientTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,13 @@ private function checkAuthHandler($http, $className)
6868
$property = $class->getProperty('stack');
6969
$property->setAccessible(true);
7070
$middlewares = $property->getValue($stack);
71-
$middleware = array_pop($middlewares);
7271

7372
if (null === $className) {
7473
// only the default middlewares have been added
75-
$this->assertCount(3, $middlewares);
74+
$defaultStack = (new GuzzleClient())->getConfig('handler');
75+
$this->assertCount(count($property->getValue($defaultStack)), $middlewares);
7676
} else {
77+
$middleware = array_pop($middlewares);
7778
$authClass = sprintf('Google\Auth\Middleware\%sMiddleware', $className);
7879
$this->assertInstanceOf($authClass, $middleware[0]);
7980
}
@@ -904,7 +905,7 @@ public function testCredentialsOptionWithFetchAuthTokenInterface()
904905
$callable(new Request('GET', '/fake-uri'), ['auth' => 'google_auth']);
905906
});
906907

907-
$httpClient = $this->prophesize('GuzzleHttp\ClientInterface');
908+
$httpClient = $this->prophesize('GuzzleHttp\Client');
908909
$httpClient->getConfig()
909910
->shouldBeCalled()
910911
->willReturn(['handler' => $handler->reveal()]);

tests/Google/Http/RESTTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
use Google\Service\Exception as ServiceException;
2222
use Google\Tests\BaseTest;
2323
use GuzzleHttp\Client as GuzzleClient;
24+
use GuzzleHttp\Exception\ClientException;
25+
use GuzzleHttp\Exception\RequestException;
2426
use GuzzleHttp\Psr7;
2527
use GuzzleHttp\Psr7\Request;
2628
use GuzzleHttp\Psr7\Response;
29+
use Prophecy\Argument;
2730

2831
class RESTTest extends BaseTest
2932
{
@@ -86,6 +89,37 @@ public function testExceptionResponse()
8689
$response = $this->rest->doExecute($http, $request);
8790
}
8891

92+
public function testRequestExceptionWithResponseIsHandled()
93+
{
94+
$this->expectException(ServiceException::class);
95+
$this->expectExceptionCode(400);
96+
97+
$request = new Request('GET', 'http://www.example.com');
98+
$response = new Response(400, [], Psr7\Utils::streamFor('{"error": "bad request"}'));
99+
100+
$http = $this->prophesize('GuzzleHttp\ClientInterface');
101+
$http->send(Argument::type('Psr\Http\Message\RequestInterface'), [])
102+
->shouldBeCalledTimes(1)
103+
->willThrow(new ClientException('Bad Request', $request, $response));
104+
105+
$this->rest->doExecute($http->reveal(), $request);
106+
}
107+
108+
public function testRequestExceptionWithoutResponseIsRethrown()
109+
{
110+
$this->expectException(RequestException::class);
111+
$this->expectExceptionMessage('Request failed');
112+
113+
$request = new Request('GET', 'http://www.example.com');
114+
115+
$http = $this->prophesize('GuzzleHttp\ClientInterface');
116+
$http->send(Argument::type('Psr\Http\Message\RequestInterface'), [])
117+
->shouldBeCalledTimes(1)
118+
->willThrow(new RequestException('Request failed', $request));
119+
120+
$this->rest->doExecute($http->reveal(), $request);
121+
}
122+
89123
public function testDecodeEmptyResponse()
90124
{
91125
$stream = Psr7\Utils::streamFor('{}');

0 commit comments

Comments
 (0)