From ce35ac544d42f47495a274d0643399e9574c0c25 Mon Sep 17 00:00:00 2001 From: Benjamin Browning Date: Wed, 4 Apr 2018 23:09:53 -0400 Subject: [PATCH 001/141] Use safer JSON.parse() instead of eval() Closes #2004 --- tests/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/server.js b/tests/server.js index 3148c354c..6bc858e30 100644 --- a/tests/server.js +++ b/tests/server.js @@ -175,7 +175,7 @@ var GuzzleServer = function(port, log) { } res.writeHead(400, 'NO RESPONSES IN REQUEST', { 'Content-Length': 0 }); } else { - that.responses = eval('(' + request.body + ')'); + that.responses = JSON.parse(request.body); for (var i = 0; i < that.responses.length; i++) { if (that.responses[i].body) { that.responses[i].body = new Buffer(that.responses[i].body, 'base64'); From a17ad8d7b398dd0ab49f8ef98f87cc290fbe3b73 Mon Sep 17 00:00:00 2001 From: Aria Stewart Date: Thu, 12 Apr 2018 13:49:54 -0400 Subject: [PATCH 002/141] Document use of a body with mock responses This was a thing I had to gather from third parties while learning to test Guzzle clients. An example like this would have made it instantly obvious what the API is. --- docs/testing.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/testing.rst b/docs/testing.rst index 0fe6e9725..2ca074a4a 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -32,7 +32,7 @@ a response or exception by shifting return values off of a queue. // Create a mock and queue two responses. $mock = new MockHandler([ - new Response(200, ['X-Foo' => 'Bar']), + new Response(200, ['X-Foo' => 'Bar'], 'Hello, World'), new Response(202, ['Content-Length' => 0]), new RequestException("Error Communicating with Server", new Request('GET', 'test')) ]); @@ -41,8 +41,11 @@ a response or exception by shifting return values off of a queue. $client = new Client(['handler' => $handler]); // The first request is intercepted with the first response. - echo $client->request('GET', '/')->getStatusCode(); + $response = $client->request('GET', '/'); + echo $response->getStatusCode(); //> 200 + echo $response->getBody()->getContents(); + //> Hello, World // The second request is intercepted with the second response. echo $client->request('GET', '/')->getStatusCode(); //> 202 From 0d7c63a663c13c170fcdd8ecb17f8e8b64e6954f Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Mon, 23 Apr 2018 02:33:37 -0300 Subject: [PATCH 003/141] Use assertRegExp Signed-off-by: Gabriel Caruso --- tests/MessageFormatterTest.php | 2 +- tests/functionsTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/MessageFormatterTest.php b/tests/MessageFormatterTest.php index 1e1f5471b..eb4cbfb44 100644 --- a/tests/MessageFormatterTest.php +++ b/tests/MessageFormatterTest.php @@ -38,7 +38,7 @@ public function testFormatsTimestamps($format, $pattern) $f = new MessageFormatter($format); $request = new Request('GET', '/'); $result = $f->format($request); - $this->assertEquals(1, preg_match($pattern, $result)); + $this->assertRegExp($pattern, $result); } public function formatProvider() diff --git a/tests/functionsTest.php b/tests/functionsTest.php index 195965ba7..292a3e847 100644 --- a/tests/functionsTest.php +++ b/tests/functionsTest.php @@ -21,7 +21,7 @@ public function noBodyProvider() public function testProvidesDefaultUserAgent() { $ua = GuzzleHttp\default_user_agent(); - $this->assertEquals(1, preg_match('#^GuzzleHttp/.+ curl/.+ PHP/.+$#', $ua)); + $this->assertRegExp('#^GuzzleHttp/.+ curl/.+ PHP/.+$#', $ua); } public function typeProvider() From 2e7aec0b445fb51e58b02b15c85a69d84abc13db Mon Sep 17 00:00:00 2001 From: Alessandro Minoccheri Date: Mon, 23 Apr 2018 09:47:05 +0200 Subject: [PATCH 004/141] split some long lines in many --- src/Handler/StreamHandler.php | 16 ++++++++++++++-- tests/Cookie/CookieJarTest.php | 10 ++++++++-- tests/Handler/CurlFactoryTest.php | 5 ++++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Handler/StreamHandler.php b/src/Handler/StreamHandler.php index b686545ea..8e9bc889b 100644 --- a/src/Handler/StreamHandler.php +++ b/src/Handler/StreamHandler.php @@ -343,13 +343,25 @@ private function resolveHost(RequestInterface $request, array $options) if ('v4' === $options['force_ip_resolve']) { $records = dns_get_record($uri->getHost(), DNS_A); if (!isset($records[0]['ip'])) { - throw new ConnectException(sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request); + throw new ConnectException( + sprintf( + "Could not resolve IPv4 address for host '%s'", + $uri->getHost() + ), + $request + ); } $uri = $uri->withHost($records[0]['ip']); } elseif ('v6' === $options['force_ip_resolve']) { $records = dns_get_record($uri->getHost(), DNS_AAAA); if (!isset($records[0]['ipv6'])) { - throw new ConnectException(sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request); + throw new ConnectException( + sprintf( + "Could not resolve IPv6 address for host '%s'", + $uri->getHost() + ), + $request + ); } $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']'); } diff --git a/tests/Cookie/CookieJarTest.php b/tests/Cookie/CookieJarTest.php index dbdc56646..dc2fbd9b5 100644 --- a/tests/Cookie/CookieJarTest.php +++ b/tests/Cookie/CookieJarTest.php @@ -394,8 +394,14 @@ public function getCookiePathsDataProvider() public function testCookiePathWithEmptySetCookiePath($uriPath, $cookiePath) { $response = (new Response(200)) - ->withAddedHeader('Set-Cookie', "foo=bar; expires=Fri, 02-Mar-2019 02:17:40 GMT; domain=www.example.com; path=;") - ->withAddedHeader('Set-Cookie', "bar=foo; expires=Fri, 02-Mar-2019 02:17:40 GMT; domain=www.example.com; path=foobar;") + ->withAddedHeader( + 'Set-Cookie', + "foo=bar; expires=Fri, 02-Mar-2019 02:17:40 GMT; domain=www.example.com; path=;" + ) + ->withAddedHeader( + 'Set-Cookie', + "bar=foo; expires=Fri, 02-Mar-2019 02:17:40 GMT; domain=www.example.com; path=foobar;" + ) ; $request = (new Request('GET', $uriPath))->withHeader('Host', 'www.example.com'); $this->jar->extractCookies($request, $response); diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index ce29978ac..a145bbc41 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -340,7 +340,10 @@ public function testDecodesGzippedResponsesWithHeader() $this->assertEquals('gzip', $sent->getHeaderLine('Accept-Encoding')); $this->assertEquals('test', (string) $response->getBody()); $this->assertFalse($response->hasHeader('content-encoding')); - $this->assertTrue(!$response->hasHeader('content-length') || $response->getHeaderLine('content-length') == $response->getBody()->getSize()); + $this->assertTrue( + !$response->hasHeader('content-length') || + $response->getHeaderLine('content-length') == $response->getBody()->getSize() + ); } public function testDoesNotForceDecode() From f0854566852cdced6b1ab850deaadd138283ffc7 Mon Sep 17 00:00:00 2001 From: MikeLund Date: Thu, 14 Jun 2018 15:09:55 +0200 Subject: [PATCH 005/141] Update curl.haxx.se URL --- src/Handler/CurlFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index e09237143..ee4ec3539 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -177,7 +177,7 @@ private static function createRejection(EasyHandle $easy, array $ctx) 'cURL error %s: %s (%s)', $ctx['errno'], $ctx['error'], - 'see http://curl.haxx.se/libcurl/c/libcurl-errors.html' + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' ); // Create a connection exception if it was a specific error code. From 40b94a3e906a764189bd309555eed3aa9020a04f Mon Sep 17 00:00:00 2001 From: Jos Ahrens Date: Wed, 23 May 2018 17:37:14 +0000 Subject: [PATCH 006/141] docs/quickstart: add Exception Tree View (#2055) Add a tree view to the quickstart documentation for Exceptions Closes #2055 --- docs/quickstart.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index d4e9a8231..37ad206e6 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -483,6 +483,23 @@ The following example shows that redirects can be disabled. Exceptions ========== +**Tree View** + +The following tree view describes how the Guzzle Exceptions depend +on eachother. + +.. code-block:: none + + . \RuntimeException + ├── SeekException (implements GuzzleException) + └── TransferException (implements GuzzleException) + └── RequestException + ├── BadResponseException + │   ├── ServerException + │ └── ClientException + ├── ConnectionException + └── TooManyRedirectsException + Guzzle throws exceptions for errors that occur during a transfer. - In the event of a networking error (connection timeout, DNS errors, etc.), From 003757426cdd50fbad1c34cdbcc8a55f70a4fe8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20S=C3=A1gi-Kaz=C3=A1r?= Date: Sat, 23 Jun 2018 23:34:47 +0200 Subject: [PATCH 007/141] Fix typo --- docs/quickstart.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 37ad206e6..16be901c8 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -486,7 +486,7 @@ Exceptions **Tree View** The following tree view describes how the Guzzle Exceptions depend -on eachother. +on each other. .. code-block:: none From 6ca1f10bdbc490d1b7927c951e55881a62b0444d Mon Sep 17 00:00:00 2001 From: Dominik Hajduk Date: Mon, 25 Jun 2018 13:32:10 +0200 Subject: [PATCH 008/141] Fix guzzle 3 docs broken link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bcd18b8e7..58f54277b 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,6 @@ composer.phar update [guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3 [guzzle-6-repo]: https://github.com/guzzle/guzzle -[guzzle-3-docs]: http://guzzle3.readthedocs.org/en/latest/ +[guzzle-3-docs]: http://guzzle3.readthedocs.org [guzzle-5-docs]: http://guzzle.readthedocs.org/en/5.3/ [guzzle-6-docs]: http://guzzle.readthedocs.org/en/latest/ From 8eb20b4470bbe5dbf9f2cda1a290a3e7aadeba7c Mon Sep 17 00:00:00 2001 From: Tarjei Huse Date: Fri, 27 Jul 2018 08:08:03 +0200 Subject: [PATCH 009/141] Clean up variable naming to make docs a bit clearer Hope it's ok ;) --- docs/testing.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/testing.rst b/docs/testing.rst index 0fe6e9725..49d42f13d 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -37,8 +37,8 @@ a response or exception by shifting return values off of a queue. new RequestException("Error Communicating with Server", new Request('GET', 'test')) ]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); + $handlerStack = HandlerStack::create($mock); + $client = new Client(['handler' => $handlerStack]); // The first request is intercepted with the first response. echo $client->request('GET', '/')->getStatusCode(); @@ -68,11 +68,13 @@ history of the requests that were sent by a client. $container = []; $history = Middleware::history($container); - $stack = HandlerStack::create(); + $handlerStack = HandlerStack::create(); + // or $handlerStack = HandlerStack::create($mock); if using the Mock handler. + // Add the history middleware to the handler stack. - $stack->push($history); + $handlerStack->push($history); - $client = new Client(['handler' => $stack]); + $client = new Client(['handler' => $handlerStack]); $client->request('GET', 'http://httpbin.org/get'); $client->request('HEAD', 'http://httpbin.org/get'); From 634baabf146dcf5c653e4b718a13e47a2cffed21 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Mon, 30 Jul 2018 11:07:04 -0500 Subject: [PATCH 010/141] Correct reference to undefined default handler The default handler is created with `HandlerStack::create()`. --- docs/request-options.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/request-options.rst b/docs/request-options.rst index 2dfc86b1a..7fbeeaa3e 100644 --- a/docs/request-options.rst +++ b/docs/request-options.rst @@ -118,7 +118,7 @@ pairs: This option only has an effect if your handler has the ``GuzzleHttp\Middleware::redirect`` middleware. This middleware is added by default when a client is created with no handler, and is added by - default when creating a handler with ``GuzzleHttp\default_handler``. + default when creating a handler with ``GuzzleHttp\HandlerStack::create``. auth From bd368857d54081a9eeaea3c0ecfcb4e10455e56b Mon Sep 17 00:00:00 2001 From: Wulfric Wang Date: Tue, 17 Jul 2018 18:11:41 +0800 Subject: [PATCH 011/141] curl error msg for low version --- src/Handler/CurlFactory.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index ee4ec3539..e6d055cb0 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -174,10 +174,11 @@ private static function createRejection(EasyHandle $easy, array $ctx) } $message = sprintf( - 'cURL error %s: %s (%s)', + 'cURL error %s: %s (%s) for %s', $ctx['errno'], $ctx['error'], - 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', + $easy->request->getUri() ); // Create a connection exception if it was a specific error code. From bcfa6bad7b0e631dbae2403c0d22780655646cef Mon Sep 17 00:00:00 2001 From: Wulfric Wang Date: Fri, 3 Aug 2018 12:05:09 +0800 Subject: [PATCH 012/141] curl error msg for low version --- src/Handler/CurlFactory.php | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index e6d055cb0..8fb3bbb7d 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -14,6 +14,8 @@ */ class CurlFactory implements CurlFactoryInterface { + private const CURL_VERSION_STR = 'curl_version'; + private const LOW_CURL_VERSION_NUMBER = '7.21.2'; /** @var array */ private $handles = []; @@ -137,6 +139,7 @@ private static function finishError( 'errno' => $easy->errno, 'error' => curl_error($easy->handle), ] + curl_getinfo($easy->handle); + $ctx[self::CURL_VERSION_STR] = curl_version()['version']; $factory->release($easy); // Retry when nothing is present or when curl failed to rewind. @@ -172,14 +175,22 @@ private static function createRejection(EasyHandle $easy, array $ctx) ) ); } - - $message = sprintf( - 'cURL error %s: %s (%s) for %s', - $ctx['errno'], - $ctx['error'], - 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', - $easy->request->getUri() - ); + if (version_compare($ctx[self::CURL_VERSION_STR], self::LOW_CURL_VERSION_NUMBER)) { + $message = sprintf( + 'cURL error %s: %s (%s)', + $ctx['errno'], + $ctx['error'], + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', + ); + } else { + $message = sprintf( + 'cURL error %s: %s (%s) for %s', + $ctx['errno'], + $ctx['error'], + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', + $easy->request->getUri() + ); + } // Create a connection exception if it was a specific error code. $error = isset($connectionErrors[$easy->errno]) From 909ac9b2c4e8e04b15dfcf87b653a46c12401769 Mon Sep 17 00:00:00 2001 From: Wulfric Wang Date: Fri, 3 Aug 2018 12:18:02 +0800 Subject: [PATCH 013/141] curl error msg for low version --- src/Handler/CurlFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index 8fb3bbb7d..53aa6bc3f 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -180,7 +180,7 @@ private static function createRejection(EasyHandle $easy, array $ctx) 'cURL error %s: %s (%s)', $ctx['errno'], $ctx['error'], - 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' ); } else { $message = sprintf( From 5c7a5c524e556113e7f8685e6880cbc4090c798d Mon Sep 17 00:00:00 2001 From: SpacePossum Date: Wed, 8 Aug 2018 06:37:00 +0200 Subject: [PATCH 014/141] RequestException - check if readable before access (#2081) * check if readable before access * Add unit tests for RequestException::getResponseBodySummary * use real object in test * update test for older PHP version support * remove no longer used imports * Update RequestExceptionTest.php --- src/Exception/RequestException.php | 2 +- tests/Exception/RequestExceptionTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Exception/RequestException.php b/src/Exception/RequestException.php index 39de327e7..f38ca8646 100644 --- a/src/Exception/RequestException.php +++ b/src/Exception/RequestException.php @@ -126,7 +126,7 @@ public static function getResponseBodySummary(ResponseInterface $response) { $body = $response->getBody(); - if (!$body->isSeekable()) { + if (!$body->isSeekable() || !$body->isReadable()) { return null; } diff --git a/tests/Exception/RequestExceptionTest.php b/tests/Exception/RequestExceptionTest.php index 6f70b3985..f72caf0f5 100644 --- a/tests/Exception/RequestExceptionTest.php +++ b/tests/Exception/RequestExceptionTest.php @@ -4,6 +4,7 @@ use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; +use GuzzleHttp\Psr7\Stream; use PHPUnit\Framework\TestCase; /** @@ -174,4 +175,27 @@ public function testObfuscateUrlWithUsernameAndPassword() $e = RequestException::create($r, new Response(500)); $this->assertContains('http://user:***@www.oo.com', $e->getMessage()); } + + public function testGetResponseBodySummaryOfNonReadableStream() + { + $this->assertNull(RequestException::getResponseBodySummary(new Response(500, [], new ReadSeekOnlyStream()))); + } +} + +final class ReadSeekOnlyStream extends Stream +{ + public function __construct() + { + parent::__construct(fopen('php://memory', 'wb')); + } + + public function isSeekable() + { + return true; + } + + public function isReadable() + { + return false; + } } From 05f9f3b9f928c7fe051382b26102b4c4e41fb61c Mon Sep 17 00:00:00 2001 From: Daniel Espendiller Date: Fri, 7 Sep 2018 19:54:47 +0200 Subject: [PATCH 015/141] Using single qoute in testing documentation (#2138) To make qoute documentation consistently use single qoute in Mock Handler section --- docs/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/testing.rst b/docs/testing.rst index 49d42f13d..5ac06691b 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -34,7 +34,7 @@ a response or exception by shifting return values off of a queue. $mock = new MockHandler([ new Response(200, ['X-Foo' => 'Bar']), new Response(202, ['Content-Length' => 0]), - new RequestException("Error Communicating with Server", new Request('GET', 'test')) + new RequestException('Error Communicating with Server', new Request('GET', 'test')) ]); $handlerStack = HandlerStack::create($mock); From dc4532af49621506d7e933fcdb61550b78fcb7e4 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Wed, 12 Sep 2018 17:44:37 +0200 Subject: [PATCH 016/141] Add a docker file for quickly testing snippets --- Dockerfile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..efc11656f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM composer:latest as setup + +RUN mkdir /guzzle + +WORKDIR /guzzle + +RUN set -xe \ + && composer init --name=guzzlehttp/test --description="Simple project for testing Guzzle scripts" --author="Márk Sági-Kazár " --no-interaction \ + && composer require guzzlehttp/guzzle + + +FROM php:7.2 + +RUN mkdir /guzzle + +WORKDIR /guzzle + +COPY --from=setup /guzzle /guzzle From c7faf23816251ca3f35463c55f3178a9b60128fc Mon Sep 17 00:00:00 2001 From: Nicolas CARPi Date: Wed, 12 Sep 2018 17:59:05 +0200 Subject: [PATCH 017/141] Fix minor errors and doc comments (#2120) * Fix minor errors and doc comments * 2 anonymous functions were declaring using a variable that wasn't used in the end, so this has been removed * The 'delay' field of RetryMiddleware was not declared * new TransferStats was called with 0 instead of null * incorrect type was supplied to withHeader() * various DocComments fixes * revert back to 0 --- src/Cookie/CookieJar.php | 2 +- src/Handler/StreamHandler.php | 2 +- src/HandlerStack.php | 8 ++++---- src/Middleware.php | 2 +- src/RetryMiddleware.php | 5 ++++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Cookie/CookieJar.php b/src/Cookie/CookieJar.php index 78f2b79fe..286264261 100644 --- a/src/Cookie/CookieJar.php +++ b/src/Cookie/CookieJar.php @@ -120,7 +120,7 @@ public function clear($domain = null, $path = null, $name = null) } elseif (!$path) { $this->cookies = array_filter( $this->cookies, - function (SetCookie $cookie) use ($path, $domain) { + function (SetCookie $cookie) use ($domain) { return !$cookie->matchesDomain($domain); } ); diff --git a/src/Handler/StreamHandler.php b/src/Handler/StreamHandler.php index 8e9bc889b..741e02d2a 100644 --- a/src/Handler/StreamHandler.php +++ b/src/Handler/StreamHandler.php @@ -42,7 +42,7 @@ public function __invoke(RequestInterface $request, array $options) // Append a content-length header if body size is zero to match // cURL's behavior. if (0 === $request->getBody()->getSize()) { - $request = $request->withHeader('Content-Length', 0); + $request = $request->withHeader('Content-Length', '0'); } return $this->createResponse( diff --git a/src/HandlerStack.php b/src/HandlerStack.php index 24c46fd9f..f0016861e 100644 --- a/src/HandlerStack.php +++ b/src/HandlerStack.php @@ -206,7 +206,7 @@ public function resolve() } /** - * @param $name + * @param string $name * @return int */ private function findByName($name) @@ -223,10 +223,10 @@ private function findByName($name) /** * Splices a function into the middleware list at a specific position. * - * @param $findName - * @param $withName + * @param string $findName + * @param string $withName * @param callable $middleware - * @param $before + * @param bool $before */ private function splice($findName, $withName, callable $middleware, $before) { diff --git a/src/Middleware.php b/src/Middleware.php index d4ad75c94..2d762a01a 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -58,7 +58,7 @@ public static function httpErrors() return $handler($request, $options); } return $handler($request, $options)->then( - function (ResponseInterface $response) use ($request, $handler) { + function (ResponseInterface $response) use ($request) { $code = $response->getStatusCode(); if ($code < 400) { return $response; diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php index f27090fd1..7d40ecaf8 100644 --- a/src/RetryMiddleware.php +++ b/src/RetryMiddleware.php @@ -19,6 +19,9 @@ class RetryMiddleware /** @var callable */ private $decider; + /** @var callable */ + private $delay; + /** * @param callable $decider Function that accepts the number of retries, * a request, [response], and [exception] and @@ -42,7 +45,7 @@ public function __construct( /** * Default exponential backoff delay function. * - * @param $retries + * @param int $retries * * @return int */ From 6e0945c536f5902e7ce6231bb9091ef0e225855a Mon Sep 17 00:00:00 2001 From: Jason Moore Date: Wed, 3 Oct 2018 14:23:23 -0500 Subject: [PATCH 018/141] Change provider method prefix to provider --- tests/Cookie/FileCookieJarTest.php | 4 ++-- tests/Cookie/SessionCookieJarTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Cookie/FileCookieJarTest.php b/tests/Cookie/FileCookieJarTest.php index af378f403..f93ab37fe 100644 --- a/tests/Cookie/FileCookieJarTest.php +++ b/tests/Cookie/FileCookieJarTest.php @@ -34,7 +34,7 @@ public function testLoadsFromFile() } /** - * @dataProvider testPersistsToFileFileParameters + * @dataProvider providerPersistsToFileFileParameters */ public function testPersistsToFile($testSaveSessionCookie = false) { @@ -78,7 +78,7 @@ public function testPersistsToFile($testSaveSessionCookie = false) unlink($this->file); } - public function testPersistsToFileFileParameters() + public function providerPersistsToFileFileParameters() { return array( array(false), diff --git a/tests/Cookie/SessionCookieJarTest.php b/tests/Cookie/SessionCookieJarTest.php index 8d6024a51..20bea8440 100644 --- a/tests/Cookie/SessionCookieJarTest.php +++ b/tests/Cookie/SessionCookieJarTest.php @@ -38,7 +38,7 @@ public function testLoadsFromSession() } /** - * @dataProvider testPersistsToSessionParameters + * @dataProvider providerPersistsToSessionParameters */ public function testPersistsToSession($testSaveSessionCookie = false) { @@ -82,7 +82,7 @@ public function testPersistsToSession($testSaveSessionCookie = false) unset($_SESSION[$this->sessionVar]); } - public function testPersistsToSessionParameters() + public function providerPersistsToSessionParameters() { return array( array(false), From edd4607e02308f525e5cf695d7de35d98498a786 Mon Sep 17 00:00:00 2001 From: Jason Moore Date: Wed, 3 Oct 2018 14:24:58 -0500 Subject: [PATCH 019/141] Add assertions --- tests/Handler/CurlHandlerTest.php | 4 ++-- tests/Handler/CurlMultiHandlerTest.php | 5 +++++ tests/Handler/StreamHandlerTest.php | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/Handler/CurlHandlerTest.php b/tests/Handler/CurlHandlerTest.php index 8c380fa3b..25c499020 100644 --- a/tests/Handler/CurlHandlerTest.php +++ b/tests/Handler/CurlHandlerTest.php @@ -37,8 +37,8 @@ public function testReusesHandles() Server::enqueue([$response, $response]); $a = new CurlHandler(); $request = new Request('GET', Server::$url); - $a($request, []); - $a($request, []); + $this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $a($request, [])); + $this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $a($request, [])); } public function testDoesSleep() diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index e9b140651..945ea8992 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -46,6 +46,10 @@ public function testCanCancel() $response->cancel(); $responses[] = $response; } + + foreach($responses as $r) { + $this->assertEquals('rejected', $response->getState()); + } } public function testCannotCancelFinished() @@ -56,6 +60,7 @@ public function testCannotCancelFinished() $response = $a(new Request('GET', Server::$url), []); $response->wait(); $response->cancel(); + $this->assertEquals('fulfilled', $response->getState()); } public function testDelaysConcurrently() diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index 208c48893..0c97e6820 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -307,7 +307,8 @@ public function testVerifiesVerifyIsValidIfPath() public function testVerifyCanBeDisabled() { - $this->getSendResult(['verify' => false]); + $handler = $this->getSendResult(['verify' => false]); + $this->assertInstanceOf('GuzzleHttp\Psr7\Response', $handler); } /** @@ -337,6 +338,8 @@ public function testUsesSystemDefaultBundle() $opts = stream_context_get_options($res->getBody()->detach()); if (PHP_VERSION_ID < 50600) { $this->assertEquals($path, $opts['ssl']['cafile']); + } else { + $this->assertArrayNotHasKey('cafile', $opts['ssl']); } } From cc362add6b24222ff235c24cd7c424487f1ae676 Mon Sep 17 00:00:00 2001 From: Jason Moore Date: Wed, 3 Oct 2018 14:25:28 -0500 Subject: [PATCH 020/141] Add annotations so tests aren't marked as risky --- tests/HandlerStackTest.php | 3 +++ tests/PoolTest.php | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/tests/HandlerStackTest.php b/tests/HandlerStackTest.php index 1d86c356f..b7489864a 100644 --- a/tests/HandlerStackTest.php +++ b/tests/HandlerStackTest.php @@ -18,6 +18,9 @@ public function testSetsHandlerInCtor() $this->assertTrue($h->hasHandler()); } + /** + * @doesNotPerformAssertions + */ public function testCanSetDifferentHandlerAfterConstruction() { $f = function () {}; diff --git a/tests/PoolTest.php b/tests/PoolTest.php index 3d3d22589..f2ba94308 100644 --- a/tests/PoolTest.php +++ b/tests/PoolTest.php @@ -34,6 +34,9 @@ public function testValidatesEachElement() $p->promise()->wait(); } + /** + * @doesNotPerformAssertions + */ public function testSendsAndRealizesFuture() { $c = $this->getClient(); @@ -41,6 +44,9 @@ public function testSendsAndRealizesFuture() $p->promise()->wait(); } + /** + * @doesNotPerformAssertions + */ public function testExecutesPendingWhenWaiting() { $r1 = new Promise(function () use (&$r1) { $r1->resolve(new Response()); }); From 4b2604b28462caff965476786291d84f00ee0099 Mon Sep 17 00:00:00 2001 From: neghmurken Date: Wed, 3 Oct 2018 21:44:25 +0200 Subject: [PATCH 021/141] Add documentation for cookies --- docs/quickstart.rst | 49 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 16be901c8..eb6d69838 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -184,10 +184,10 @@ requests. 'webp' => $client->getAsync('/image/webp') ]; - // Wait on all of the requests to complete. Throws a ConnectException + // Wait on all of the requests to complete. Throws a ConnectException // if any of the requests fail $results = Promise\unwrap($promises); - + // Wait for the requests to complete, even if some of them fail $results = Promise\settle($promises)->wait(); @@ -229,7 +229,7 @@ amount of requests you wish to send. // Force the pool of requests to complete. $promise->wait(); - + Or using a closure that will return a promise once the pool calls the closure. .. code-block:: php @@ -246,7 +246,7 @@ Or using a closure that will return a promise once the pool calls the closure. }; $pool = new Pool($client, $requests(100)); - + Using Responses =============== @@ -447,6 +447,43 @@ to use a shared cookie jar for all requests. $client = new \GuzzleHttp\Client(['cookies' => true]); $r = $client->request('GET', 'http://httpbin.org/cookies'); +Different implementations exist for the ``GuzzleHttp\Cookie\CookieJarInterface`` +: + +- The ``GuzzleHttp\Cookie\CookieJar`` class stores cookies as an array. +- The ``GuzzleHttp\Cookie\FileCookieJar`` class persists non-session cookies + using a JSON formatted file. +- The ``GuzzleHttp\Cookie\SessionCookieJar`` class persists cookies in the + client session. + +You can manually set cookies into a cookie jar with the named constructor +``fromArray(array $cookies, $domain)``. + +.. code-block:: php + + $jar = \GuzzleHttp\Cookie\CookieJar::fromArray( + [ + 'some_cookie' => 'foo', + 'other_cookie' => 'barbaz1234' + ], + 'example.org' + ); + +You can get a cookie by its name with the ``getCookieByName($name)`` method +which returns a ``GuzzleHttp\Cookie\SetCookie`` instance. + +.. code-block:: php + + $cookie = $jar->getCookieByName('some_cookie'); + + $cookie->getValue(); // 'foo' + $cookie->getDomain(); // 'example.org' + $cookie->getExpires(); // expiration date as a Unix timestamp + +The cookies can be also fetched into an array thanks to the `toArray()` method. +The ``GuzzleHttp\Cookie\CookieJarInterface`` interface extends +``Traversable`` so it can be iterated in a foreach loop. + Redirects ========= @@ -499,7 +536,7 @@ on each other. │ └── ClientException ├── ConnectionException └── TooManyRedirectsException - + Guzzle throws exceptions for errors that occur during a transfer. - In the event of a networking error (connection timeout, DNS errors, etc.), @@ -568,7 +605,7 @@ behavior of the library. the timeout. ``HTTP_PROXY`` Defines the proxy to use when sending requests using the "http" protocol. - + Note: because the HTTP_PROXY variable may contain arbitrary user input on some (CGI) environments, the variable is only used on the CLI SAPI. See https://httpoxy.org for more information. ``HTTPS_PROXY`` Defines the proxy to use when sending requests using the "https" protocol. From ef4490a9ab201dca751121dc3e9e7f0c9365c761 Mon Sep 17 00:00:00 2001 From: Nicolas MURE Date: Thu, 4 Oct 2018 15:03:31 +0200 Subject: [PATCH 022/141] doc : typehint Pool's 'fulfilled' and 'rejected' callbacks --- docs/quickstart.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index eb6d69838..203970bc0 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -201,9 +201,11 @@ amount of requests you wish to send. .. code-block:: php - use GuzzleHttp\Pool; use GuzzleHttp\Client; + use GuzzleHttp\Exception\RequestException; + use GuzzleHttp\Pool; use GuzzleHttp\Psr7\Request; + use GuzzleHttp\Psr7\Response; $client = new Client(); @@ -216,10 +218,10 @@ amount of requests you wish to send. $pool = new Pool($client, $requests(100), [ 'concurrency' => 5, - 'fulfilled' => function ($response, $index) { + 'fulfilled' => function (Response $response, $index) { // this is delivered each successful response }, - 'rejected' => function ($reason, $index) { + 'rejected' => function (RequestException $reason, $index) { // this is delivered each failed request }, ]); @@ -481,7 +483,7 @@ which returns a ``GuzzleHttp\Cookie\SetCookie`` instance. $cookie->getExpires(); // expiration date as a Unix timestamp The cookies can be also fetched into an array thanks to the `toArray()` method. -The ``GuzzleHttp\Cookie\CookieJarInterface`` interface extends +The ``GuzzleHttp\Cookie\CookieJarInterface`` interface extends ``Traversable`` so it can be iterated in a foreach loop. From 5a3f1414e2ee11d9aaf3a638f1a0c85f8019b469 Mon Sep 17 00:00:00 2001 From: Jason Moore Date: Thu, 4 Oct 2018 08:59:48 -0500 Subject: [PATCH 023/141] Add support for documented environment variable. Closes #2136 --- src/Handler/CurlMultiHandler.php | 10 ++++++++-- tests/Handler/CurlMultiHandlerTest.php | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Handler/CurlMultiHandler.php b/src/Handler/CurlMultiHandler.php index 2754d8e43..7097835d1 100644 --- a/src/Handler/CurlMultiHandler.php +++ b/src/Handler/CurlMultiHandler.php @@ -37,8 +37,14 @@ public function __construct(array $options = []) { $this->factory = isset($options['handle_factory']) ? $options['handle_factory'] : new CurlFactory(50); - $this->selectTimeout = isset($options['select_timeout']) - ? $options['select_timeout'] : 1; + + if (isset($options['select_timeout'])) { + $this->selectTimeout = $options['select_timeout']; + } elseif ($selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { + $this->selectTimeout = $selectTimeout; + } else { + $this->selectTimeout = 1; + } } public function __get($name) diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 945ea8992..5aaa2d6bc 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -74,6 +74,20 @@ public function testDelaysConcurrently() $this->assertGreaterThanOrEqual($expected, microtime(true)); } + public function testUsesTimeoutEnvironmentVariables() + { + $a = new CurlMultiHandler(); + + //default if no options are given and no environment variable is set + $this->assertEquals(1, $this->readAttribute($a, 'selectTimeout')); + + putenv("GUZZLE_CURL_SELECT_TIMEOUT=3"); + $a = new CurlMultiHandler(); + $selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT'); + //Handler reads from the environment if no options are given + $this->assertEquals($selectTimeout, $this->readAttribute($a, 'selectTimeout')); + } + /** * @expectedException \BadMethodCallException */ From 00a56572161f26252d43f1e263dc8926408a954e Mon Sep 17 00:00:00 2001 From: Jason Moore Date: Thu, 4 Oct 2018 09:00:25 -0500 Subject: [PATCH 024/141] Add to list of supported environment variables --- docs/quickstart.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index eb6d69838..e0e6c4971 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -609,6 +609,8 @@ behavior of the library. Note: because the HTTP_PROXY variable may contain arbitrary user input on some (CGI) environments, the variable is only used on the CLI SAPI. See https://httpoxy.org for more information. ``HTTPS_PROXY`` Defines the proxy to use when sending requests using the "https" protocol. +``NO_PROXY`` + Defines URLs for which a proxy should not be used. See :ref:`proxy-option` for usage. Relevant ini Settings From 3e6a823b48c3d19ed0ecf2ce0916e284357a4e65 Mon Sep 17 00:00:00 2001 From: George Mponos Date: Sat, 6 Oct 2018 14:41:00 +0300 Subject: [PATCH 025/141] Add invalid argument exception --- src/Exception/InvalidArgumentException.php | 5 +++++ src/functions.php | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 src/Exception/InvalidArgumentException.php diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..7ce5294cb --- /dev/null +++ b/src/Exception/InvalidArgumentException.php @@ -0,0 +1,5 @@ + Date: Sun, 7 Oct 2018 01:36:52 -0300 Subject: [PATCH 026/141] Move null typehint on the last position --- src/Cookie/SetCookie.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cookie/SetCookie.php b/src/Cookie/SetCookie.php index f6993943e..3d776a70b 100644 --- a/src/Cookie/SetCookie.php +++ b/src/Cookie/SetCookie.php @@ -227,7 +227,7 @@ public function setExpires($timestamp) /** * Get whether or not this is a secure cookie * - * @return null|bool + * @return bool|null */ public function getSecure() { @@ -247,7 +247,7 @@ public function setSecure($secure) /** * Get whether or not this is a session cookie * - * @return null|bool + * @return bool|null */ public function getDiscard() { From a759c5621240718a18813fb6b2bf4621195bb57f Mon Sep 17 00:00:00 2001 From: Marcos Felipe Date: Sun, 7 Oct 2018 01:44:39 -0300 Subject: [PATCH 027/141] Adds typehint in method equals phpDocs --- src/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 80417918d..0f43c71f0 100644 --- a/src/Client.php +++ b/src/Client.php @@ -210,7 +210,7 @@ private function configureDefaults(array $config) * * @return array */ - private function prepareDefaults($options) + private function prepareDefaults(array $options) { $defaults = $this->config; From 97b2bc9adb4eff9c2bc31a514fadf3270b53a89e Mon Sep 17 00:00:00 2001 From: Mponos George Date: Tue, 16 Oct 2018 08:39:40 +0300 Subject: [PATCH 028/141] Update InvalidArgumentException.php --- src/Exception/InvalidArgumentException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 7ce5294cb..15b7f9137 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -2,4 +2,4 @@ namespace GuzzleHttp\Exception; -class InvalidArgumentException extends \InvalidArgumentException implements GuzzleException {} \ No newline at end of file +final class InvalidArgumentException extends \InvalidArgumentException implements GuzzleException {} From 636b6b2ec9037713c9cc4a7f30c322de5e26f3c7 Mon Sep 17 00:00:00 2001 From: Darryl Hein Date: Fri, 26 Oct 2018 20:12:33 -0600 Subject: [PATCH 029/141] add use statement --- docs/quickstart.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index eb6d69838..9b69a94d5 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -571,6 +571,7 @@ Guzzle throws exceptions for errors that occur during a transfer. .. code-block:: php + use GuzzleHttp\Psr7; use GuzzleHttp\Exception\ClientException; try { From 44e0c5ca71709183ea75ab9cc936e86d93cfe891 Mon Sep 17 00:00:00 2001 From: Andrey Bolonin Date: Sat, 27 Oct 2018 11:23:53 +0300 Subject: [PATCH 030/141] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 94159e79f..6f3ef75e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ php: - 7.0 - 7.1 - 7.2 + - 7.3 - nightly before_script: From 6c6d4459113cb19169b868c429432999a5450e1f Mon Sep 17 00:00:00 2001 From: Anna Sidwell Date: Tue, 30 Oct 2018 13:40:22 +0000 Subject: [PATCH 031/141] Use GuzzleHttp's include-guarded functions (#2135) --- build/packager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/packager.php b/build/packager.php index 9d6d21317..f0316e234 100644 --- a/build/packager.php +++ b/build/packager.php @@ -18,9 +18,9 @@ $packager->recursiveCopy('vendor/psr/http-message/src', 'Psr/Http/Message'); $packager->createAutoloader([ - 'GuzzleHttp/functions.php', - 'GuzzleHttp/Psr7/functions.php', - 'GuzzleHttp/Promise/functions.php', + 'GuzzleHttp/functions_include.php', + 'GuzzleHttp/Psr7/functions_include.php', + 'GuzzleHttp/Promise/functions_include.php', ]); $packager->createPhar(__DIR__ . '/artifacts/guzzle.phar'); From ffc61ebd8d5ce30f129fde277ba3c23e658c2742 Mon Sep 17 00:00:00 2001 From: George Mponos Date: Wed, 31 Oct 2018 22:40:38 +0200 Subject: [PATCH 032/141] Fix wrong namespaces --- tests/Exception/ConnectExceptionTest.php | 4 ++-- tests/Exception/RequestExceptionTest.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Exception/ConnectExceptionTest.php b/tests/Exception/ConnectExceptionTest.php index e518c0dcb..8ab945ec7 100644 --- a/tests/Exception/ConnectExceptionTest.php +++ b/tests/Exception/ConnectExceptionTest.php @@ -1,12 +1,12 @@ assertSame($req, $e->getRequest()); $this->assertSame($res, $e->getResponse()); $this->assertTrue($e->hasResponse()); - $this->assertEquals('foo', $e->getMessage()); + $this->assertSame('foo', $e->getMessage()); } public function testCreatesGenerateException() { $e = RequestException::create(new Request('GET', '/')); - $this->assertEquals('Error completing request', $e->getMessage()); + $this->assertSame('Error completing request', $e->getMessage()); $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); } From 3c4f9564a8f235d6a8b0e27d20195e213ce4983f Mon Sep 17 00:00:00 2001 From: yuuri111 Date: Fri, 2 Nov 2018 00:59:25 +0900 Subject: [PATCH 033/141] update exceptions doc from Connection to Connect ConnectionException does not exist. --- docs/quickstart.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 9b69a94d5..1ff812205 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -534,7 +534,7 @@ on each other. ├── BadResponseException │   ├── ServerException │ └── ClientException - ├── ConnectionException + ├── ConnectException └── TooManyRedirectsException Guzzle throws exceptions for errors that occur during a transfer. From cf86e51dd6331187c0a5dfe03d15ef7950199b63 Mon Sep 17 00:00:00 2001 From: Mponos George Date: Thu, 1 Nov 2018 23:47:08 +0200 Subject: [PATCH 034/141] Remove assertEquals in favor of assertSame (#2188) --- tests/ClientTest.php | 82 ++++++++-------- tests/Cookie/CookieJarTest.php | 10 +- tests/Cookie/FileCookieJarTest.php | 2 +- tests/Cookie/SessionCookieJarTest.php | 2 +- tests/Cookie/SetCookieTest.php | 38 ++++---- tests/Exception/ConnectExceptionTest.php | 4 +- tests/Exception/RequestExceptionTest.php | 4 +- tests/Handler/CurlFactoryTest.php | 42 ++++---- tests/Handler/CurlMultiHandlerTest.php | 6 +- tests/Handler/MockHandlerTest.php | 2 +- tests/Handler/StreamHandlerTest.php | 116 +++++++++++------------ tests/HandlerStackTest.php | 16 ++-- tests/MessageFormatterTest.php | 2 +- tests/MiddlewareTest.php | 30 +++--- tests/PoolTest.php | 8 +- tests/PrepareBodyMiddlewareTest.php | 18 ++-- tests/RedirectMiddlewareTest.php | 32 +++---- tests/RetryMiddlewareTest.php | 24 ++--- tests/TransferStatsTest.php | 4 +- tests/UriTemplateTest.php | 8 +- tests/functionsTest.php | 10 +- 21 files changed, 230 insertions(+), 230 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index f14d8eb4e..e9bad4c1e 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -20,7 +20,7 @@ public function testUsesDefaultHandler() $client = new Client(); Server::enqueue([new Response(200, ['Content-Length' => 0])]); $response = $client->get(Server::$url); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } /** @@ -40,10 +40,10 @@ public function testCanSendMagicAsyncRequests() Server::enqueue([new Response(200, ['Content-Length' => 2], 'hi')]); $p = $client->getAsync(Server::$url, ['query' => ['test' => 'foo']]); $this->assertInstanceOf(PromiseInterface::class, $p); - $this->assertEquals(200, $p->wait()->getStatusCode()); + $this->assertSame(200, $p->wait()->getStatusCode()); $received = Server::received(true); $this->assertCount(1, $received); - $this->assertEquals('test=foo', $received[0]->getUri()->getQuery()); + $this->assertSame('test=foo', $received[0]->getUri()->getQuery()); } public function testCanSendSynchronously() @@ -52,7 +52,7 @@ public function testCanSendSynchronously() $request = new Request('GET', 'http://example.com'); $r = $client->send($request); $this->assertInstanceOf(ResponseInterface::class, $r); - $this->assertEquals(200, $r->getStatusCode()); + $this->assertSame(200, $r->getStatusCode()); } public function testClientHasOptions() @@ -64,10 +64,10 @@ public function testClientHasOptions() 'handler' => new MockHandler() ]); $base = $client->getConfig('base_uri'); - $this->assertEquals('http://foo.com', (string) $base); + $this->assertSame('http://foo.com', (string) $base); $this->assertInstanceOf(Uri::class, $base); $this->assertNotNull($client->getConfig('handler')); - $this->assertEquals(2, $client->getConfig('timeout')); + $this->assertSame(2, $client->getConfig('timeout')); $this->assertArrayHasKey('timeout', $client->getConfig()); $this->assertArrayHasKey('headers', $client->getConfig()); } @@ -80,9 +80,9 @@ public function testCanMergeOnBaseUri() 'handler' => $mock ]); $client->get('baz'); - $this->assertEquals( + $this->assertSame( 'http://foo.com/bar/baz', - $mock->getLastRequest()->getUri() + (string)$mock->getLastRequest()->getUri() ); } @@ -94,13 +94,13 @@ public function testCanMergeOnBaseUriWithRequest() 'base_uri' => 'http://foo.com/bar/' ]); $client->request('GET', new Uri('baz')); - $this->assertEquals( + $this->assertSame( 'http://foo.com/bar/baz', (string) $mock->getLastRequest()->getUri() ); $client->request('GET', new Uri('baz'), ['base_uri' => 'http://example.com/foo/']); - $this->assertEquals( + $this->assertSame( 'http://example.com/foo/baz', (string) $mock->getLastRequest()->getUri(), 'Can overwrite the base_uri through the request options' @@ -114,10 +114,10 @@ public function testCanUseRelativeUriWithSend() 'handler' => $mock, 'base_uri' => 'http://bar.com' ]); - $this->assertEquals('http://bar.com', (string) $client->getConfig('base_uri')); + $this->assertSame('http://bar.com', (string) $client->getConfig('base_uri')); $request = new Request('GET', '/baz'); $client->send($request); - $this->assertEquals( + $this->assertSame( 'http://bar.com/baz', (string) $mock->getLastRequest()->getUri() ); @@ -126,7 +126,7 @@ public function testCanUseRelativeUriWithSend() public function testMergesDefaultOptionsAndDoesNotOverwriteUa() { $c = new Client(['headers' => ['User-agent' => 'foo']]); - $this->assertEquals(['User-agent' => 'foo'], $c->getConfig('headers')); + $this->assertSame(['User-agent' => 'foo'], $c->getConfig('headers')); $this->assertInternalType('array', $c->getConfig('allow_redirects')); $this->assertTrue($c->getConfig('http_errors')); $this->assertTrue($c->getConfig('decode_content')); @@ -141,7 +141,7 @@ public function testDoesNotOverwriteHeaderWithDefault() 'handler' => $mock ]); $c->get('http://example.com', ['headers' => ['User-Agent' => 'bar']]); - $this->assertEquals('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); + $this->assertSame('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); } public function testDoesNotOverwriteHeaderWithDefaultInRequest() @@ -153,7 +153,7 @@ public function testDoesNotOverwriteHeaderWithDefaultInRequest() ]); $request = new Request('GET', Server::$url, ['User-Agent' => 'bar']); $c->send($request); - $this->assertEquals('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); + $this->assertSame('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); } public function testDoesOverwriteHeaderWithSetRequestOption() @@ -165,7 +165,7 @@ public function testDoesOverwriteHeaderWithSetRequestOption() ]); $request = new Request('GET', Server::$url, ['User-Agent' => 'bar']); $c->send($request, ['headers' => ['User-Agent' => 'YO']]); - $this->assertEquals('YO', $mock->getLastRequest()->getHeaderLine('User-Agent')); + $this->assertSame('YO', $mock->getLastRequest()->getHeaderLine('User-Agent')); } public function testCanUnsetRequestOptionWithNull() @@ -183,7 +183,7 @@ public function testRewriteExceptionsToHttpErrors() { $client = new Client(['handler' => new MockHandler([new Response(404)])]); $res = $client->get('http://foo.com', ['exceptions' => false]); - $this->assertEquals(404, $res->getStatusCode()); + $this->assertSame(404, $res->getStatusCode()); } public function testRewriteSaveToToSink() @@ -249,7 +249,7 @@ public function testSetCookieToTrueUsesSharedJar() $client = new Client(['handler' => $handler, 'cookies' => true]); $client->get('http://foo.com'); $client->get('http://foo.com'); - $this->assertEquals('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); + $this->assertSame('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); } public function testSetCookieToJar() @@ -263,7 +263,7 @@ public function testSetCookieToJar() $jar = new CookieJar(); $client->get('http://foo.com', ['cookies' => $jar]); $client->get('http://foo.com', ['cookies' => $jar]); - $this->assertEquals('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); + $this->assertSame('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); } public function testCanDisableContentDecoding() @@ -282,8 +282,8 @@ public function testCanSetContentDecodingToValue() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['decode_content' => 'gzip']); $last = $mock->getLastRequest(); - $this->assertEquals('gzip', $last->getHeaderLine('Accept-Encoding')); - $this->assertEquals('gzip', $mock->getLastOptions()['decode_content']); + $this->assertSame('gzip', $last->getHeaderLine('Accept-Encoding')); + $this->assertSame('gzip', $mock->getLastOptions()['decode_content']); } /** @@ -303,7 +303,7 @@ public function testAddsBody() $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['body' => 'foo']); $last = $mock->getLastRequest(); - $this->assertEquals('foo', (string) $last->getBody()); + $this->assertSame('foo', (string) $last->getBody()); } /** @@ -323,7 +323,7 @@ public function testQueryCanBeString() $client = new Client(['handler' => $mock]); $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['query' => 'foo']); - $this->assertEquals('foo', $mock->getLastRequest()->getUri()->getQuery()); + $this->assertSame('foo', $mock->getLastRequest()->getUri()->getQuery()); } public function testQueryCanBeArray() @@ -332,7 +332,7 @@ public function testQueryCanBeArray() $client = new Client(['handler' => $mock]); $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['query' => ['foo' => 'bar baz']]); - $this->assertEquals('foo=bar%20baz', $mock->getLastRequest()->getUri()->getQuery()); + $this->assertSame('foo=bar%20baz', $mock->getLastRequest()->getUri()->getQuery()); } public function testCanAddJsonData() @@ -342,8 +342,8 @@ public function testCanAddJsonData() $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['json' => ['foo' => 'bar']]); $last = $mock->getLastRequest(); - $this->assertEquals('{"foo":"bar"}', (string) $mock->getLastRequest()->getBody()); - $this->assertEquals('application/json', $last->getHeaderLine('Content-Type')); + $this->assertSame('{"foo":"bar"}', (string) $mock->getLastRequest()->getBody()); + $this->assertSame('application/json', $last->getHeaderLine('Content-Type')); } public function testCanAddJsonDataWithoutOverwritingContentType() @@ -356,8 +356,8 @@ public function testCanAddJsonDataWithoutOverwritingContentType() 'json' => 'a' ]); $last = $mock->getLastRequest(); - $this->assertEquals('"a"', (string) $mock->getLastRequest()->getBody()); - $this->assertEquals('foo', $last->getHeaderLine('Content-Type')); + $this->assertSame('"a"', (string) $mock->getLastRequest()->getBody()); + $this->assertSame('foo', $last->getHeaderLine('Content-Type')); } public function testAuthCanBeTrue() @@ -375,7 +375,7 @@ public function testAuthCanBeArrayForBasicAuth() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => ['a', 'b']]); $last = $mock->getLastRequest(); - $this->assertEquals('Basic YTpi', $last->getHeaderLine('Authorization')); + $this->assertSame('Basic YTpi', $last->getHeaderLine('Authorization')); } public function testAuthCanBeArrayForDigestAuth() @@ -384,7 +384,7 @@ public function testAuthCanBeArrayForDigestAuth() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => ['a', 'b', 'digest']]); $last = $mock->getLastOptions(); - $this->assertEquals([ + $this->assertSame([ CURLOPT_HTTPAUTH => 2, CURLOPT_USERPWD => 'a:b' ], $last['curl']); @@ -396,7 +396,7 @@ public function testAuthCanBeArrayForNtlmAuth() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => ['a', 'b', 'ntlm']]); $last = $mock->getLastOptions(); - $this->assertEquals([ + $this->assertSame([ CURLOPT_HTTPAUTH => 8, CURLOPT_USERPWD => 'a:b' ], $last['curl']); @@ -408,7 +408,7 @@ public function testAuthCanBeCustomType() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => 'foo']); $last = $mock->getLastOptions(); - $this->assertEquals('foo', $last['auth']); + $this->assertSame('foo', $last['auth']); } public function testCanAddFormParams() @@ -422,11 +422,11 @@ public function testCanAddFormParams() ] ]); $last = $mock->getLastRequest(); - $this->assertEquals( + $this->assertSame( 'application/x-www-form-urlencoded', $last->getHeaderLine('Content-Type') ); - $this->assertEquals( + $this->assertSame( 'foo=bar+bam&baz%5Bboo%5D=qux', (string) $last->getBody() ); @@ -445,7 +445,7 @@ public function testFormParamsEncodedProperly() ] ]); $last = $mock->getLastRequest(); - $this->assertEquals( + $this->assertSame( 'foo=bar+bam&baz%5Bboo%5D=qux', (string) $last->getBody() ); @@ -559,14 +559,14 @@ public function testUsesProxyEnvironmentVariables() $this->assertNull($client->getConfig('proxy')); putenv('HTTP_PROXY=127.0.0.1'); $client = new Client(); - $this->assertEquals( + $this->assertSame( ['http' => '127.0.0.1'], $client->getConfig('proxy') ); putenv('HTTPS_PROXY=127.0.0.2'); putenv('NO_PROXY=127.0.0.3, 127.0.0.4'); $client = new Client(); - $this->assertEquals( + $this->assertSame( ['http' => '127.0.0.1', 'https' => '127.0.0.2', 'no' => ['127.0.0.3','127.0.0.4']], $client->getConfig('proxy') ); @@ -596,7 +596,7 @@ public function testCanSetCustomHandler() $mock = new MockHandler([new Response(500)]); $client = new Client(['handler' => $mock]); $mock2 = new MockHandler([new Response(200)]); - $this->assertEquals( + $this->assertSame( 200, $client->send(new Request('GET', 'http://foo.com'), [ 'handler' => $mock2 @@ -610,7 +610,7 @@ public function testProperlyBuildsQuery() $client = new Client(['handler' => $mock]); $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['query' => ['foo' => 'bar', 'john' => 'doe']]); - $this->assertEquals('foo=bar&john=doe', $mock->getLastRequest()->getUri()->getQuery()); + $this->assertSame('foo=bar&john=doe', $mock->getLastRequest()->getUri()->getQuery()); } public function testSendSendsWithIpAddressAndPortAndHostHeaderInRequestTheHostShouldBePreserved() @@ -621,7 +621,7 @@ public function testSendSendsWithIpAddressAndPortAndHostHeaderInRequestTheHostSh $client->send($request); - $this->assertEquals('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); + $this->assertSame('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); } public function testSendSendsWithDomainAndHostHeaderInRequestTheHostShouldBePreserved() @@ -632,7 +632,7 @@ public function testSendSendsWithDomainAndHostHeaderInRequestTheHostShouldBePres $client->send($request); - $this->assertEquals('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); + $this->assertSame('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); } /** diff --git a/tests/Cookie/CookieJarTest.php b/tests/Cookie/CookieJarTest.php index dc2fbd9b5..8416c9a24 100644 --- a/tests/Cookie/CookieJarTest.php +++ b/tests/Cookie/CookieJarTest.php @@ -238,7 +238,7 @@ public function testOverwritesCookiesThatHaveChanged() $this->assertCount(1, $this->jar); $c = $this->jar->getIterator()->getArrayCopy(); - $this->assertEquals('zoo', $c[0]->getValue()); + $this->assertSame('zoo', $c[0]->getValue()); } public function testAddsCookiesFromResponseWithRequest() @@ -313,7 +313,7 @@ public function testReturnsCookiesMatchingRequests($url, $cookies) $request = new Request('GET', $url); $request = $this->jar->withCookieHeader($request); - $this->assertEquals($cookies, $request->getHeaderLine('Cookie')); + $this->assertSame($cookies, $request->getHeaderLine('Cookie')); } /** @@ -346,7 +346,7 @@ public function testDeletesCookiesByName() $names = array_map(function (SetCookie $c) { return $c->getName(); }, $jar->getIterator()->getArrayCopy()); - $this->assertEquals(['foo', 'test', 'you'], $names); + $this->assertSame(['foo', 'test', 'you'], $names); } public function testCanConvertToAndLoadFromArray() @@ -406,7 +406,7 @@ public function testCookiePathWithEmptySetCookiePath($uriPath, $cookiePath) $request = (new Request('GET', $uriPath))->withHeader('Host', 'www.example.com'); $this->jar->extractCookies($request, $response); - $this->assertEquals($cookiePath, $this->jar->toArray()[0]['Path']); - $this->assertEquals($cookiePath, $this->jar->toArray()[1]['Path']); + $this->assertSame($cookiePath, $this->jar->toArray()[0]['Path']); + $this->assertSame($cookiePath, $this->jar->toArray()[1]['Path']); } } diff --git a/tests/Cookie/FileCookieJarTest.php b/tests/Cookie/FileCookieJarTest.php index f93ab37fe..0fcf0ab3c 100644 --- a/tests/Cookie/FileCookieJarTest.php +++ b/tests/Cookie/FileCookieJarTest.php @@ -29,7 +29,7 @@ public function testValidatesCookieFile() public function testLoadsFromFile() { $jar = new FileCookieJar($this->file); - $this->assertEquals([], $jar->getIterator()->getArrayCopy()); + $this->assertSame([], $jar->getIterator()->getArrayCopy()); unlink($this->file); } diff --git a/tests/Cookie/SessionCookieJarTest.php b/tests/Cookie/SessionCookieJarTest.php index 20bea8440..77c3816cf 100644 --- a/tests/Cookie/SessionCookieJarTest.php +++ b/tests/Cookie/SessionCookieJarTest.php @@ -33,7 +33,7 @@ public function testValidatesCookieSession() public function testLoadsFromSession() { $jar = new SessionCookieJar($this->sessionVar); - $this->assertEquals([], $jar->getIterator()->getArrayCopy()); + $this->assertSame([], $jar->getIterator()->getArrayCopy()); unset($_SESSION[$this->sessionVar]); } diff --git a/tests/Cookie/SetCookieTest.php b/tests/Cookie/SetCookieTest.php index 3625d323a..973de554a 100644 --- a/tests/Cookie/SetCookieTest.php +++ b/tests/Cookie/SetCookieTest.php @@ -12,7 +12,7 @@ class SetCookieTest extends TestCase public function testInitializesDefaultValues() { $cookie = new SetCookie(); - $this->assertEquals('/', $cookie->getPath()); + $this->assertSame('/', $cookie->getPath()); } public function testConvertsDateTimeMaxAgeToUnixTimestamp() @@ -48,17 +48,17 @@ public function testHoldsValues() $cookie = new SetCookie($data); $this->assertEquals($data, $cookie->toArray()); - $this->assertEquals('foo', $cookie->getName()); - $this->assertEquals('baz', $cookie->getValue()); - $this->assertEquals('baz.com', $cookie->getDomain()); - $this->assertEquals('/bar', $cookie->getPath()); - $this->assertEquals($t, $cookie->getExpires()); - $this->assertEquals(100, $cookie->getMaxAge()); + $this->assertSame('foo', $cookie->getName()); + $this->assertSame('baz', $cookie->getValue()); + $this->assertSame('baz.com', $cookie->getDomain()); + $this->assertSame('/bar', $cookie->getPath()); + $this->assertSame($t, $cookie->getExpires()); + $this->assertSame(100, $cookie->getMaxAge()); $this->assertTrue($cookie->getSecure()); $this->assertTrue($cookie->getDiscard()); $this->assertTrue($cookie->getHttpOnly()); - $this->assertEquals('baz', $cookie->toArray()['foo']); - $this->assertEquals('bam', $cookie->toArray()['bar']); + $this->assertSame('baz', $cookie->toArray()['foo']); + $this->assertSame('bam', $cookie->toArray()['bar']); $cookie->setName('a'); $cookie->setValue('b'); @@ -70,12 +70,12 @@ public function testHoldsValues() $cookie->setHttpOnly(false); $cookie->setDiscard(false); - $this->assertEquals('a', $cookie->getName()); - $this->assertEquals('b', $cookie->getValue()); - $this->assertEquals('c', $cookie->getPath()); - $this->assertEquals('bar.com', $cookie->getDomain()); - $this->assertEquals(10, $cookie->getExpires()); - $this->assertEquals(200, $cookie->getMaxAge()); + $this->assertSame('a', $cookie->getName()); + $this->assertSame('b', $cookie->getValue()); + $this->assertSame('c', $cookie->getPath()); + $this->assertSame('bar.com', $cookie->getDomain()); + $this->assertSame(10, $cookie->getExpires()); + $this->assertSame(200, $cookie->getMaxAge()); $this->assertFalse($cookie->getSecure()); $this->assertFalse($cookie->getDiscard()); $this->assertFalse($cookie->getHttpOnly()); @@ -149,7 +149,7 @@ public function testMatchesPath($cookiePath, $requestPath, $isMatch) { $cookie = new SetCookie(); $cookie->setPath($cookiePath); - $this->assertEquals($isMatch, $cookie->matchesPath($requestPath)); + $this->assertSame($isMatch, $cookie->matchesPath($requestPath)); } public function cookieValidateProvider() @@ -196,7 +196,7 @@ public function testConvertsToString() 'HttpOnly' => true, 'Secure' => true ]); - $this->assertEquals( + $this->assertSame( 'test=123; Domain=foo.com; Path=/abc; Expires=Sun, 27 Oct 2013 23:20:08 GMT; Secure; HttpOnly', (string) $cookie ); @@ -386,7 +386,7 @@ public function testParseCookie($cookie, $parsed) $this->assertEquals($p[$key], $parsed[$key], 'Comparing ' . $key . ' ' . var_export($value, true) . ' : ' . var_export($parsed, true) . ' | ' . var_export($p, true)); } } else { - $this->assertEquals([ + $this->assertSame([ 'Name' => null, 'Value' => null, 'Domain' => null, @@ -437,7 +437,7 @@ public function isExpiredProvider() */ public function testIsExpired($cookie, $expired) { - $this->assertEquals( + $this->assertSame( $expired, SetCookie::fromString($cookie)->isExpired() ); diff --git a/tests/Exception/ConnectExceptionTest.php b/tests/Exception/ConnectExceptionTest.php index 8ab945ec7..dd5df027b 100644 --- a/tests/Exception/ConnectExceptionTest.php +++ b/tests/Exception/ConnectExceptionTest.php @@ -18,8 +18,8 @@ public function testHasNoResponse() $this->assertSame($req, $e->getRequest()); $this->assertNull($e->getResponse()); $this->assertFalse($e->hasResponse()); - $this->assertEquals('foo', $e->getMessage()); - $this->assertEquals('bar', $e->getHandlerContext()['foo']); + $this->assertSame('foo', $e->getMessage()); + $this->assertSame('bar', $e->getHandlerContext()['foo']); $this->assertSame($prev, $e->getPrevious()); } } diff --git a/tests/Exception/RequestExceptionTest.php b/tests/Exception/RequestExceptionTest.php index 208c31c18..5a826d36f 100644 --- a/tests/Exception/RequestExceptionTest.php +++ b/tests/Exception/RequestExceptionTest.php @@ -135,7 +135,7 @@ public function testCreatesExceptionWithoutPrintableBody() public function testHasStatusCodeAsExceptionCode() { $e = RequestException::create(new Request('GET', '/'), new Response(442)); - $this->assertEquals(442, $e->getCode()); + $this->assertSame(442, $e->getCode()); } public function testWrapsRequestExceptions() @@ -159,7 +159,7 @@ public function testCanProvideHandlerContext() { $r = new Request('GET', 'http://www.oo.com'); $e = new RequestException('foo', $r, null, null, ['bar' => 'baz']); - $this->assertEquals(['bar' => 'baz'], $e->getHandlerContext()); + $this->assertSame(['bar' => 'baz'], $e->getHandlerContext()); } public function testObfuscateUrlWithUsername() diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index a145bbc41..0907c21fe 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -48,19 +48,19 @@ public function testCreatesCurlHandle() $this->assertInternalType('array', $result->headers); $this->assertSame($stream, $result->sink); curl_close($result->handle); - $this->assertEquals('PUT', $_SERVER['_curl'][CURLOPT_CUSTOMREQUEST]); - $this->assertEquals( + $this->assertSame('PUT', $_SERVER['_curl'][CURLOPT_CUSTOMREQUEST]); + $this->assertSame( 'http://127.0.0.1:8126/', $_SERVER['_curl'][CURLOPT_URL] ); // Sends via post fields when the request is small enough - $this->assertEquals('testing', $_SERVER['_curl'][CURLOPT_POSTFIELDS]); + $this->assertSame('testing', $_SERVER['_curl'][CURLOPT_POSTFIELDS]); $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_RETURNTRANSFER]); $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_HEADER]); - $this->assertEquals(150, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT]); + $this->assertSame(150, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT]); $this->assertInstanceOf('Closure', $_SERVER['_curl'][CURLOPT_HEADERFUNCTION]); if (defined('CURLOPT_PROTOCOLS')) { - $this->assertEquals( + $this->assertSame( CURLPROTO_HTTP | CURLPROTO_HTTPS, $_SERVER['_curl'][CURLOPT_PROTOCOLS] ); @@ -512,11 +512,11 @@ public function testHandles100Continue() ], 'test'); $handler = new Handler\CurlMultiHandler(); $response = $handler($request, [])->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('OK', $response->getReasonPhrase()); - $this->assertEquals('Hello', $response->getHeaderLine('Test')); - $this->assertEquals('4', $response->getHeaderLine('Content-Length')); - $this->assertEquals('test', (string) $response->getBody()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('OK', $response->getReasonPhrase()); + $this->assertSame('Hello', $response->getHeaderLine('Test')); + $this->assertSame('4', $response->getHeaderLine('Content-Length')); + $this->assertSame('test', (string) $response->getBody()); } /** @@ -656,9 +656,9 @@ public function testSuccessfullyCallsOnHeadersBeforeWritingToSink() ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('bar', $response->getHeaderLine('X-Foo')); - $this->assertEquals('abc 123', (string) $response->getBody()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('bar', $response->getHeaderLine('X-Foo')); + $this->assertSame('abc 123', (string) $response->getBody()); } public function testInvokesOnStatsOnSuccess() @@ -674,13 +674,13 @@ public function testInvokesOnStatsOnSuccess() } ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals(200, $gotStats->getResponse()->getStatusCode()); - $this->assertEquals( + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame(200, $gotStats->getResponse()->getStatusCode()); + $this->assertSame( Server::$url, (string) $gotStats->getEffectiveUri() ); - $this->assertEquals( + $this->assertSame( Server::$url, (string) $gotStats->getRequest()->getUri() ); @@ -701,13 +701,13 @@ public function testInvokesOnStatsOnError() ]); $promise->wait(false); $this->assertFalse($gotStats->hasResponse()); - $this->assertEquals( + $this->assertSame( 'http://127.0.0.1:123', - $gotStats->getEffectiveUri() + (string) $gotStats->getEffectiveUri() ); - $this->assertEquals( + $this->assertSame( 'http://127.0.0.1:123', - $gotStats->getRequest()->getUri() + (string) $gotStats->getRequest()->getUri() ); $this->assertInternalType('float', $gotStats->getTransferTime()); $this->assertInternalType('int', $gotStats->getHandlerErrorData()); diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 945ea8992..61df32679 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -15,7 +15,7 @@ public function testSendsRequest() $a = new CurlMultiHandler(); $request = new Request('GET', Server::$url); $response = $a($request, [])->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } /** @@ -48,7 +48,7 @@ public function testCanCancel() } foreach($responses as $r) { - $this->assertEquals('rejected', $response->getState()); + $this->assertSame('rejected', $response->getState()); } } @@ -60,7 +60,7 @@ public function testCannotCancelFinished() $response = $a(new Request('GET', Server::$url), []); $response->wait(); $response->cancel(); - $this->assertEquals('fulfilled', $response->getState()); + $this->assertSame('fulfilled', $response->getState()); } public function testDelaysConcurrently() diff --git a/tests/Handler/MockHandlerTest.php b/tests/Handler/MockHandlerTest.php index 94a5c4a20..e067a8b48 100644 --- a/tests/Handler/MockHandlerTest.php +++ b/tests/Handler/MockHandlerTest.php @@ -65,7 +65,7 @@ public function testCanGetLastRequestAndOptions() $request = new Request('GET', 'http://example.com'); $mock($request, ['foo' => 'bar']); $this->assertSame($request, $mock->getLastRequest()); - $this->assertEquals(['foo' => 'bar'], $mock->getLastOptions()); + $this->assertSame(['foo' => 'bar'], $mock->getLastOptions()); } public function testSinkFilename() diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index 0c97e6820..495cd95f1 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -37,16 +37,16 @@ public function testReturnsResponseForSuccessfulRequest() new Request('GET', Server::$url, ['Foo' => 'Bar']), [] )->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('OK', $response->getReasonPhrase()); - $this->assertEquals('Bar', $response->getHeaderLine('Foo')); - $this->assertEquals('8', $response->getHeaderLine('Content-Length')); - $this->assertEquals('hi there', (string) $response->getBody()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('OK', $response->getReasonPhrase()); + $this->assertSame('Bar', $response->getHeaderLine('Foo')); + $this->assertSame('8', $response->getHeaderLine('Content-Length')); + $this->assertSame('hi there', (string) $response->getBody()); $sent = Server::received()[0]; - $this->assertEquals('GET', $sent->getMethod()); - $this->assertEquals('/', $sent->getUri()->getPath()); - $this->assertEquals('127.0.0.1:8126', $sent->getHeaderLine('Host')); - $this->assertEquals('Bar', $sent->getHeaderLine('foo')); + $this->assertSame('GET', $sent->getMethod()); + $this->assertSame('/', $sent->getUri()->getPath()); + $this->assertSame('127.0.0.1:8126', $sent->getHeaderLine('Host')); + $this->assertSame('Bar', $sent->getHeaderLine('foo')); } /** @@ -72,20 +72,20 @@ public function testStreamAttributeKeepsStreamOpen() 'test' ); $response = $handler($request, ['stream' => true])->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('OK', $response->getReasonPhrase()); - $this->assertEquals('8', $response->getHeaderLine('Content-Length')); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('OK', $response->getReasonPhrase()); + $this->assertSame('8', $response->getHeaderLine('Content-Length')); $body = $response->getBody(); $stream = $body->detach(); $this->assertInternalType('resource', $stream); - $this->assertEquals('http', stream_get_meta_data($stream)['wrapper_type']); - $this->assertEquals('hi there', stream_get_contents($stream)); + $this->assertSame('http', stream_get_meta_data($stream)['wrapper_type']); + $this->assertSame('hi there', stream_get_contents($stream)); fclose($stream); $sent = Server::received()[0]; - $this->assertEquals('PUT', $sent->getMethod()); - $this->assertEquals('http://127.0.0.1:8126/foo?baz=bar', (string) $sent->getUri()); - $this->assertEquals('Bar', $sent->getHeaderLine('Foo')); - $this->assertEquals('test', (string) $sent->getBody()); + $this->assertSame('PUT', $sent->getMethod()); + $this->assertSame('http://127.0.0.1:8126/foo?baz=bar', (string) $sent->getUri()); + $this->assertSame('Bar', $sent->getHeaderLine('Foo')); + $this->assertSame('test', (string) $sent->getBody()); } public function testDrainsResponseIntoTempStream() @@ -96,8 +96,8 @@ public function testDrainsResponseIntoTempStream() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertEquals('php://temp', stream_get_meta_data($stream)['uri']); - $this->assertEquals('hi', fread($stream, 2)); + $this->assertSame('php://temp', stream_get_meta_data($stream)['uri']); + $this->assertSame('hi', fread($stream, 2)); fclose($stream); } @@ -109,9 +109,9 @@ public function testDrainsResponseIntoSaveToBody() $request = new Request('GET', Server::$url); $response = $handler($request, ['sink' => $r])->wait(); $body = $response->getBody()->detach(); - $this->assertEquals('php://temp', stream_get_meta_data($body)['uri']); - $this->assertEquals('hi', fread($body, 2)); - $this->assertEquals(' there', stream_get_contents($r)); + $this->assertSame('php://temp', stream_get_meta_data($body)['uri']); + $this->assertSame('hi', fread($body, 2)); + $this->assertSame(' there', stream_get_contents($r)); fclose($r); } @@ -123,8 +123,8 @@ public function testDrainsResponseIntoSaveToBodyAtPath() $request = new Request('GET', Server::$url); $response = $handler($request, ['sink' => $tmpfname])->wait(); $body = $response->getBody(); - $this->assertEquals($tmpfname, $body->getMetadata('uri')); - $this->assertEquals('hi', $body->read(2)); + $this->assertSame($tmpfname, $body->getMetadata('uri')); + $this->assertSame('hi', $body->read(2)); $body->close(); unlink($tmpfname); } @@ -138,8 +138,8 @@ public function testDrainsResponseIntoSaveToBodyAtNonExistentPath() $request = new Request('GET', Server::$url); $response = $handler($request, ['sink' => $tmpfname])->wait(); $body = $response->getBody(); - $this->assertEquals($tmpfname, $body->getMetadata('uri')); - $this->assertEquals('hi', $body->read(2)); + $this->assertSame($tmpfname, $body->getMetadata('uri')); + $this->assertSame('hi', $body->read(2)); $body->close(); unlink($tmpfname); } @@ -158,7 +158,7 @@ public function testDrainsResponseAndReadsOnlyContentLengthBytes() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertEquals('hi there', stream_get_contents($stream)); + $this->assertSame('hi there', stream_get_contents($stream)); fclose($stream); } @@ -177,7 +177,7 @@ public function testDoesNotDrainWhenHeadRequest() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertEquals('', stream_get_contents($stream)); + $this->assertSame('', stream_get_contents($stream)); fclose($stream); } @@ -194,7 +194,7 @@ public function testAutomaticallyDecompressGzip() $handler = new StreamHandler(); $request = new Request('GET', Server::$url); $response = $handler($request, ['decode_content' => true])->wait(); - $this->assertEquals('test', (string) $response->getBody()); + $this->assertSame('test', (string) $response->getBody()); $this->assertFalse($response->hasHeader('content-encoding')); $this->assertTrue(!$response->hasHeader('content-length') || $response->getHeaderLine('content-length') == $response->getBody()->getSize()); } @@ -237,7 +237,7 @@ public function testDoesNotForceGzipDecode() $request = new Request('GET', Server::$url); $response = $handler($request, ['decode_content' => false])->wait(); $this->assertSame($content, (string) $response->getBody()); - $this->assertEquals('gzip', $response->getHeaderLine('content-encoding')); + $this->assertSame('gzip', $response->getHeaderLine('content-encoding')); $this->assertEquals(strlen($content), $response->getHeaderLine('content-length')); } @@ -247,7 +247,7 @@ public function testProtocolVersion() $handler = new StreamHandler(); $request = new Request('GET', Server::$url, [], null, '1.0'); $handler($request, []); - $this->assertEquals('1.0', Server::received()[0]->getProtocolVersion()); + $this->assertSame('1.0', Server::received()[0]->getProtocolVersion()); } protected function getSendResult(array $opts) @@ -275,7 +275,7 @@ public function testAddsProxyByProtocol() $url = rtrim($url, '/'); $res = $this->getSendResult(['proxy' => ['http' => $url]]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertEquals($url, $opts['http']['proxy']); + $this->assertSame($url, $opts['http']['proxy']); } public function testAddsProxyButHonorsNoProxy() @@ -327,7 +327,7 @@ public function testVerifyCanBeSetToPath() $opts = stream_context_get_options($res->getBody()->detach()); $this->assertTrue($opts['ssl']['verify_peer']); $this->assertTrue($opts['ssl']['verify_peer_name']); - $this->assertEquals($path, $opts['ssl']['cafile']); + $this->assertSame($path, $opts['ssl']['cafile']); $this->assertFileExists($opts['ssl']['cafile']); } @@ -337,7 +337,7 @@ public function testUsesSystemDefaultBundle() $res = $this->getSendResult(['verify' => true]); $opts = stream_context_get_options($res->getBody()->detach()); if (PHP_VERSION_ID < 50600) { - $this->assertEquals($path, $opts['ssl']['cafile']); + $this->assertSame($path, $opts['ssl']['cafile']); } else { $this->assertArrayNotHasKey('cafile', $opts['ssl']); } @@ -357,8 +357,8 @@ public function testCanSetPasswordWhenSettingCert() $path = __FILE__; $res = $this->getSendResult(['cert' => [$path, 'foo']]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertEquals($path, $opts['ssl']['local_cert']); - $this->assertEquals('foo', $opts['ssl']['passphrase']); + $this->assertSame($path, $opts['ssl']['local_cert']); + $this->assertSame('foo', $opts['ssl']['passphrase']); } public function testDebugAttributeWritesToStream() @@ -440,9 +440,9 @@ public function testPerformsShallowMergeOfCustomContextOptions() ], ]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertEquals('HEAD', $opts['http']['method']); + $this->assertSame('HEAD', $opts['http']['method']); $this->assertTrue($opts['http']['request_fulluri']); - $this->assertEquals('127.0.0.1:0', $opts['socket']['bindto']); + $this->assertSame('127.0.0.1:0', $opts['socket']['bindto']); $this->assertFalse($opts['ssl']['verify_peer']); } @@ -494,10 +494,10 @@ public function testSupports100Continue() $request = new Request('PUT', Server::$url, ['Expect' => '100-Continue'], 'test'); $handler = new StreamHandler(); $response = $handler($request, [])->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('Hello', $response->getHeaderLine('Test')); - $this->assertEquals('4', $response->getHeaderLine('Content-Length')); - $this->assertEquals('test', (string) $response->getBody()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('Hello', $response->getHeaderLine('Test')); + $this->assertSame('4', $response->getHeaderLine('Content-Length')); + $this->assertSame('test', (string) $response->getBody()); } public function testDoesSleep() @@ -564,14 +564,14 @@ public function testSuccessfullyCallsOnHeadersBeforeWritingToSink() 'sink' => $stream, 'on_headers' => function (ResponseInterface $res) use (&$got) { $got = $res; - $this->assertEquals('bar', $res->getHeaderLine('X-Foo')); + $this->assertSame('bar', $res->getHeaderLine('X-Foo')); } ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('bar', $response->getHeaderLine('X-Foo')); - $this->assertEquals('abc 123', (string) $response->getBody()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('bar', $response->getHeaderLine('X-Foo')); + $this->assertSame('abc 123', (string) $response->getBody()); } public function testInvokesOnStatsOnSuccess() @@ -587,13 +587,13 @@ public function testInvokesOnStatsOnSuccess() } ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals(200, $gotStats->getResponse()->getStatusCode()); - $this->assertEquals( + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame(200, $gotStats->getResponse()->getStatusCode()); + $this->assertSame( Server::$url, (string) $gotStats->getEffectiveUri() ); - $this->assertEquals( + $this->assertSame( Server::$url, (string) $gotStats->getRequest()->getUri() ); @@ -614,11 +614,11 @@ public function testInvokesOnStatsOnError() ]); $promise->wait(false); $this->assertFalse($gotStats->hasResponse()); - $this->assertEquals( + $this->assertSame( 'http://127.0.0.1:123', (string) $gotStats->getEffectiveUri() ); - $this->assertEquals( + $this->assertSame( 'http://127.0.0.1:123', (string) $gotStats->getRequest()->getUri() ); @@ -641,7 +641,7 @@ public function testStreamIgnoresZeroTimeout() 'timeout' => 0 ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } public function testDrainsResponseAndReadsAllContentWhenContentLengthIsZero() @@ -658,7 +658,7 @@ public function testDrainsResponseAndReadsAllContentWhenContentLengthIsZero() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertEquals('hi there... This has a lot of data!', stream_get_contents($stream)); + $this->assertSame('hi there... This has a lot of data!', stream_get_contents($stream)); fclose($stream); } @@ -673,11 +673,11 @@ public function testHonorsReadTimeout() RequestOptions::STREAM => true, ] )->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('OK', $response->getReasonPhrase()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('OK', $response->getReasonPhrase()); $body = $response->getBody()->detach(); $line = fgets($body); - $this->assertEquals("sleeping 60 seconds ...\n", $line); + $this->assertSame("sleeping 60 seconds ...\n", $line); $line = fgets($body); $this->assertFalse($line); $this->assertTrue(stream_get_meta_data($body)['timed_out']); diff --git a/tests/HandlerStackTest.php b/tests/HandlerStackTest.php index b7489864a..6856b6af4 100644 --- a/tests/HandlerStackTest.php +++ b/tests/HandlerStackTest.php @@ -47,8 +47,8 @@ public function testPushInOrder() $builder->push($meths[3]); $builder->push($meths[4]); $composed = $builder->resolve(); - $this->assertEquals('Hello - test123', $composed('test')); - $this->assertEquals( + $this->assertSame('Hello - test123', $composed('test')); + $this->assertSame( [['a', 'test'], ['b', 'test1'], ['c', 'test12']], $meths[0] ); @@ -63,8 +63,8 @@ public function testUnshiftsInReverseOrder() $builder->unshift($meths[3]); $builder->unshift($meths[4]); $composed = $builder->resolve(); - $this->assertEquals('Hello - test321', $composed('test')); - $this->assertEquals( + $this->assertSame('Hello - test321', $composed('test')); + $this->assertSame( [['c', 'test'], ['b', 'test3'], ['a', 'test32']], $meths[0] ); @@ -82,7 +82,7 @@ public function testCanRemoveMiddlewareByInstance() $builder->push($meths[2]); $builder->remove($meths[3]); $composed = $builder->resolve(); - $this->assertEquals('Hello - test1131', $composed('test')); + $this->assertSame('Hello - test1131', $composed('test')); } public function testCanPrintMiddleware() @@ -163,10 +163,10 @@ public function testPicksUpCookiesFromRedirects() 'allow_redirects' => true, 'cookies' => $jar ])->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); $lastRequest = $mock->getLastRequest(); - $this->assertEquals('http://foo.com/baz', (string) $lastRequest->getUri()); - $this->assertEquals('foo=bar', $lastRequest->getHeaderLine('Cookie')); + $this->assertSame('http://foo.com/baz', (string) $lastRequest->getUri()); + $this->assertSame('foo=bar', $lastRequest->getHeaderLine('Cookie')); } private function getFunctions() diff --git a/tests/MessageFormatterTest.php b/tests/MessageFormatterTest.php index eb4cbfb44..e9054a1ac 100644 --- a/tests/MessageFormatterTest.php +++ b/tests/MessageFormatterTest.php @@ -88,6 +88,6 @@ public function formatProvider() public function testFormatsMessages($template, $args, $result) { $f = new MessageFormatter($template); - $this->assertEquals((string) $result, call_user_func_array(array($f, 'format'), $args)); + $this->assertSame((string) $result, call_user_func_array(array($f, 'format'), $args)); } } diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 88013c9ef..27d4a2ac4 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -51,9 +51,9 @@ public function testThrowsExceptionOnHttpClientError() $h = new MockHandler([new Response(404)]); $f = $m($h); $p = $f(new Request('GET', 'http://foo.com'), ['http_errors' => true]); - $this->assertEquals('pending', $p->getState()); + $this->assertSame('pending', $p->getState()); $p->wait(); - $this->assertEquals('rejected', $p->getState()); + $this->assertSame('rejected', $p->getState()); } /** @@ -65,9 +65,9 @@ public function testThrowsExceptionOnHttpServerError() $h = new MockHandler([new Response(500)]); $f = $m($h); $p = $f(new Request('GET', 'http://foo.com'), ['http_errors' => true]); - $this->assertEquals('pending', $p->getState()); + $this->assertSame('pending', $p->getState()); $p->wait(); - $this->assertEquals('rejected', $p->getState()); + $this->assertSame('rejected', $p->getState()); } /** @@ -83,12 +83,12 @@ public function testTracksHistory($container) $p1->wait(); $p2->wait(); $this->assertCount(2, $container); - $this->assertEquals(200, $container[0]['response']->getStatusCode()); - $this->assertEquals(201, $container[1]['response']->getStatusCode()); - $this->assertEquals('GET', $container[0]['request']->getMethod()); - $this->assertEquals('HEAD', $container[1]['request']->getMethod()); - $this->assertEquals('bar', $container[0]['options']['headers']['foo']); - $this->assertEquals('baz', $container[1]['options']['headers']['foo']); + $this->assertSame(200, $container[0]['response']->getStatusCode()); + $this->assertSame(201, $container[1]['response']->getStatusCode()); + $this->assertSame('GET', $container[0]['request']->getMethod()); + $this->assertSame('HEAD', $container[1]['request']->getMethod()); + $this->assertSame('bar', $container[0]['options']['headers']['foo']); + $this->assertSame('baz', $container[1]['options']['headers']['foo']); } public function getHistoryUseCases() @@ -108,7 +108,7 @@ public function testTracksHistoryForFailures() $f = $m($h); $f($request, [])->wait(false); $this->assertCount(1, $container); - $this->assertEquals('GET', $container[0]['request']->getMethod()); + $this->assertSame('GET', $container[0]['request']->getMethod()); $this->assertInstanceOf(RequestException::class, $container[0]['error']); } @@ -137,16 +137,16 @@ function (RequestInterface $request, array $options, PromiseInterface $p) use (& $b->push($m); $comp = $b->resolve(); $p = $comp(new Request('GET', 'http://foo.com'), []); - $this->assertEquals('123', implode('', $calls)); + $this->assertSame('123', implode('', $calls)); $this->assertInstanceOf(PromiseInterface::class, $p); - $this->assertEquals(200, $p->wait()->getStatusCode()); + $this->assertSame(200, $p->wait()->getStatusCode()); } public function testMapsRequest() { $h = new MockHandler([ function (RequestInterface $request, array $options) { - $this->assertEquals('foo', $request->getHeaderLine('Bar')); + $this->assertSame('foo', $request->getHeaderLine('Bar')); return new Response(200); } ]); @@ -169,7 +169,7 @@ public function testMapsResponse() $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); $p->wait(); - $this->assertEquals('foo', $p->wait()->getHeaderLine('Bar')); + $this->assertSame('foo', $p->wait()->getHeaderLine('Bar')); } public function testLogsRequestsAndResponses() diff --git a/tests/PoolTest.php b/tests/PoolTest.php index f2ba94308..94b44fa47 100644 --- a/tests/PoolTest.php +++ b/tests/PoolTest.php @@ -117,10 +117,10 @@ public function testBatchesResults() $client = new Client(['handler' => $handler]); $results = Pool::batch($client, $requests); $this->assertCount(4, $results); - $this->assertEquals([0, 1, 2, 3], array_keys($results)); - $this->assertEquals(200, $results[0]->getStatusCode()); - $this->assertEquals(201, $results[1]->getStatusCode()); - $this->assertEquals(202, $results[2]->getStatusCode()); + $this->assertSame([0, 1, 2, 3], array_keys($results)); + $this->assertSame(200, $results[0]->getStatusCode()); + $this->assertSame(201, $results[1]->getStatusCode()); + $this->assertSame(202, $results[2]->getStatusCode()); $this->assertInstanceOf(ClientException::class, $results[3]); } diff --git a/tests/PrepareBodyMiddlewareTest.php b/tests/PrepareBodyMiddlewareTest.php index 1876a00f0..53d2316e5 100644 --- a/tests/PrepareBodyMiddlewareTest.php +++ b/tests/PrepareBodyMiddlewareTest.php @@ -47,7 +47,7 @@ function (RequestInterface $request) use ($body) { $p = $comp(new Request($method, 'http://www.google.com', [], $body), []); $this->assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } public function testAddsTransferEncodingWhenNoContentLength() @@ -58,7 +58,7 @@ public function testAddsTransferEncodingWhenNoContentLength() $h = new MockHandler([ function (RequestInterface $request) { $this->assertFalse($request->hasHeader('Content-Length')); - $this->assertEquals('chunked', $request->getHeaderLine('Transfer-Encoding')); + $this->assertSame('chunked', $request->getHeaderLine('Transfer-Encoding')); return new Response(200); } ]); @@ -69,7 +69,7 @@ function (RequestInterface $request) { $p = $comp(new Request('PUT', 'http://www.google.com', [], $body), []); $this->assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } public function testAddsContentTypeWhenMissingAndPossible() @@ -77,7 +77,7 @@ public function testAddsContentTypeWhenMissingAndPossible() $bd = Psr7\stream_for(fopen(__DIR__ . '/../composer.json', 'r')); $h = new MockHandler([ function (RequestInterface $request) { - $this->assertEquals('application/json', $request->getHeaderLine('Content-Type')); + $this->assertSame('application/json', $request->getHeaderLine('Content-Type')); $this->assertTrue($request->hasHeader('Content-Length')); return new Response(200); } @@ -89,7 +89,7 @@ function (RequestInterface $request) { $p = $comp(new Request('PUT', 'http://www.google.com', [], $bd), []); $this->assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } public function expectProvider() @@ -111,7 +111,7 @@ public function testAddsExpect($value, $result) $h = new MockHandler([ function (RequestInterface $request) use ($result) { - $this->assertEquals($result, $request->getHeader('Expect')); + $this->assertSame($result, $request->getHeader('Expect')); return new Response(200); } ]); @@ -125,7 +125,7 @@ function (RequestInterface $request) use ($result) { ]); $this->assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } public function testIgnoresIfExpectIsPresent() @@ -133,7 +133,7 @@ public function testIgnoresIfExpectIsPresent() $bd = Psr7\stream_for(fopen(__DIR__ . '/../composer.json', 'r')); $h = new MockHandler([ function (RequestInterface $request) { - $this->assertEquals(['Foo'], $request->getHeader('Expect')); + $this->assertSame(['Foo'], $request->getHeader('Expect')); return new Response(200); } ]); @@ -148,6 +148,6 @@ function (RequestInterface $request) { ); $this->assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } } diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index 16e1e2439..bf5fb0e48 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -25,7 +25,7 @@ public function testIgnoresNonRedirects() $request = new Request('GET', 'http://example.com'); $promise = $handler($request, []); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); + $this->assertSame(200, $response->getStatusCode()); } public function testIgnoresWhenNoLocation() @@ -37,7 +37,7 @@ public function testIgnoresWhenNoLocation() $request = new Request('GET', 'http://example.com'); $promise = $handler($request, []); $response = $promise->wait(); - $this->assertEquals(304, $response->getStatusCode()); + $this->assertSame(304, $response->getStatusCode()); } public function testRedirectsWithAbsoluteUri() @@ -54,8 +54,8 @@ public function testRedirectsWithAbsoluteUri() 'allow_redirects' => ['max' => 2] ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('http://test.com', $mock->getLastRequest()->getUri()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('http://test.com', (string)$mock->getLastRequest()->getUri()); } public function testRedirectsWithRelativeUri() @@ -72,8 +72,8 @@ public function testRedirectsWithRelativeUri() 'allow_redirects' => ['max' => 2] ]); $response = $promise->wait(); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('http://example.com/foo', $mock->getLastRequest()->getUri()); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('http://example.com/foo', (string)$mock->getLastRequest()->getUri()); } /** @@ -126,7 +126,7 @@ public function testAddsRefererHeader() 'allow_redirects' => ['max' => 2, 'referer' => true] ]); $promise->wait(); - $this->assertEquals( + $this->assertSame( 'http://example.com?a=b', $mock->getLastRequest()->getHeaderLine('Referer') ); @@ -149,7 +149,7 @@ public function testAddsGuzzleRedirectHeader() 'allow_redirects' => ['track_redirects' => true] ]); $response = $promise->wait(true); - $this->assertEquals( + $this->assertSame( [ 'http://example.com', 'http://example.com/foo', @@ -177,12 +177,12 @@ public function testAddsGuzzleRedirectStatusHeader() 'allow_redirects' => ['track_redirects' => true] ]); $response = $promise->wait(true); - $this->assertEquals( + $this->assertSame( [ - 301, - 302, - 301, - 302, + '301', + '302', + '301', + '302', ], $response->getHeader(RedirectMiddleware::STATUS_HISTORY_HEADER) ); @@ -220,9 +220,9 @@ public function testInvokesOnRedirectForRedirects() 'allow_redirects' => [ 'max' => 2, 'on_redirect' => function ($request, $response, $uri) use (&$call) { - $this->assertEquals(302, $response->getStatusCode()); - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('http://test.com', (string) $uri); + $this->assertSame(302, $response->getStatusCode()); + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('http://test.com', (string) $uri); $call = true; } ] diff --git a/tests/RetryMiddlewareTest.php b/tests/RetryMiddlewareTest.php index 063c2bca6..3189340f5 100644 --- a/tests/RetryMiddlewareTest.php +++ b/tests/RetryMiddlewareTest.php @@ -22,7 +22,7 @@ public function testRetriesWhenDeciderReturnsTrue() }; $delay = function ($retries, $response) use (&$delayCalls) { $delayCalls++; - $this->assertEquals($retries, $delayCalls); + $this->assertSame($retries, $delayCalls); $this->assertInstanceOf(Response::class, $response); return 1; }; @@ -33,8 +33,8 @@ public function testRetriesWhenDeciderReturnsTrue() $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); $p->wait(); $this->assertCount(3, $calls); - $this->assertEquals(2, $delayCalls); - $this->assertEquals(202, $p->wait()->getStatusCode()); + $this->assertSame(2, $delayCalls); + $this->assertSame(202, $p->wait()->getStatusCode()); } public function testDoesNotRetryWhenDeciderReturnsFalse() @@ -44,7 +44,7 @@ public function testDoesNotRetryWhenDeciderReturnsFalse() $h = new MockHandler([new Response(200)]); $c = new Client(['handler' => $m($h)]); $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); - $this->assertEquals(200, $p->wait()->getStatusCode()); + $this->assertSame(200, $p->wait()->getStatusCode()); } public function testCanRetryExceptions() @@ -58,22 +58,22 @@ public function testCanRetryExceptions() $h = new MockHandler([new \Exception(), new Response(201)]); $c = new Client(['handler' => $m($h)]); $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); - $this->assertEquals(201, $p->wait()->getStatusCode()); + $this->assertSame(201, $p->wait()->getStatusCode()); $this->assertCount(2, $calls); - $this->assertEquals(0, $calls[0][0]); + $this->assertSame(0, $calls[0][0]); $this->assertNull($calls[0][2]); $this->assertInstanceOf('Exception', $calls[0][3]); - $this->assertEquals(1, $calls[1][0]); + $this->assertSame(1, $calls[1][0]); $this->assertInstanceOf(Response::class, $calls[1][2]); $this->assertNull($calls[1][3]); } public function testBackoffCalculateDelay() { - $this->assertEquals(0, RetryMiddleware::exponentialDelay(0)); - $this->assertEquals(1, RetryMiddleware::exponentialDelay(1)); - $this->assertEquals(2, RetryMiddleware::exponentialDelay(2)); - $this->assertEquals(4, RetryMiddleware::exponentialDelay(3)); - $this->assertEquals(8, RetryMiddleware::exponentialDelay(4)); + $this->assertSame(0, RetryMiddleware::exponentialDelay(0)); + $this->assertSame(1, RetryMiddleware::exponentialDelay(1)); + $this->assertSame(2, RetryMiddleware::exponentialDelay(2)); + $this->assertSame(4, RetryMiddleware::exponentialDelay(3)); + $this->assertSame(8, RetryMiddleware::exponentialDelay(4)); } } diff --git a/tests/TransferStatsTest.php b/tests/TransferStatsTest.php index 247e4e86d..9ef891794 100644 --- a/tests/TransferStatsTest.php +++ b/tests/TransferStatsTest.php @@ -21,8 +21,8 @@ public function testHasData() $this->assertSame($request, $stats->getRequest()); $this->assertSame($response, $stats->getResponse()); $this->assertTrue($stats->hasResponse()); - $this->assertEquals(['foo' => 'bar'], $stats->getHandlerStats()); - $this->assertEquals('bar', $stats->getHandlerStat('foo')); + $this->assertSame(['foo' => 'bar'], $stats->getHandlerStats()); + $this->assertSame('bar', $stats->getHandlerStat('foo')); $this->assertSame($request->getUri(), $stats->getEffectiveUri()); $this->assertEquals(10.5, $stats->getTransferTime()); $this->assertNull($stats->getHandlerErrorData()); diff --git a/tests/UriTemplateTest.php b/tests/UriTemplateTest.php index a5f33402b..eb61dd10a 100644 --- a/tests/UriTemplateTest.php +++ b/tests/UriTemplateTest.php @@ -121,7 +121,7 @@ public function templateProvider() public function testExpandsUriTemplates($template, $expansion, $params) { $uri = new UriTemplate(); - $this->assertEquals($expansion, $uri->expand($template, $params)); + $this->assertSame($expansion, $uri->expand($template, $params)); } public function expressionProvider() @@ -131,7 +131,7 @@ public function expressionProvider() '{+var*}', array( 'operator' => '+', 'values' => array( - array('value' => 'var', 'modifier' => '*') + array('modifier' => '*', 'value' => 'var') ) ), ), @@ -171,7 +171,7 @@ public function testParsesExpressions($exp, $data) $method->setAccessible(true); $exp = substr($exp, 1, -1); - $this->assertEquals($data, $method->invokeArgs($template, array($exp))); + $this->assertSame($data, $method->invokeArgs($template, array($exp))); } /** @@ -197,6 +197,6 @@ public function testAllowsNestedArrayExpansion() ) )); - $this->assertEquals('http://example.com/foo/bar/one,two?query=test&more%5B0%5D=fun&more%5B1%5D=ice%20cream&baz%5Bbar%5D=fizz&baz%5Btest%5D=buzz&bam=boo', $result); + $this->assertSame('http://example.com/foo/bar/one,two?query=test&more%5B0%5D=fun&more%5B1%5D=ice%20cream&baz%5Bbar%5D=fizz&baz%5Btest%5D=buzz&bam=boo', $result); } } diff --git a/tests/functionsTest.php b/tests/functionsTest.php index 292a3e847..fd65d41b6 100644 --- a/tests/functionsTest.php +++ b/tests/functionsTest.php @@ -8,7 +8,7 @@ class FunctionsTest extends TestCase { public function testExpandsTemplate() { - $this->assertEquals( + $this->assertSame( 'foo/123', GuzzleHttp\uri_template('foo/{bar}', ['bar' => '123']) ); @@ -41,13 +41,13 @@ public function typeProvider() */ public function testDescribesType($input, $output) { - $this->assertEquals($output, GuzzleHttp\describe_type($input)); + $this->assertSame($output, GuzzleHttp\describe_type($input)); } public function testParsesHeadersFromLines() { $lines = ['Foo: bar', 'Foo: baz', 'Abc: 123', 'Def: a, b']; - $this->assertEquals([ + $this->assertSame([ 'Foo' => ['bar', 'baz'], 'Abc' => ['123'], 'Def' => ['a, b'], @@ -57,7 +57,7 @@ public function testParsesHeadersFromLines() public function testParsesHeadersFromLinesWithMultipleLines() { $lines = ['Foo: bar', 'Foo: baz', 'Foo: 123']; - $this->assertEquals([ + $this->assertSame([ 'Foo' => ['bar', 'baz', '123'], ], GuzzleHttp\headers_from_lines($lines)); } @@ -105,7 +105,7 @@ public function testEnsuresNoProxyCheckHostIsSet() public function testEncodesJson() { - $this->assertEquals('true', \GuzzleHttp\json_encode(true)); + $this->assertSame('true', \GuzzleHttp\json_encode(true)); } /** From 7f82c29209f156eda72086d88ee9e2c36cb987ad Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Fri, 16 Nov 2018 10:34:39 -0200 Subject: [PATCH 035/141] Use more accurate assertion while checking for non-existent array's key --- tests/Handler/StreamHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index 495cd95f1..6c10ec3f0 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -286,7 +286,7 @@ public function testAddsProxyButHonorsNoProxy() 'no' => ['*'] ]]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertTrue(empty($opts['http']['proxy'])); + $this->assertArrayNotHasKey('proxy', $opts['http']); } public function testAddsTimeout() From 758127d23c6c0642da72aabccd51787023be78cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sun, 18 Nov 2018 23:50:19 +0100 Subject: [PATCH 036/141] Enhancement: Normalize composer.json --- composer.json | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 1f328e308..923ba074b 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,15 @@ "name": "guzzlehttp/guzzle", "type": "library", "description": "Guzzle is a PHP HTTP client library", - "keywords": ["framework", "http", "rest", "web service", "curl", "client", "HTTP client"], + "keywords": [ + "framework", + "http", + "rest", + "web service", + "curl", + "client", + "HTTP client" + ], "homepage": "http://guzzlephp.org/", "license": "MIT", "authors": [ @@ -14,31 +22,33 @@ ], "require": { "php": ">=5.5", - "guzzlehttp/psr7": "^1.4", - "guzzlehttp/promises": "^1.0" + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4" }, "require-dev": { "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", "psr/log": "^1.0" }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "extra": { + "branch-alias": { + "dev-master": "6.3-dev" + } + }, "autoload": { - "files": ["src/functions_include.php"], "psr-4": { "GuzzleHttp\\": "src/" - } + }, + "files": [ + "src/functions_include.php" + ] }, "autoload-dev": { "psr-4": { "GuzzleHttp\\Tests\\": "tests/" } - }, - "suggest": { - "psr/log": "Required for using the Log middleware" - }, - "extra": { - "branch-alias": { - "dev-master": "6.3-dev" - } } } From f61f37400070d4537d03cf6d2b3da75dd4581cd2 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Mon, 19 Nov 2018 15:03:43 +0100 Subject: [PATCH 037/141] Improve github issue templates --- .github/ISSUE_TEMPLATE.md | 28 +--------------------- .github/ISSUE_TEMPLATE/bug_report.md | 18 ++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 14 +++++++++++ .github/ISSUE_TEMPLATE/security_issue.md | 10 ++++++++ .github/ISSUE_TEMPLATE/support_question.md | 10 ++++++++ .github/SUPPORT.md | 18 ++++++++++++++ 6 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/security_issue.md create mode 100644 .github/ISSUE_TEMPLATE/support_question.md create mode 100644 .github/SUPPORT.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index d4ecf20f3..f822c0dd1 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,27 +1 @@ -| Q | A -| ------------ | --- -| Bug? | no|yes -| New Feature? | no|yes -| Version | Specific version or SHA of a commit - - -#### Actual Behavior - -What is the actual behavior? - - -#### Expected Behavior - -What is the behavior you expect? - - -#### Steps to Reproduce - -What are the steps to reproduce this bug? Please add code examples, -screenshots or links to GitHub repositories that reproduce the problem. - - -#### Possible Solutions - -If you have already ideas how to solve the issue, add them here. -(remove this section if not needed) +Please consider using one of the issue templates (bug report, feature request). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..37bc02963 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,18 @@ +--- +name: 🐛 Bug Report +about: Report errors and problems +--- + +**Guzzle version(s) affected**: x.y.z + +**Description** + + +**How to reproduce** + + +**Possible Solution** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..981f4f674 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: 🚀 Feature Request +about: RFC and ideas for new features and improvements +--- + +**Description** + + +**Example** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/security_issue.md b/.github/ISSUE_TEMPLATE/security_issue.md new file mode 100644 index 000000000..84ae4e554 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/security_issue.md @@ -0,0 +1,10 @@ +--- +name: ⛔ Security Issue +about: See the description to report security-related issues +--- + +⚠ PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, SEE BELOW. + +If you have found a security issue in Guzzle, please send the details to +security [at] guzzlephp.org and don't disclose it publicly until we can provide a +fix for it. diff --git a/.github/ISSUE_TEMPLATE/support_question.md b/.github/ISSUE_TEMPLATE/support_question.md new file mode 100644 index 000000000..383c6f40e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support_question.md @@ -0,0 +1,10 @@ +--- +name: ⛔ Support Question +about: See https://github.com/guzzle/guzzle/blob/master/.github/SUPPORT.md for questions about using Guzzle and its components +--- + +We use GitHub issues only to discuss about Guzzle bugs and new features. +For this kind of questions about using Guzzle, +please use any of the support alternatives shown in https://github.com/guzzle/guzzle/blob/master/.github/SUPPORT.md + +Thanks! diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 000000000..0abc59338 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,18 @@ +# Support + +If you're looking for support for Guzzle, here are a few options: + +- [Documentation](http://guzzlephp.org/) +- [Gitter](https://gitter.im/guzzle/guzzle) +- [#guzzle](https://php-http.slack.com/messages/CE6UAAKL4/) channel in [PHP-HTTP](http://php-http.org) Slack team + +Guzzle is a relatively old project, so chances are you will find +much about them on Google or Stack Overflow: + +- [guzzle](https://stackoverflow.com/questions/tagged/guzzle) tag on Stack Overflow (recommended) +- [guzzlehttp](https://stackoverflow.com/questions/tagged/guzzlehttp) tag on Stack Overflow +- [guzzle6](https://stackoverflow.com/questions/tagged/guzzle6) tag on Stack Overflow + + +You can also browse the issue tracker for support requests, +but we encourage everyone to use the channels above instead. From b309ed9ad49331e5bf90a86e175286498190a3da Mon Sep 17 00:00:00 2001 From: Mponos George Date: Wed, 21 Nov 2018 19:36:52 +0200 Subject: [PATCH 038/141] Use test logger of PSR (#2215) --- composer.json | 2 +- tests/MiddlewareTest.php | 37 ++++++++++++------------------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/composer.json b/composer.json index 923ba074b..7c4509b63 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "require-dev": { "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "psr/log": "^1.1" }, "suggest": { "psr/log": "Required for using the Log middleware" diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 27d4a2ac4..2f7881b4c 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -9,14 +9,12 @@ use GuzzleHttp\MessageFormatter; use GuzzleHttp\Middleware; use GuzzleHttp\Promise\PromiseInterface; -use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Log\LoggerInterface; -use Psr\Log\LoggerTrait; use PHPUnit\Framework\TestCase; +use Psr\Log\Test\TestLogger; class MiddlewareTest extends TestCase { @@ -176,55 +174,44 @@ public function testLogsRequestsAndResponses() { $h = new MockHandler([new Response(200)]); $stack = new HandlerStack($h); - $logger = new Logger(); + $logger = new TestLogger(); $formatter = new MessageFormatter(); $stack->push(Middleware::log($logger, $formatter)); $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); $p->wait(); - $this->assertContains('"PUT / HTTP/1.1" 200', $logger->output); + $this->assertCount(1, $logger->records); + $this->assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']); } public function testLogsRequestsAndResponsesCustomLevel() { $h = new MockHandler([new Response(200)]); $stack = new HandlerStack($h); - $logger = new Logger(); + $logger = new TestLogger(); $formatter = new MessageFormatter(); $stack->push(Middleware::log($logger, $formatter, 'debug')); $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); $p->wait(); - $this->assertContains('"PUT / HTTP/1.1" 200', $logger->output); - $this->assertContains('[debug]', $logger->output); + $this->assertCount(1, $logger->records); + $this->assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']); + $this->assertSame('debug', $logger->records[0]['level']); } public function testLogsRequestsAndErrors() { $h = new MockHandler([new Response(404)]); $stack = new HandlerStack($h); - $logger = new Logger(); + $logger = new TestLogger(); $formatter = new MessageFormatter('{code} {error}'); $stack->push(Middleware::log($logger, $formatter)); $stack->push(Middleware::httpErrors()); $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), ['http_errors' => true]); $p->wait(false); - $this->assertContains('PUT http://www.google.com', $logger->output); - $this->assertContains('404 Not Found', $logger->output); - } -} - -/** - * @internal - */ -class Logger implements LoggerInterface -{ - use LoggerTrait; - public $output; - - public function log($level, $message, array $context = []) - { - $this->output .= "[{$level}] {$message}\n"; + $this->assertCount(1, $logger->records); + $this->assertContains('PUT http://www.google.com', $logger->records[0]['message']); + $this->assertContains('404 Not Found', $logger->records[0]['message']); } } From 8db1967d92f55de1b94b175478ed16a7dfc53a90 Mon Sep 17 00:00:00 2001 From: Mponos George Date: Sat, 24 Nov 2018 22:31:03 +0200 Subject: [PATCH 039/141] Fixed typehint $transferTime of constructor (#2217) --- src/TransferStats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TransferStats.php b/src/TransferStats.php index 15f717e1e..23a22a336 100644 --- a/src/TransferStats.php +++ b/src/TransferStats.php @@ -20,7 +20,7 @@ final class TransferStats /** * @param RequestInterface $request Request that was sent. * @param ResponseInterface $response Response received (if any) - * @param null $transferTime Total handler transfer time. + * @param float|null $transferTime Total handler transfer time. * @param mixed $handlerErrorData Handler error data. * @param array $handlerStats Handler specific stats. */ From 59c59cf12af33e6e9398640835c12d352ee46a5c Mon Sep 17 00:00:00 2001 From: George Mponos Date: Sun, 25 Nov 2018 22:09:37 +0200 Subject: [PATCH 040/141] Require ext-json --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 7c4509b63..b0d9c2508 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ ], "require": { "php": ">=5.5", + "ext-json": "*", "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.4" }, From 1a587b777cbc47a5e7ca9c0d1e4714e20b12509a Mon Sep 17 00:00:00 2001 From: George Mponos Date: Sun, 25 Nov 2018 22:11:59 +0200 Subject: [PATCH 041/141] Added sort packages on composer config --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index b0d9c2508..bdadb9263 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,9 @@ "suggest": { "psr/log": "Required for using the Log middleware" }, + "config": { + "sort-packages": true + }, "extra": { "branch-alias": { "dev-master": "6.3-dev" From 3ef0c808db62ffb1c566b9940234b88807fa1eb9 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Thu, 6 Dec 2018 16:41:22 -0600 Subject: [PATCH 042/141] Clean up concurrent requests documentation --- docs/quickstart.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 1ff812205..69ceb9d4d 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -184,17 +184,16 @@ requests. 'webp' => $client->getAsync('/image/webp') ]; - // Wait on all of the requests to complete. Throws a ConnectException + // Wait for the requests to complete; throws a ConnectException // if any of the requests fail - $results = Promise\unwrap($promises); + $responses = Promise\unwrap($promises); // Wait for the requests to complete, even if some of them fail - $results = Promise\settle($promises)->wait(); + $responses = Promise\settle($promises)->wait(); - // You can access each result using the key provided to the unwrap - // function. - echo $results['image']['value']->getHeader('Content-Length')[0] - echo $results['png']['value']->getHeader('Content-Length')[0] + // You can access each response using the key of the promise + echo $responses['image']->getHeader('Content-Length')[0] + echo $responses['png']->getHeader('Content-Length')[0] You can use the ``GuzzleHttp\Pool`` object when you have an indeterminate amount of requests you wish to send. From 9799bbcb90ed2df488adb0924169163156483e52 Mon Sep 17 00:00:00 2001 From: Christoffer Ekblom Date: Fri, 7 Dec 2018 09:18:25 +0100 Subject: [PATCH 043/141] Fixed 'command not found' (#2197) * Fixed 'command not found' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 58f54277b..0e826e816 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ require 'vendor/autoload.php'; You can then later update Guzzle using composer: ```bash -composer.phar update +php composer.phar update ``` From d4141ca962683a09f27b17823d6dc08b8010eabe Mon Sep 17 00:00:00 2001 From: Rafael K Date: Fri, 21 Dec 2018 17:15:38 +0100 Subject: [PATCH 044/141] Prevent Exception (#2212) Add test for checking curl release --- tests/Handler/CurlFactoryTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index 0907c21fe..af52c58d2 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -743,4 +743,13 @@ public function testDoesNotRewindUnseekableBody() $this->assertSame(1024 * 1024, $body->tell()); } + + public function testRelease() + { + $factory = new CurlFactory(1); + $easyHandle = new EasyHandle(); + $easyHandle->handle = curl_init(); + + $this->assertEmpty($factory->release($easyHandle)); + } } From 05ffabc88f3f360ccbc3843860b07c156e0f2fa3 Mon Sep 17 00:00:00 2001 From: Oxicode Date: Tue, 8 Jan 2019 15:57:56 -0500 Subject: [PATCH 045/141] Update README.md --- README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0e826e816..98bce02fd 100644 --- a/README.md +++ b/README.md @@ -21,19 +21,18 @@ trivial to integrate with web services. ```php $client = new \GuzzleHttp\Client(); -$res = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); -echo $res->getStatusCode(); -// 200 -echo $res->getHeaderLine('content-type'); -// 'application/json; charset=utf8' -echo $res->getBody(); -// '{"id": 1420053, "name": "guzzle", ...}' - -// Send an asynchronous request. +$request = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); + +echo $request->getStatusCode(); # 200 +echo $request->getHeaderLine('content-type'); # 'application/json; charset=utf8' +echo $request->getBody(); # '{"id": 1420053, "name": "guzzle", ...}' + +# Send an asynchronous request. $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org'); $promise = $client->sendAsync($request)->then(function ($response) { echo 'I completed! ' . $response->getBody(); }); + $promise->wait(); ``` From d394afd1f357bfa61939d188e9ed983f59466512 Mon Sep 17 00:00:00 2001 From: Oxicode Date: Mon, 14 Jan 2019 09:56:56 -0500 Subject: [PATCH 046/141] Fix name var --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 98bce02fd..074ea45df 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ trivial to integrate with web services. ```php $client = new \GuzzleHttp\Client(); -$request = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); +$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); -echo $request->getStatusCode(); # 200 -echo $request->getHeaderLine('content-type'); # 'application/json; charset=utf8' -echo $request->getBody(); # '{"id": 1420053, "name": "guzzle", ...}' +echo $response->getStatusCode(); # 200 +echo $response->getHeaderLine('content-type'); # 'application/json; charset=utf8' +echo $response->getBody(); # '{"id": 1420053, "name": "guzzle", ...}' # Send an asynchronous request. $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org'); From fa745406c2f48210693ba05f11280a1473037b2f Mon Sep 17 00:00:00 2001 From: Jared Howland Date: Tue, 26 Feb 2019 10:21:14 -0700 Subject: [PATCH 047/141] [FIX] Code block in Quickstart documentation (#2268) --- docs/quickstart.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 4ac28e684..1c6988c3a 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -192,8 +192,8 @@ requests. $responses = Promise\settle($promises)->wait(); // You can access each response using the key of the promise - echo $responses['image']->getHeader('Content-Length')[0] - echo $responses['png']->getHeader('Content-Length')[0] + echo $responses['image']->getHeader('Content-Length')[0]; + echo $responses['png']->getHeader('Content-Length')[0]; You can use the ``GuzzleHttp\Pool`` object when you have an indeterminate amount of requests you wish to send. From 693d98d8bcd220ba77fa6593cf379e56f5036efe Mon Sep 17 00:00:00 2001 From: Benjamin Morel Date: Wed, 20 Mar 2019 16:56:14 +0100 Subject: [PATCH 048/141] The $downloadTotal parameter can be zero in progress callback --- docs/request-options.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/request-options.rst b/docs/request-options.rst index 7fbeeaa3e..47f5c66a7 100644 --- a/docs/request-options.rst +++ b/docs/request-options.rst @@ -737,7 +737,7 @@ progress The function accepts the following positional arguments: -- the total number of bytes expected to be downloaded +- the total number of bytes expected to be downloaded, zero if unknown - the number of bytes downloaded so far - the total number of bytes expected to be uploaded - the number of bytes uploaded so far From 136239dffd75409d0602c3b17c744aa4cb04ed91 Mon Sep 17 00:00:00 2001 From: Erik Booij Date: Wed, 20 Mar 2019 09:42:08 +0100 Subject: [PATCH 049/141] Fix unit test that is breaking because of hardcoded cookie expiration date --- tests/Cookie/CookieJarTest.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/Cookie/CookieJarTest.php b/tests/Cookie/CookieJarTest.php index 8416c9a24..f0fad497d 100644 --- a/tests/Cookie/CookieJarTest.php +++ b/tests/Cookie/CookieJarTest.php @@ -1,6 +1,9 @@ "fpc=foobar; expires=Fri, 02-Mar-2019 02:17:40 GMT; path=;" + 'Set-Cookie' => "fpc=foobar; expires={$this->futureExpirationDate()}; path=;" )); $request = new Request('GET', 'http://www.example.com'); $this->jar->extractCookies($request, $response); @@ -396,11 +399,11 @@ public function testCookiePathWithEmptySetCookiePath($uriPath, $cookiePath) $response = (new Response(200)) ->withAddedHeader( 'Set-Cookie', - "foo=bar; expires=Fri, 02-Mar-2019 02:17:40 GMT; domain=www.example.com; path=;" + "foo=bar; expires={$this->futureExpirationDate()}; domain=www.example.com; path=;" ) ->withAddedHeader( 'Set-Cookie', - "bar=foo; expires=Fri, 02-Mar-2019 02:17:40 GMT; domain=www.example.com; path=foobar;" + "bar=foo; expires={$this->futureExpirationDate()}; domain=www.example.com; path=foobar;" ) ; $request = (new Request('GET', $uriPath))->withHeader('Host', 'www.example.com'); @@ -409,4 +412,9 @@ public function testCookiePathWithEmptySetCookiePath($uriPath, $cookiePath) $this->assertSame($cookiePath, $this->jar->toArray()[0]['Path']); $this->assertSame($cookiePath, $this->jar->toArray()[1]['Path']); } + + private function futureExpirationDate() + { + return (new DateTimeImmutable)->add(new DateInterval('P1D'))->format(DateTime::COOKIE); + } } From e3177967220089725dfbd61e2241e501ef655787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20S=C3=A1gi-Kaz=C3=A1r?= Date: Mon, 15 Apr 2019 07:52:34 +0200 Subject: [PATCH 050/141] Remove getContents --- docs/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/testing.rst b/docs/testing.rst index 2ca074a4a..92bfd6e3d 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -44,7 +44,7 @@ a response or exception by shifting return values off of a queue. $response = $client->request('GET', '/'); echo $response->getStatusCode(); //> 200 - echo $response->getBody()->getContents(); + echo $response->getBody(); //> Hello, World // The second request is intercepted with the second response. echo $client->request('GET', '/')->getStatusCode(); From f5203f739df4e0ff83b01eadc23f2501dc6336f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20S=C3=A1gi-Kaz=C3=A1r?= Date: Mon, 15 Apr 2019 07:58:14 +0200 Subject: [PATCH 051/141] Remove constant visibility --- src/Handler/CurlFactory.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index 53aa6bc3f..7da4af8d5 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -14,8 +14,9 @@ */ class CurlFactory implements CurlFactoryInterface { - private const CURL_VERSION_STR = 'curl_version'; - private const LOW_CURL_VERSION_NUMBER = '7.21.2'; + const CURL_VERSION_STR = 'curl_version'; + const LOW_CURL_VERSION_NUMBER = '7.21.2'; + /** @var array */ private $handles = []; From 3b0452a3a0347e74c42e9b9a2e9b11158531ce14 Mon Sep 17 00:00:00 2001 From: Dzhuneyt <1754428+Dzhuneyt@users.noreply.github.com> Date: Mon, 15 Apr 2019 09:36:28 +0300 Subject: [PATCH 052/141] Replace microtime() usages with hrtime() (#2242) * Replace microtime() usages with hrtime() * Replace microtime() usages with hrtime() * Wrongly used 1e9 instead of 1e7 * Replaced 1e7 with 1e9 * Marked function as @internal * Internal function name prefixed with underscore --- src/Handler/CurlMultiHandler.php | 6 +++--- src/Handler/StreamHandler.php | 4 ++-- src/functions.php | 12 ++++++++++++ tests/Handler/CurlHandlerTest.php | 4 ++-- tests/Handler/CurlMultiHandlerTest.php | 4 ++-- tests/Handler/StreamHandlerTest.php | 4 ++-- tests/functionsTest.php | 5 +++++ 7 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Handler/CurlMultiHandler.php b/src/Handler/CurlMultiHandler.php index 7097835d1..d8297623c 100644 --- a/src/Handler/CurlMultiHandler.php +++ b/src/Handler/CurlMultiHandler.php @@ -88,7 +88,7 @@ public function tick() { // Add any delayed handles if needed. if ($this->delays) { - $currentTime = microtime(true); + $currentTime = \GuzzleHttp\_current_time(); foreach ($this->delays as $id => $delay) { if ($currentTime >= $delay) { unset($this->delays[$id]); @@ -140,7 +140,7 @@ private function addRequest(array $entry) if (empty($easy->options['delay'])) { curl_multi_add_handle($this->_mh, $easy->handle); } else { - $this->delays[$id] = microtime(true) + ($easy->options['delay'] / 1000); + $this->delays[$id] = \GuzzleHttp\_current_time() + ($easy->options['delay'] / 1000); } } @@ -192,7 +192,7 @@ private function processMessages() private function timeToNext() { - $currentTime = microtime(true); + $currentTime = \GuzzleHttp\_current_time(); $nextTime = PHP_INT_MAX; foreach ($this->delays as $time) { if ($time < $nextTime) { diff --git a/src/Handler/StreamHandler.php b/src/Handler/StreamHandler.php index 741e02d2a..0dedd7da4 100644 --- a/src/Handler/StreamHandler.php +++ b/src/Handler/StreamHandler.php @@ -33,7 +33,7 @@ public function __invoke(RequestInterface $request, array $options) usleep($options['delay'] * 1000); } - $startTime = isset($options['on_stats']) ? microtime(true) : null; + $startTime = isset($options['on_stats']) ? \GuzzleHttp\_current_time() : null; try { // Does not support the expect header. @@ -82,7 +82,7 @@ private function invokeStats( $stats = new TransferStats( $request, $response, - microtime(true) - $startTime, + \GuzzleHttp\_current_time() - $startTime, $error, [] ); diff --git a/src/functions.php b/src/functions.php index 5081bb5fa..3c472bc6a 100644 --- a/src/functions.php +++ b/src/functions.php @@ -331,3 +331,15 @@ function json_encode($value, $options = 0, $depth = 512) return $json; } + +/** + * Wrapper for the hrtime() or microtime() functions + * (depending on the PHP version, one of the two is used) + * + * @return float|mixed UNIX timestamp + * @internal + */ +function _current_time() +{ + return function_exists('hrtime') ? hrtime(true) / 1e9 : microtime(true); +} diff --git a/tests/Handler/CurlHandlerTest.php b/tests/Handler/CurlHandlerTest.php index 25c499020..6a4d233a0 100644 --- a/tests/Handler/CurlHandlerTest.php +++ b/tests/Handler/CurlHandlerTest.php @@ -47,9 +47,9 @@ public function testDoesSleep() Server::enqueue([$response]); $a = new CurlHandler(); $request = new Request('GET', Server::$url); - $s = microtime(true); + $s = \GuzzleHttp\_current_time(); $a($request, ['delay' => 0.1])->wait(); - $this->assertGreaterThan(0.0001, microtime(true) - $s); + $this->assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); } public function testCreatesCurlErrorsWithContext() diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 6c987afb8..03043f5ff 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -68,10 +68,10 @@ public function testDelaysConcurrently() Server::flush(); Server::enqueue([new Response()]); $a = new CurlMultiHandler(); - $expected = microtime(true) + (100 / 1000); + $expected = \GuzzleHttp\_current_time() + (100 / 1000); $response = $a(new Request('GET', Server::$url), ['delay' => 100]); $response->wait(); - $this->assertGreaterThanOrEqual($expected, microtime(true)); + $this->assertGreaterThanOrEqual($expected, \GuzzleHttp\_current_time()); } public function testUsesTimeoutEnvironmentVariables() diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index 6c10ec3f0..f62994896 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -506,9 +506,9 @@ public function testDoesSleep() Server::enqueue([$response]); $a = new StreamHandler(); $request = new Request('GET', Server::$url); - $s = microtime(true); + $s = \GuzzleHttp\_current_time(); $a($request, ['delay' => 0.1])->wait(); - $this->assertGreaterThan(0.0001, microtime(true) - $s); + $this->assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); } /** diff --git a/tests/functionsTest.php b/tests/functionsTest.php index fd65d41b6..bf5c8d8b8 100644 --- a/tests/functionsTest.php +++ b/tests/functionsTest.php @@ -128,6 +128,11 @@ public function testDecodesJsonAndThrowsOnError() { \GuzzleHttp\json_decode('{{]]'); } + + public function testCurrentTime() + { + $this->assertGreaterThan(0, GuzzleHttp\_current_time()); + } } final class StrClass From d808f797eb379cdb7a1951b3f717370a18762170 Mon Sep 17 00:00:00 2001 From: Marcel Hernandez Date: Wed, 10 Apr 2019 15:32:09 +0200 Subject: [PATCH 053/141] collect appconnect_time --- src/Handler/CurlFactory.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index 7da4af8d5..e349bb4c4 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -120,6 +120,7 @@ public static function finish( private static function invokeStats(EasyHandle $easy) { $curlStats = curl_getinfo($easy->handle); + $curlStats['appconnect_time'] = curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME); $stats = new TransferStats( $easy->request, $easy->response, @@ -139,6 +140,7 @@ private static function finishError( $ctx = [ 'errno' => $easy->errno, 'error' => curl_error($easy->handle), + 'appconnect_time' => curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME), ] + curl_getinfo($easy->handle); $ctx[self::CURL_VERSION_STR] = curl_version()['version']; $factory->release($easy); From 40aa8b1642762ed00ea7cb4a5d4aa8219126c87b Mon Sep 17 00:00:00 2001 From: Marcel Hernandez Date: Wed, 10 Apr 2019 15:46:08 +0200 Subject: [PATCH 054/141] test presence of appconnect_time key in curl stats array --- tests/Handler/CurlFactoryTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index af52c58d2..d1e4e9980 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -685,6 +685,7 @@ public function testInvokesOnStatsOnSuccess() (string) $gotStats->getRequest()->getUri() ); $this->assertGreaterThan(0, $gotStats->getTransferTime()); + $this->assertArrayHasKey('appconnect_time', $gotStats->getHandlerStats()); } public function testInvokesOnStatsOnError() @@ -711,6 +712,7 @@ public function testInvokesOnStatsOnError() ); $this->assertInternalType('float', $gotStats->getTransferTime()); $this->assertInternalType('int', $gotStats->getHandlerErrorData()); + $this->assertArrayHasKey('appconnect_time', $gotStats->getHandlerStats()); } public function testRewindsBodyIfPossible() From fe346ef3c482e65b0ba4427ba8c694a072aaa0a4 Mon Sep 17 00:00:00 2001 From: Erik Booij Date: Thu, 7 Mar 2019 09:46:39 +0100 Subject: [PATCH 055/141] Make GuzzleException extend Throwable whereever it's available --- src/Exception/GuzzleException.php | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Exception/GuzzleException.php b/src/Exception/GuzzleException.php index 510778f6e..c232fa637 100644 --- a/src/Exception/GuzzleException.php +++ b/src/Exception/GuzzleException.php @@ -1,13 +1,20 @@ Date: Tue, 7 May 2019 23:57:52 -0300 Subject: [PATCH 056/141] [tests] Add test covering client responses --- tests/ClientTest.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index e9bad4c1e..debcb6c8c 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -674,4 +674,26 @@ public function testHandlerIsCallable() { new Client(['handler' => 'not_cllable']); } + + public function testResponseBodyAsString() + { + $responseBody = '{ "package": "guzzle" }'; + $mock = new MockHandler([new Response(200, ['Content-Type' => 'application/json'], $responseBody)]); + $client = new Client(['handler' => $mock]); + $request = new Request('GET', 'http://foo.com'); + $response = $client->send($request, ['json' => ['a' => 'b']]); + + $this->assertSame($responseBody, (string) $response->getBody()); + } + + public function testResponseContent() + { + $responseBody = '{ "package": "guzzle" }'; + $mock = new MockHandler([new Response(200, ['Content-Type' => 'application/json'], $responseBody)]); + $client = new Client(['handler' => $mock]); + $request = new Request('POST', 'http://foo.com'); + $response = $client->send($request, ['json' => ['a' => 'b']]); + + $this->assertSame($responseBody, $response->getBody()->getContents()); + } } From d0a7b5939c09e3fa92eff38da223bc6634f6d43b Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 12 May 2019 13:11:06 +0100 Subject: [PATCH 057/141] Use PHP 7.3 in the Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index efc11656f..f6a095230 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN set -xe \ && composer require guzzlehttp/guzzle -FROM php:7.2 +FROM php:7.3 RUN mkdir /guzzle From 069b926fa96f2efed4ba98bc17f8f8fe7b00e10c Mon Sep 17 00:00:00 2001 From: Andrey Bolonin Date: Sun, 14 Jul 2019 15:40:46 +0300 Subject: [PATCH 058/141] add php 7.4snapshot --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6f3ef75e4..a99c69970 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ php: - 7.1 - 7.2 - 7.3 + - 7.4snapshot - nightly before_script: From 193489808f9e7d5b01153d75dfa66fbbaac782c4 Mon Sep 17 00:00:00 2001 From: Amin Shojaei Date: Wed, 31 Jul 2019 13:16:45 +0430 Subject: [PATCH 059/141] Use composer command instead of php composer.phar --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 074ea45df..a5ef18aee 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ curl -sS https://getcomposer.org/installer | php Next, run the Composer command to install the latest stable version of Guzzle: ```bash -php composer.phar require guzzlehttp/guzzle +composer require guzzlehttp/guzzle ``` After installing, you need to require Composer's autoloader: @@ -68,7 +68,7 @@ require 'vendor/autoload.php'; You can then later update Guzzle using composer: ```bash -php composer.phar update +composer update ``` From f18a4a2e7f8263acb39c450c5ee8800b5d69fa87 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 5 Aug 2019 17:08:16 +0100 Subject: [PATCH 060/141] Fix PHPUnit Configuration warning --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 70da48c2f..5369af3f9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -3,7 +3,7 @@ backupGlobals="true" colors="true"> - + tests From b55fb938ac4f34d2d089f8e726630f92fe21e866 Mon Sep 17 00:00:00 2001 From: Benjamin Morel Date: Thu, 8 Aug 2019 11:52:10 +0200 Subject: [PATCH 061/141] allow_redirects.referer is false by default --- src/RequestOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RequestOptions.php b/src/RequestOptions.php index c6aacfb15..5c0fd19d3 100644 --- a/src/RequestOptions.php +++ b/src/RequestOptions.php @@ -22,7 +22,7 @@ final class RequestOptions * - strict: (bool, default=false) Set to true to use strict redirects * meaning redirect POST requests with POST requests vs. doing what most * browsers do which is redirect POST requests with GET requests - * - referer: (bool, default=true) Set to false to disable the Referer + * - referer: (bool, default=false) Set to true to enable the Referer * header. * - protocols: (array, default=['http', 'https']) Allowed redirect * protocols. From e26a75f024b9a51e94d370f32316f6e9e2e016d0 Mon Sep 17 00:00:00 2001 From: Bas Peeters Date: Tue, 13 Aug 2019 09:15:59 +0200 Subject: [PATCH 062/141] Factor http code bounds into exception test --- tests/Exception/RequestExceptionTest.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/Exception/RequestExceptionTest.php b/tests/Exception/RequestExceptionTest.php index 5a826d36f..55c25c6e7 100644 --- a/tests/Exception/RequestExceptionTest.php +++ b/tests/Exception/RequestExceptionTest.php @@ -60,18 +60,27 @@ public function testCreatesServerErrorResponseException() public function testCreatesGenericErrorResponseException() { - $e = RequestException::create(new Request('GET', '/'), new Response(600)); + $e = RequestException::create(new Request('GET', '/'), new Response(300)); $this->assertContains( 'GET /', $e->getMessage() ); $this->assertContains( - '600 ', + '300 ', $e->getMessage() ); $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); } + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Status code must be an integer value between 1xx and 5xx. + */ + public function testThrowsInvalidArgumentExceptionOnOutOfBoundsResponseCode() + { + throw RequestException::create(new Request('GET', '/'), new Response(600)); + } + public function dataPrintableResponses() { return [ From da21d40ad9e80171ba630f7e0e8f84bb93193874 Mon Sep 17 00:00:00 2001 From: Bas Peeters Date: Tue, 13 Aug 2019 09:35:30 +0200 Subject: [PATCH 063/141] Add cookie as a string in middleware test --- tests/MiddlewareTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 2f7881b4c..1d5e276d2 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -26,7 +26,7 @@ public function testAddsCookiesToRequests() [ function (RequestInterface $request) { return new Response(200, [ - 'Set-Cookie' => new SetCookie([ + 'Set-Cookie' => (string) new SetCookie([ 'Name' => 'name', 'Value' => 'value', 'Domain' => 'foo.com' From 7a97aae678539c5f8604ac037667ece5fe01e0dd Mon Sep 17 00:00:00 2001 From: Bas Peeters Date: Tue, 13 Aug 2019 10:56:21 +0200 Subject: [PATCH 064/141] Clear userinfo with empty user according to PSR7 --- src/RedirectMiddleware.php | 2 +- tests/RedirectMiddlewareTest.php | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index 131b77179..bff4e4e8a 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -186,7 +186,7 @@ public function modifyRequest( if ($options['allow_redirects']['referer'] && $modify['uri']->getScheme() === $request->getUri()->getScheme() ) { - $uri = $request->getUri()->withUserInfo('', ''); + $uri = $request->getUri()->withUserInfo(''); $modify['set_headers']['Referer'] = (string) $uri; } else { $modify['remove_headers'][] = 'Referer'; diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index bf5fb0e48..39fbb5c3e 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -132,6 +132,26 @@ public function testAddsRefererHeader() ); } + public function testAddsRefererHeaderButClearsUserInfo() + { + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://test.com']), + new Response(200) + ]); + $stack = new HandlerStack($mock); + $stack->push(Middleware::redirect()); + $handler = $stack->resolve(); + $request = new Request('GET', 'http://foo:bar@example.com?a=b'); + $promise = $handler($request, [ + 'allow_redirects' => ['max' => 2, 'referer' => true] + ]); + $promise->wait(); + $this->assertSame( + 'http://example.com?a=b', + $mock->getLastRequest()->getHeaderLine('Referer') + ); + } + public function testAddsGuzzleRedirectHeader() { $mock = new MockHandler([ From 261cb1f6d73b4fa3351bd4115cd7d5fb1a39ce1a Mon Sep 17 00:00:00 2001 From: Bas Peeters Date: Tue, 13 Aug 2019 11:32:15 +0200 Subject: [PATCH 065/141] Set dist in travis to support PHP 5.5 --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6f3ef75e4..42887db00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ language: php sudo: false php: - - 5.5 - 5.6 - 7.0 - 7.1 @@ -25,7 +24,9 @@ matrix: - php: hhvm dist: trusty - php: nightly - include: + include: + - php: 5.5 + dist: trusty - php: hhvm dist: trusty fast_finish: true From c90af9d0bcbff719bbd382ddefcc748814a2d50c Mon Sep 17 00:00:00 2001 From: Karl Scheirer Date: Fri, 23 Aug 2019 12:24:38 -0700 Subject: [PATCH 066/141] Typo in Pool.php fix typo --- src/Pool.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pool.php b/src/Pool.php index 8f1be33cd..05c854aeb 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -6,7 +6,7 @@ use GuzzleHttp\Promise\EachPromise; /** - * Sends and iterator of requests concurrently using a capped pool size. + * Sends an iterator of requests concurrently using a capped pool size. * * The pool will read from an iterator until it is cancelled or until the * iterator is consumed. When a request is yielded, the request is sent after From a8bc49c996934b0c31da7506bb855c0becce802d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Benoist?= Date: Wed, 24 Jul 2019 14:45:25 +0200 Subject: [PATCH 067/141] Prevent concurrent writes Concurrent writes might lead to invalid JSON being saved in the cookie jar. --- src/Cookie/FileCookieJar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cookie/FileCookieJar.php b/src/Cookie/FileCookieJar.php index 9887c1d54..0de809099 100644 --- a/src/Cookie/FileCookieJar.php +++ b/src/Cookie/FileCookieJar.php @@ -56,7 +56,7 @@ public function save($filename) } $jsonStr = \GuzzleHttp\json_encode($json); - if (false === file_put_contents($filename, $jsonStr)) { + if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) { throw new \RuntimeException("Unable to save file {$filename}"); } } From 7c8d53b3007cd7b41bdb8d0fb887cb1322eabb61 Mon Sep 17 00:00:00 2001 From: Mike Wink Date: Thu, 12 Sep 2019 11:32:34 +0200 Subject: [PATCH 068/141] Fixed a little typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a tiny typo in the proxy section. "…it is up to you[r] to provide the no value…" --- docs/request-options.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/request-options.rst b/docs/request-options.rst index 47f5c66a7..14be1dac7 100644 --- a/docs/request-options.rst +++ b/docs/request-options.rst @@ -788,7 +788,7 @@ host names that should not be proxied to. Guzzle will automatically populate this value with your environment's ``NO_PROXY`` environment variable. However, when providing a ``proxy`` - request option, it is up to your to provide the ``no`` value parsed from + request option, it is up to you to provide the ``no`` value parsed from the ``NO_PROXY`` environment variable (e.g., ``explode(',', getenv('NO_PROXY'))``). From b07fcf95e7e953218ccad9f8ec7eb1986efc5ecb Mon Sep 17 00:00:00 2001 From: Vahid Fazlollahzade Date: Fri, 11 Oct 2019 20:37:20 +0330 Subject: [PATCH 069/141] Added a note to Overview to mention cURL Without cURL, concurrency is not available. See https://bit.ly/33fA7RU and https://bit.ly/2IFVG6o for some SO questions. --- docs/overview.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/overview.rst b/docs/overview.rst index 1ddca55e2..9bfddcf49 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -16,6 +16,14 @@ Requirements Guzzle no longer requires cURL in order to send HTTP requests. Guzzle will use the PHP stream wrapper to send HTTP requests if cURL is not installed. Alternatively, you can provide your own HTTP handler used to send requests. + + +.. note:: + + Although Guzzle does not require cURL in order to work properly, but without + cURL, concurrent requests are sent sequentially. In order to get truely + concurrent requests, install cURL extension for you PHP installation. + .. _installation: From 2b4f1cc9cc237a3531a113df5c7bc0fc792db309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20S=C3=A1gi-Kaz=C3=A1r?= Date: Mon, 14 Oct 2019 11:12:37 +0200 Subject: [PATCH 070/141] Update overview.rst --- docs/overview.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/overview.rst b/docs/overview.rst index 9bfddcf49..6d3fa07ee 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -16,13 +16,7 @@ Requirements Guzzle no longer requires cURL in order to send HTTP requests. Guzzle will use the PHP stream wrapper to send HTTP requests if cURL is not installed. Alternatively, you can provide your own HTTP handler used to send requests. - - -.. note:: - - Although Guzzle does not require cURL in order to work properly, but without - cURL, concurrent requests are sent sequentially. In order to get truely - concurrent requests, install cURL extension for you PHP installation. + Keep in mind that cURL is still required for sending concurrent requests. .. _installation: From cbc63fb37f7389b6b35ab8bf4a668184903b47ce Mon Sep 17 00:00:00 2001 From: voprak <45544596+voprak@users.noreply.github.com> Date: Fri, 18 Oct 2019 04:22:48 -0500 Subject: [PATCH 071/141] Add ability to test transfer time (#2362) * Add ability to test transfer time --- src/Handler/MockHandler.php | 3 ++- tests/Handler/MockHandlerTest.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Handler/MockHandler.php b/src/Handler/MockHandler.php index d892061c7..d5c449c1d 100644 --- a/src/Handler/MockHandler.php +++ b/src/Handler/MockHandler.php @@ -182,7 +182,8 @@ private function invokeStats( $reason = null ) { if (isset($options['on_stats'])) { - $stats = new TransferStats($request, $response, 0, $reason); + $transferTime = isset($options['transfer_time']) ? $options['transfer_time'] : 0; + $stats = new TransferStats($request, $response, $transferTime, $reason); call_user_func($options['on_stats'], $stats); } } diff --git a/tests/Handler/MockHandlerTest.php b/tests/Handler/MockHandlerTest.php index e067a8b48..f050ef299 100644 --- a/tests/Handler/MockHandlerTest.php +++ b/tests/Handler/MockHandlerTest.php @@ -221,4 +221,18 @@ public function testInvokesOnStatsFunctionForError() $this->assertNull($stats->getResponse()); $this->assertSame($request, $stats->getRequest()); } + + public function testTransferTime() + { + $e = new \Exception('a'); + $c = null; + $mock = new MockHandler([$e], null, function ($v) use (&$c) { $c = $v; }); + $request = new Request('GET', 'http://example.com'); + $stats = null; + $onStats = function (TransferStats $s) use (&$stats) { + $stats = $s; + }; + $mock($request, [ 'on_stats' => $onStats, 'transfer_time' => 0.4 ])->wait(false); + $this->assertEquals(0.4, $stats->getTransferTime()); + } } From 354b4b5575b8835929df03eda6cfd079b3589548 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 18 Oct 2019 12:14:45 +0200 Subject: [PATCH 072/141] Added changelog for 6.4.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17badd756..d8cb2a201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## 6.4.0 - 2018-10-18 + +* Improvement: Improved error messages when using cUrl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) +* Fix: Test if response is readable before returing a summery in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) +* Fix: Add support for GUZZLE_CURL_SELECT_TIMEOUT environment variable [#2161](https://github.com/guzzle/guzzle/pull/2161) +* Improvement: Added `GuzzleHttp\Exception\InvalidArgumentException` [#2163](https://github.com/guzzle/guzzle/pull/2163) +* Improvement: Added `GuzzleHttp\_current_time()` to use `hrtime()` if that function exists. [#2242](https://github.com/guzzle/guzzle/pull/2242) +* Improvement: Added cUrl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284) +* Improvement: Make GuzzleException extend Throwable whereever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273) +* Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335) +* Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362) + ## 6.3.3 - 2018-04-22 * Fix: Default headers when decode_content is specified From 5084d8e9f7721f3b7ab502d501e486becc3671d9 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Fri, 18 Oct 2019 12:17:52 +0200 Subject: [PATCH 073/141] Require latest version of guzzlehttp/psr7 (#2373) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bdadb9263..c55325753 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "php": ">=5.5", "ext-json": "*", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4" + "guzzlehttp/psr7": "^1.6.1" }, "require-dev": { "ext-curl": "*", From 294a66294ed9cb7e7f216a7dc4e1eed98513402a Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 18 Oct 2019 12:36:53 +0200 Subject: [PATCH 074/141] Added workflows for static analysis --- .github/workflows/bc.yml | 10 ++++++++++ .github/workflows/static.yml | 22 +++++++++++++++++++++ .php_cs | 21 ++++++++++++++++++++ phpstan.neon.dist | 9 +++++++++ src/Cookie/FileCookieJar.php | 1 + src/Cookie/SessionCookieJar.php | 1 + src/Exception/ClientException.php | 4 +++- src/Exception/GuzzleException.php | 9 ++++++--- src/Exception/InvalidArgumentException.php | 4 +++- src/Exception/ServerException.php | 4 +++- src/Exception/TooManyRedirectsException.php | 4 +++- src/Exception/TransferException.php | 4 +++- src/Middleware.php | 2 +- src/functions.php | 3 ++- 14 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/bc.yml create mode 100644 .github/workflows/static.yml create mode 100644 .php_cs create mode 100644 phpstan.neon.dist diff --git a/.github/workflows/bc.yml b/.github/workflows/bc.yml new file mode 100644 index 000000000..2d288edfe --- /dev/null +++ b/.github/workflows/bc.yml @@ -0,0 +1,10 @@ +on: [push, pull_request] +name: Roave +jobs: + roave_bc_check: + name: BC Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Roave BC Check + uses: docker://nyholm/roave-bc-check-ga diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml new file mode 100644 index 000000000..14900316a --- /dev/null +++ b/.github/workflows/static.yml @@ -0,0 +1,22 @@ +on: [push, pull_request] +name: Static analysis +jobs: + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: PHPStan + uses: docker://oskarstark/phpstan-ga + with: + args: analyze --no-progress + + php-cs-fixer: + name: PHP-CS-Fixer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: PHP-CS-Fixer + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --dry-run --diff-format udiff diff --git a/.php_cs b/.php_cs new file mode 100644 index 000000000..a8ace8aab --- /dev/null +++ b/.php_cs @@ -0,0 +1,21 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'declare_strict_types' => false, + 'concat_space' => ['spacing'=>'one'], + // 'ordered_imports' => true, + // 'phpdoc_align' => ['align'=>'vertical'], + // 'native_function_invocation' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__.'/src') + ->name('*.php') + ) +; + +return $config; diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 000000000..4ef4192d3 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,9 @@ +parameters: + level: 1 + paths: + - src + + ignoreErrors: + - + message: '#Function uri_template not found#' + path: %currentWorkingDirectory%/src/functions.php diff --git a/src/Cookie/FileCookieJar.php b/src/Cookie/FileCookieJar.php index 0de809099..3fb8600ef 100644 --- a/src/Cookie/FileCookieJar.php +++ b/src/Cookie/FileCookieJar.php @@ -23,6 +23,7 @@ class FileCookieJar extends CookieJar */ public function __construct($cookieFile, $storeSessionCookies = false) { + parent::__construct(); $this->filename = $cookieFile; $this->storeSessionCookies = $storeSessionCookies; diff --git a/src/Cookie/SessionCookieJar.php b/src/Cookie/SessionCookieJar.php index 4497bcf03..0224a2447 100644 --- a/src/Cookie/SessionCookieJar.php +++ b/src/Cookie/SessionCookieJar.php @@ -22,6 +22,7 @@ class SessionCookieJar extends CookieJar */ public function __construct($sessionKey, $storeSessionCookies = false) { + parent::__construct(); $this->sessionKey = $sessionKey; $this->storeSessionCookies = $storeSessionCookies; $this->load(); diff --git a/src/Exception/ClientException.php b/src/Exception/ClientException.php index f95c09f2b..4cfd393cc 100644 --- a/src/Exception/ClientException.php +++ b/src/Exception/ClientException.php @@ -4,4 +4,6 @@ /** * Exception when a client error is encountered (4xx codes) */ -class ClientException extends BadResponseException {} +class ClientException extends BadResponseException +{ +} diff --git a/src/Exception/GuzzleException.php b/src/Exception/GuzzleException.php index c232fa637..27b2722b0 100644 --- a/src/Exception/GuzzleException.php +++ b/src/Exception/GuzzleException.php @@ -4,7 +4,9 @@ use Throwable; if (interface_exists(Throwable::class)) { - interface GuzzleException extends Throwable {} + interface GuzzleException extends Throwable + { + } } else { /** * @method string getMessage() @@ -15,6 +17,7 @@ interface GuzzleException extends Throwable {} * @method array getTrace() * @method string getTraceAsString() */ - interface GuzzleException {} + interface GuzzleException + { + } } - diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 15b7f9137..bfd20e232 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -2,4 +2,6 @@ namespace GuzzleHttp\Exception; -final class InvalidArgumentException extends \InvalidArgumentException implements GuzzleException {} +final class InvalidArgumentException extends \InvalidArgumentException implements GuzzleException +{ +} diff --git a/src/Exception/ServerException.php b/src/Exception/ServerException.php index 7cdd34086..127094c14 100644 --- a/src/Exception/ServerException.php +++ b/src/Exception/ServerException.php @@ -4,4 +4,6 @@ /** * Exception when a server error is encountered (5xx codes) */ -class ServerException extends BadResponseException {} +class ServerException extends BadResponseException +{ +} diff --git a/src/Exception/TooManyRedirectsException.php b/src/Exception/TooManyRedirectsException.php index b60a9678d..fff05251d 100644 --- a/src/Exception/TooManyRedirectsException.php +++ b/src/Exception/TooManyRedirectsException.php @@ -1,4 +1,6 @@ extractCookies($request, $response); return $response; } - ); + ); }; }; } diff --git a/src/functions.php b/src/functions.php index 3c472bc6a..51d736d88 100644 --- a/src/functions.php +++ b/src/functions.php @@ -196,7 +196,8 @@ function default_ca_bundle() } } - throw new \RuntimeException(<<< EOT + throw new \RuntimeException( + <<< EOT No system CA bundle could be found in any of the the common system locations. PHP versions earlier than 5.6 are not properly configured to use the system's CA bundle by default. In order to verify peer certificates, you will need to From d55dab8d2ff269348e91634036db24547c9d1560 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Fri, 18 Oct 2019 13:32:11 +0200 Subject: [PATCH 075/141] Updated the ClientInterface::VERSION (#2376) --- src/ClientInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 2dbcffa49..cd4b73b8d 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -12,7 +12,7 @@ */ interface ClientInterface { - const VERSION = '6.3.3'; + const VERSION = '6.4.0'; /** * Send an HTTP request. From 2b1dfedd8d59a521832c0837be045b83cd746fa0 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Fri, 18 Oct 2019 14:00:04 +0200 Subject: [PATCH 076/141] Link Multipartstream in PSR-7 docs (#2305) --- docs/psr7.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/psr7.rst b/docs/psr7.rst index 10ba01c6e..3766aaa85 100644 --- a/docs/psr7.rst +++ b/docs/psr7.rst @@ -451,5 +451,6 @@ functionality. - `InflateStream `_ - `LazyOpenStream `_ - `LimitStream `_ +- `MultipartStream `_ - `NoSeekStream `_ - `PumpStream `_ From d22913fae7df66acf26c93b10c13d0030b58f490 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Sun, 20 Oct 2019 08:27:22 +0200 Subject: [PATCH 077/141] Updated date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8cb2a201..5dde12074 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## 6.4.0 - 2018-10-18 +## 6.4.0 - 2018-10-23 * Improvement: Improved error messages when using cUrl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) * Fix: Test if response is readable before returing a summery in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) From 49c26d821a750a40f534e32de59d533b5be7e4c9 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 16:10:54 +0200 Subject: [PATCH 078/141] Fixed typos --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dde12074..debd1ffd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,13 @@ ## 6.4.0 - 2018-10-23 -* Improvement: Improved error messages when using cUrl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) -* Fix: Test if response is readable before returing a summery in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) +* Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) +* Fix: Test if response is readable before returning a summary in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) * Fix: Add support for GUZZLE_CURL_SELECT_TIMEOUT environment variable [#2161](https://github.com/guzzle/guzzle/pull/2161) * Improvement: Added `GuzzleHttp\Exception\InvalidArgumentException` [#2163](https://github.com/guzzle/guzzle/pull/2163) * Improvement: Added `GuzzleHttp\_current_time()` to use `hrtime()` if that function exists. [#2242](https://github.com/guzzle/guzzle/pull/2242) -* Improvement: Added cUrl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284) -* Improvement: Make GuzzleException extend Throwable whereever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273) +* Improvement: Added curl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284) +* Improvement: Make GuzzleException extend Throwable wherever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273) * Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335) * Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362) From 6f4024e875ce5ebe20820ed39324a941b6f690f4 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 17:28:20 +0200 Subject: [PATCH 079/141] fixed year --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index debd1ffd8..15c39ecf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## 6.4.0 - 2018-10-23 +## 6.4.0 - 2019-10-23 * Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) * Fix: Test if response is readable before returning a summary in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) From 53f39bbfbeac90791d38d2889c8e44a40b9e833b Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 17:46:03 +0200 Subject: [PATCH 080/141] Make sure we dont use Psr\Log\LogLevel since we dont require it in composer. --- src/Middleware.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Middleware.php b/src/Middleware.php index 07364755f..8d6ead992 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -1,13 +1,13 @@ withCookieHeader($request); @@ -73,15 +73,15 @@ function (ResponseInterface $response) use ($request) { /** * Middleware that pushes history data to an ArrayAccess container. * - * @param array|\ArrayAccess $container Container to hold the history (by reference). + * @param array|ArrayAccess $container Container to hold the history (by reference). * * @return callable Returns a function that accepts the next handler. - * @throws \InvalidArgumentException if container is not an array or ArrayAccess. + * @throws InvalidArgumentException if container is not an array or ArrayAccess. */ public static function history(&$container) { - if (!is_array($container) && !$container instanceof \ArrayAccess) { - throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); + if (!is_array($container) && !$container instanceof ArrayAccess) { + throw new InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); } return function (callable $handler) use (&$container) { @@ -103,7 +103,7 @@ function ($reason) use ($request, &$container, $options) { 'error' => $reason, 'options' => $options ]; - return \GuzzleHttp\Promise\rejection_for($reason); + return rejection_for($reason); } ); }; @@ -183,7 +183,7 @@ public static function retry(callable $decider, callable $delay = null) * * @return callable Returns a function that accepts the next handler. */ - public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO) + public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = 'info' /* \Psr\Log\LogLevel::INFO */) { return function (callable $handler) use ($logger, $formatter, $logLevel) { return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) { @@ -199,7 +199,7 @@ function ($reason) use ($logger, $request, $formatter) { : null; $message = $formatter->format($request, $response, $reason); $logger->notice($message); - return \GuzzleHttp\Promise\rejection_for($reason); + return rejection_for($reason); } ); }; From 101bf83fbc72705ebff21486b1d016e583ff916a Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Wed, 23 Oct 2019 17:48:01 +0200 Subject: [PATCH 081/141] Fix API key --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 28b8a0c6a..79d9e32ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ deploy: provider: releases skip_cleanup: true api_key: - secure: UpypqlYgsU68QT/x40YzhHXvzWjFwCNo9d+G8KAdm7U9+blFfcWhV1aMdzugvPMl6woXgvJj7qHq5tAL4v6oswCORhpSBfLgOQVFaica5LiHsvWlAedOhxGmnJqMTwuepjBCxXhs3+I8Kof1n4oUL9gKytXjOVCX/f7XU1HiinU= + secure: mz9H1B4cPH7dW9hTzgHnbh75+HJ6fJZ9S/1nMWFaqgj5C0wDzTqkJ+BbwiCEiqXGh6VGZbM4EmO1/wnZ7B+Hk8zsB1PP+GKVkq8+7a/261o60W3OS4gQpZQ9R68dyEO1EyZBJvL1Lzc03rkt/0WnKiAjg7nsc1j4aLKhWMDQ6x8= file: - build/artifacts/guzzle.phar - build/artifacts/guzzle.zip From ab33dc51704c7a528022329a1e759c339849f1fd Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 17:48:26 +0200 Subject: [PATCH 082/141] cs --- src/Middleware.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Middleware.php b/src/Middleware.php index 8d6ead992..bffc1974b 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -1,13 +1,12 @@ withCookieHeader($request); @@ -73,15 +72,15 @@ function (ResponseInterface $response) use ($request) { /** * Middleware that pushes history data to an ArrayAccess container. * - * @param array|ArrayAccess $container Container to hold the history (by reference). + * @param array|\ArrayAccess $container Container to hold the history (by reference). * * @return callable Returns a function that accepts the next handler. - * @throws InvalidArgumentException if container is not an array or ArrayAccess. + * @throws \InvalidArgumentException if container is not an array or ArrayAccess. */ public static function history(&$container) { - if (!is_array($container) && !$container instanceof ArrayAccess) { - throw new InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); + if (!is_array($container) && !$container instanceof \ArrayAccess) { + throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); } return function (callable $handler) use (&$container) { @@ -103,7 +102,7 @@ function ($reason) use ($request, &$container, $options) { 'error' => $reason, 'options' => $options ]; - return rejection_for($reason); + return \GuzzleHttp\Promise\rejection_for($reason); } ); }; @@ -199,7 +198,7 @@ function ($reason) use ($logger, $request, $formatter) { : null; $message = $formatter->format($request, $response, $reason); $logger->notice($message); - return rejection_for($reason); + return \GuzzleHttp\Promise\rejection_for($reason); } ); }; From ebfbcdacd603099c7badc5e16f795b5127e13fe4 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 17:56:10 +0200 Subject: [PATCH 083/141] Added change log for 6.4.1 --- CHANGELOG.md | 5 +++++ src/ClientInterface.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15c39ecf6..65557498b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 6.4.1 - 2019-10-23 + +* No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that +* Added `parent::__construct()` to `FileCookieJar` and `SessionCookieJar` + ## 6.4.0 - 2019-10-23 * Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index cd4b73b8d..5b3708514 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -12,7 +12,7 @@ */ interface ClientInterface { - const VERSION = '6.4.0'; + const VERSION = '6.4.1'; /** * Send an HTTP request. From 8f10d0ea90c205a70bfceb17ee8563a425cc7621 Mon Sep 17 00:00:00 2001 From: Alexey Shokov Date: Wed, 23 Oct 2019 18:13:30 +0200 Subject: [PATCH 084/141] Custom option for cURL multi handler (#2287) * Custom option for cURL multi handler * Assertion fix --- docs/faq.rst | 17 +++++++++++++++++ src/Handler/CurlMultiHandler.php | 18 ++++++++++++++++-- tests/Handler/CurlMultiHandlerTest.php | 23 +++++++++++++++++++++++ tests/bootstrap.php | 14 ++++++++++++-- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index ee7949bf8..e94b1035b 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -65,6 +65,23 @@ used with a client. ] ]); +If you use asynchronous requests with cURL multi handler and want to tweak it, +additional options can be specified as an associative array in the +**options** key of the ``CurlMultiHandler`` constructor. + +.. code-block:: php + + use \GuzzleHttp\Client; + use \GuzzleHttp\HandlerStack; + use \GuzzleHttp\Handler\CurlMultiHandler; + + $client = new Client(['handler' => HandlerStack::create(new CurlMultiHandler([ + 'options' => [ + CURLMOPT_MAX_TOTAL_CONNECTIONS => 50, + CURLMOPT_MAX_HOST_CONNECTIONS => 5, + ] + ]))]); + How can I add custom stream context options? ============================================ diff --git a/src/Handler/CurlMultiHandler.php b/src/Handler/CurlMultiHandler.php index d8297623c..b73e5c72d 100644 --- a/src/Handler/CurlMultiHandler.php +++ b/src/Handler/CurlMultiHandler.php @@ -1,9 +1,9 @@ selectTimeout = 1; } + + $this->options = isset($options['options']) ? $options['options'] : []; } public function __get($name) { if ($name === '_mh') { - return $this->_mh = curl_multi_init(); + $this->_mh = curl_multi_init(); + + foreach ($this->options as $option => $value) { + // A warning is raised in case of a wrong option. + curl_multi_setopt($this->_mh, $option, $value); + } + + // Further calls to _mh will return the value directly, without entering the + // __get() method at all. + return $this->_mh; } throw new \BadMethodCallException(); diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 03043f5ff..22db0dbca 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -9,6 +9,29 @@ class CurlMultiHandlerTest extends TestCase { + public function setUp() + { + $_SERVER['curl_test'] = true; + unset($_SERVER['_curl_multi']); + } + + public function tearDown() + { + unset($_SERVER['_curl_multi'], $_SERVER['curl_test']); + } + + public function testCanAddCustomCurlOptions() + { + Server::flush(); + Server::enqueue([new Response()]); + $a = new CurlMultiHandler(['options' => [ + CURLMOPT_MAXCONNECTS => 5, + ]]); + $request = new Request('GET', Server::$url); + $a($request, []); + $this->assertEquals(5, $_SERVER['_curl_multi'][CURLMOPT_MAXCONNECTS]); + } + public function testSendsRequest() { Server::enqueue([new Response()]); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1cf17b6df..36fbd62e4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -10,7 +10,7 @@ }); } -// Override curl_setopt_array() to get the last set curl options +// Override curl_setopt_array() and curl_multi_setopt() to get the last set curl options namespace GuzzleHttp\Handler { function curl_setopt_array($handle, array $options) { @@ -19,6 +19,16 @@ function curl_setopt_array($handle, array $options) } else { unset($_SERVER['_curl']); } - \curl_setopt_array($handle, $options); + return \curl_setopt_array($handle, $options); + } + + function curl_multi_setopt($handle, $option, $value) + { + if (!empty($_SERVER['curl_test'])) { + $_SERVER['_curl_multi'][$option] = $value; + } else { + unset($_SERVER['_curl_multi']); + } + return \curl_multi_setopt($handle, $option, $value); } } From 33bee79d0c54b8bac3f20c9ee7c3e521a48d29c1 Mon Sep 17 00:00:00 2001 From: Orian de Wit Date: Wed, 23 Oct 2019 18:13:55 +0200 Subject: [PATCH 085/141] Update Client.php to handle null headers (#2259) * Update Client.php A post with options `['json' => $data, 'headers' => null]` gives a `Undefined index: _conditional` in the `Psr7\_caseless_remove()` call on line 326. When the headers key exists but is null, it seems more logical to set `$defaults['_conditional']` to an empty array than null. * added test --- src/Client.php | 2 +- tests/ClientTest.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 0f43c71f0..7530e1bcc 100644 --- a/src/Client.php +++ b/src/Client.php @@ -225,7 +225,7 @@ private function prepareDefaults(array $options) if (array_key_exists('headers', $options)) { // Allows default headers to be unset. if ($options['headers'] === null) { - $defaults['_conditional'] = null; + $defaults['_conditional'] = []; unset($options['headers']); } elseif (!is_array($options['headers'])) { throw new \InvalidArgumentException('headers must be an array'); diff --git a/tests/ClientTest.php b/tests/ClientTest.php index debcb6c8c..16a661534 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -360,6 +360,20 @@ public function testCanAddJsonDataWithoutOverwritingContentType() $this->assertSame('foo', $last->getHeaderLine('Content-Type')); } + public function testCanAddJsonDataWithNullHeader() + { + $mock = new MockHandler([new Response()]); + $client = new Client(['handler' => $mock]); + $request = new Request('PUT', 'http://foo.com'); + $client->send($request, [ + 'headers' => null, + 'json' => 'a' + ]); + $last = $mock->getLastRequest(); + $this->assertSame('"a"', (string) $mock->getLastRequest()->getBody()); + $this->assertSame('application/json', $last->getHeaderLine('Content-Type')); + } + public function testAuthCanBeTrue() { $mock = new MockHandler([new Response()]); From 6a946467b3afd7512a575fbb5169c9674a87da67 Mon Sep 17 00:00:00 2001 From: Luis Jimenez Date: Wed, 23 Oct 2019 12:14:20 -0400 Subject: [PATCH 086/141] MockHandler - Add support to reset internal queue (#2143) --- docs/testing.rst | 15 ++++++++++++--- src/Handler/MockHandler.php | 5 +++++ tests/Handler/MockHandlerTest.php | 12 ++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/testing.rst b/docs/testing.rst index fd84d2cdb..0598a215d 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -50,10 +50,19 @@ a response or exception by shifting return values off of a queue. echo $client->request('GET', '/')->getStatusCode(); //> 202 + // Reset the queue and queue up a new response + $mock->reset(); + $mock->append(new Response(201)); + + // As the mock was reset, the new response is the 201 CREATED, + // instead of the previously queued RequestException + echo $client->request('GET', '/')->getStatusCode(); + //> 201 + + When no more responses are in the queue and a request is sent, an ``OutOfBoundsException`` is thrown. - History Middleware ================== @@ -71,9 +80,9 @@ history of the requests that were sent by a client. $container = []; $history = Middleware::history($container); - $handlerStack = HandlerStack::create(); + $handlerStack = HandlerStack::create(); // or $handlerStack = HandlerStack::create($mock); if using the Mock handler. - + // Add the history middleware to the handler stack. $handlerStack->push($history); diff --git a/src/Handler/MockHandler.php b/src/Handler/MockHandler.php index d5c449c1d..804b84773 100644 --- a/src/Handler/MockHandler.php +++ b/src/Handler/MockHandler.php @@ -175,6 +175,11 @@ public function count() return count($this->queue); } + public function reset() + { + $this->queue = []; + } + private function invokeStats( RequestInterface $request, array $options, diff --git a/tests/Handler/MockHandlerTest.php b/tests/Handler/MockHandlerTest.php index f050ef299..087a94e47 100644 --- a/tests/Handler/MockHandlerTest.php +++ b/tests/Handler/MockHandlerTest.php @@ -235,4 +235,16 @@ public function testTransferTime() $mock($request, [ 'on_stats' => $onStats, 'transfer_time' => 0.4 ])->wait(false); $this->assertEquals(0.4, $stats->getTransferTime()); } + + public function testResetQueue() + { + $mock = new MockHandler([new Response(200), new Response(204)]); + $this->assertCount(2, $mock); + + $mock->reset(); + $this->assertEmpty($mock); + + $mock->append(new Response(500)); + $this->assertCount(1, $mock); + } } From 11337163c1e96235e917c4d287bcc15b86a492d1 Mon Sep 17 00:00:00 2001 From: Mponos George Date: Wed, 23 Oct 2019 19:14:36 +0300 Subject: [PATCH 087/141] Missing docblocks affecting code (#2223) * Missing docblocks affecting code * Reverted docblocks * Revert instance check --- src/Client.php | 1 + src/Cookie/CookieJar.php | 6 ++++-- src/Cookie/CookieJarInterface.php | 6 +++--- src/Exception/RequestException.php | 4 ++-- src/Handler/MockHandler.php | 2 +- src/HandlerStack.php | 6 +++++- src/RedirectMiddleware.php | 4 ++-- src/TransferStats.php | 12 ++++++------ tests/Handler/MockHandlerTest.php | 3 +++ 9 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/Client.php b/src/Client.php index 7530e1bcc..aa5a89cd4 100644 --- a/src/Client.php +++ b/src/Client.php @@ -271,6 +271,7 @@ private function transfer(RequestInterface $request, array $options) } $request = $this->applyOptions($request, $options); + /** @var HandlerStack $handler */ $handler = $options['handler']; try { diff --git a/src/Cookie/CookieJar.php b/src/Cookie/CookieJar.php index 286264261..38f98ad7c 100644 --- a/src/Cookie/CookieJar.php +++ b/src/Cookie/CookieJar.php @@ -94,8 +94,8 @@ public static function shouldPersist( */ public function getCookieByName($name) { - // don't allow a null name - if ($name === null) { + // don't allow a non string name + if ($name === null || !is_scalar($name)) { return null; } foreach ($this->cookies as $cookie) { @@ -103,6 +103,8 @@ public function getCookieByName($name) return $cookie; } } + + return null; } public function toArray() diff --git a/src/Cookie/CookieJarInterface.php b/src/Cookie/CookieJarInterface.php index 2cf298a86..6ee11885e 100644 --- a/src/Cookie/CookieJarInterface.php +++ b/src/Cookie/CookieJarInterface.php @@ -58,9 +58,9 @@ public function setCookie(SetCookie $cookie); * arguments, then the cookie with the specified name, path and domain is * removed. * - * @param string $domain Clears cookies matching a domain - * @param string $path Clears cookies matching a domain and path - * @param string $name Clears cookies matching a domain, path, and name + * @param string|null $domain Clears cookies matching a domain + * @param string|null $path Clears cookies matching a domain and path + * @param string|null $name Clears cookies matching a domain, path, and name * * @return CookieJarInterface */ diff --git a/src/Exception/RequestException.php b/src/Exception/RequestException.php index f38ca8646..3e8cc3f81 100644 --- a/src/Exception/RequestException.php +++ b/src/Exception/RequestException.php @@ -14,7 +14,7 @@ class RequestException extends TransferException /** @var RequestInterface */ private $request; - /** @var ResponseInterface */ + /** @var ResponseInterface|null */ private $response; /** @var array */ @@ -159,7 +159,7 @@ public static function getResponseBodySummary(ResponseInterface $response) * * @return UriInterface */ - private static function obfuscateUri($uri) + private static function obfuscateUri(UriInterface $uri) { $userInfo = $uri->getUserInfo(); diff --git a/src/Handler/MockHandler.php b/src/Handler/MockHandler.php index 804b84773..5b312bc04 100644 --- a/src/Handler/MockHandler.php +++ b/src/Handler/MockHandler.php @@ -66,7 +66,7 @@ public function __invoke(RequestInterface $request, array $options) throw new \OutOfBoundsException('Mock queue is empty'); } - if (isset($options['delay'])) { + if (isset($options['delay']) && is_numeric($options['delay'])) { usleep($options['delay'] * 1000); } diff --git a/src/HandlerStack.php b/src/HandlerStack.php index f0016861e..6a49cc069 100644 --- a/src/HandlerStack.php +++ b/src/HandlerStack.php @@ -1,7 +1,9 @@ getStatusCode(); if ($statusCode == 303 || - ($statusCode <= 302 && $request->getBody() && !$options['allow_redirects']['strict']) + ($statusCode <= 302 && !$options['allow_redirects']['strict']) ) { $modify['method'] = 'GET'; $modify['body'] = ''; diff --git a/src/TransferStats.php b/src/TransferStats.php index 23a22a336..87fb3c001 100644 --- a/src/TransferStats.php +++ b/src/TransferStats.php @@ -18,11 +18,11 @@ final class TransferStats private $handlerErrorData; /** - * @param RequestInterface $request Request that was sent. - * @param ResponseInterface $response Response received (if any) - * @param float|null $transferTime Total handler transfer time. - * @param mixed $handlerErrorData Handler error data. - * @param array $handlerStats Handler specific stats. + * @param RequestInterface $request Request that was sent. + * @param ResponseInterface|null $response Response received (if any) + * @param float|null $transferTime Total handler transfer time. + * @param mixed $handlerErrorData Handler error data. + * @param array $handlerStats Handler specific stats. */ public function __construct( RequestInterface $request, @@ -93,7 +93,7 @@ public function getEffectiveUri() /** * Get the estimated time the request was being transferred by the handler. * - * @return float Time in seconds. + * @return float|null Time in seconds. */ public function getTransferTime() { diff --git a/tests/Handler/MockHandlerTest.php b/tests/Handler/MockHandlerTest.php index 087a94e47..147e55235 100644 --- a/tests/Handler/MockHandlerTest.php +++ b/tests/Handler/MockHandlerTest.php @@ -196,6 +196,7 @@ public function testInvokesOnStatsFunctionForResponse() $res = new Response(); $mock = new MockHandler([$res]); $request = new Request('GET', 'http://example.com'); + /** @var TransferStats|null $stats */ $stats = null; $onStats = function (TransferStats $s) use (&$stats) { $stats = $s; @@ -212,6 +213,8 @@ public function testInvokesOnStatsFunctionForError() $c = null; $mock = new MockHandler([$e], null, function ($v) use (&$c) { $c = $v; }); $request = new Request('GET', 'http://example.com'); + + /** @var TransferStats|null $stats */ $stats = null; $onStats = function (TransferStats $s) use (&$stats) { $stats = $s; From 7fad7865dc253ed2624fea7932fd913ea6fea6c4 Mon Sep 17 00:00:00 2001 From: Mponos George Date: Wed, 23 Oct 2019 19:21:36 +0300 Subject: [PATCH 088/141] Use get_message_body_summary of PSR7 and require min 1.5 (#2227) * Update RequestException.php * Use get message body summary * Added a message to getResponseBodySummary to apply changes to PSR7 also * Require guzzlehttp/psr7 1.5.2 * Return to static call of getSummary * remove the extra comment --- src/Exception/RequestException.php | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/Exception/RequestException.php b/src/Exception/RequestException.php index 3e8cc3f81..652002e02 100644 --- a/src/Exception/RequestException.php +++ b/src/Exception/RequestException.php @@ -124,32 +124,7 @@ public static function create( */ public static function getResponseBodySummary(ResponseInterface $response) { - $body = $response->getBody(); - - if (!$body->isSeekable() || !$body->isReadable()) { - return null; - } - - $size = $body->getSize(); - - if ($size === 0) { - return null; - } - - $summary = $body->read(120); - $body->rewind(); - - if ($size > 120) { - $summary .= ' (truncated...)'; - } - - // Matches any printable character, including unicode characters: - // letters, marks, numbers, punctuation, spacing, and separators. - if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) { - return null; - } - - return $summary; + return \GuzzleHttp\Psr7\get_message_body_summary($response); } /** From 7e387c10977412148363bfcbf91764912e7fd404 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Wed, 23 Oct 2019 23:15:47 +0300 Subject: [PATCH 089/141] Do not fail on BC break failure (#2383) * Do not fail on BC break failure * Adding BC break * Removing BC break * typos --- .github/workflows/bc.entrypoint | 37 +++++++++++++++++++++++++++++++++ .github/workflows/bc.yml | 2 ++ 2 files changed, 39 insertions(+) create mode 100755 .github/workflows/bc.entrypoint diff --git a/.github/workflows/bc.entrypoint b/.github/workflows/bc.entrypoint new file mode 100755 index 000000000..04436e670 --- /dev/null +++ b/.github/workflows/bc.entrypoint @@ -0,0 +1,37 @@ +#!/bin/sh -l + +# +# This file is a hack to suppress warnings from Roave BC check +# + +composer install + +# Capture output to variable AND print it +exec 4711>&1 +OUTPUT=$(/composer/vendor/bin/roave-backward-compatibility-check 2>&1 | tee /dev/fd/4711) + +# Remove rows we want to suppress +OUTPUT=`echo "$OUTPUT" | sed '/GuzzleHttp\\\ClientInterface::VERSION/'d` +OUTPUT=`echo "$OUTPUT" | sed '/Roave\\\BetterReflection\\\Reflection\\\ReflectionClass "Psr\\\Log\\\LogLevel" could not be found in the located source/'d` + +# Number of rows we found with "[BC]" in them +BC_BREAKS=`echo "$OUTPUT" | grep -o '\[BC\]' | wc -l | awk '{ print $1 }'` + +# The last row of the output is "X backwards-incompatible changes detected". Find X. +STATED_BREAKS=`echo "$OUTPUT" | tail -n 1 | awk -F' ' '{ print $1 }'` + +# If +# We found "[BC]" in the command output after we removed suppressed lines +# OR +# We have suppressed X number of BC breaks. If $STATED_BREAKS is larger than X +# THEN +# exit 1 + +if [ $BC_BREAKS -gt 0 ] || [ $STATED_BREAKS -gt 2 ]; then + echo "EXIT 1" + exit 1 +fi + +# No BC breaks found +echo "EXIT 0" +exit 0 diff --git a/.github/workflows/bc.yml b/.github/workflows/bc.yml index 2d288edfe..a2dbf0ecd 100644 --- a/.github/workflows/bc.yml +++ b/.github/workflows/bc.yml @@ -8,3 +8,5 @@ jobs: - uses: actions/checkout@master - name: Roave BC Check uses: docker://nyholm/roave-bc-check-ga + with: + entrypoint: ./.github/workflows/bc.entrypoint From 31a8b427ea9b5ba7bdffa37bed72c94a38673435 Mon Sep 17 00:00:00 2001 From: Jesse Kramer Date: Sat, 6 Oct 2018 23:01:51 +0200 Subject: [PATCH 090/141] Update PHPDoc --- src/Client.php | 78 ++++++++++++++++++++++++++++++++++- src/MessageFormatter.php | 5 +++ src/Pool.php | 11 +++++ src/PrepareBodyMiddleware.php | 7 ++++ src/RedirectMiddleware.php | 14 +++++++ src/RetryMiddleware.php | 19 +++++++++ src/functions.php | 2 +- 7 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/Client.php b/src/Client.php index aa5a89cd4..8ba0d0e80 100644 --- a/src/Client.php +++ b/src/Client.php @@ -75,7 +75,13 @@ public function __construct(array $config = []) $this->configureDefaults($config); } - public function __call($method, $args) + /** + * PHP Magic method + * @param string $method + * @param array $args + * @return Promise\PromiseInterface + */ + public function __call($method, array $args) { if (count($args) < 1) { throw new \InvalidArgumentException('Magic request methods require a URI and optional options array'); @@ -89,6 +95,15 @@ public function __call($method, $args) : $this->request($method, $uri, $opts); } + /** + * Asynchronously send an HTTP request. + * + * @param RequestInterface $request Request to send + * @param array $options Request options to apply to the given + * request and to the transfer. + * + * @return PromiseInterface + */ public function sendAsync(RequestInterface $request, array $options = []) { // Merge the base URI into the request URI if needed. @@ -100,12 +115,36 @@ public function sendAsync(RequestInterface $request, array $options = []) ); } + /** + * Send an HTTP request. + * + * @param RequestInterface $request Request to send + * @param array $options Request options to apply to the given + * request and to the transfer. + * + * @return ResponseInterface + * @throws GuzzleException + */ public function send(RequestInterface $request, array $options = []) { $options[RequestOptions::SYNCHRONOUS] = true; return $this->sendAsync($request, $options)->wait(); } + /** + * Create and send an asynchronous HTTP request. + * + * Use an absolute path to override the base path of the client, or a + * relative path to append to the base path of the client. The URL can + * contain the query string as well. Use an array to provide a URL + * template and additional variables to use in the URL template expansion. + * + * @param string $method HTTP method + * @param string|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @return PromiseInterface + */ public function requestAsync($method, $uri = '', array $options = []) { $options = $this->prepareDefaults($options); @@ -125,12 +164,37 @@ public function requestAsync($method, $uri = '', array $options = []) return $this->transfer($request, $options); } + /** + * Create and send an HTTP request. + * + * Use an absolute path to override the base path of the client, or a + * relative path to append to the base path of the client. The URL can + * contain the query string as well. + * + * @param string $method HTTP method. + * @param string|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @return ResponseInterface + * @throws GuzzleException + */ public function request($method, $uri = '', array $options = []) { $options[RequestOptions::SYNCHRONOUS] = true; return $this->requestAsync($method, $uri, $options)->wait(); } + /** + * Get a client configuration option. + * + * These options include default request options of the client, a "handler" + * (if utilized by the concrete client), and a "base_uri" if utilized by + * the concrete client. + * + * @param string|null $option The config option to retrieve. + * + * @return mixed + */ public function getConfig($option = null) { return $option === null @@ -138,6 +202,12 @@ public function getConfig($option = null) : (isset($this->config[$option]) ? $this->config[$option] : null); } + /** + * Build URI object. + * @param string|null $uri + * @param array $config + * @return UriInterface + */ private function buildUri($uri, array $config) { // for BC we accept null which would otherwise fail in uri_for @@ -154,6 +224,7 @@ private function buildUri($uri, array $config) * Configures the default options for a client. * * @param array $config + * @return void */ private function configureDefaults(array $config) { @@ -412,6 +483,11 @@ private function applyOptions(RequestInterface $request, array &$options) return $request; } + /** + * Throw Exception with pre-set message. + * @return void + * @throws InvalidArgumentException Invalid body. + */ private function invalidBody() { throw new \InvalidArgumentException('Passing in the "body" request ' diff --git a/src/MessageFormatter.php b/src/MessageFormatter.php index 663ac7391..8401f9936 100644 --- a/src/MessageFormatter.php +++ b/src/MessageFormatter.php @@ -168,6 +168,11 @@ function (array $matches) use ($request, $response, $error, &$cache) { ); } + /** + * Get headers from message as string + * @param MessageInterface $message + * @return string + */ private function headers(MessageInterface $message) { $result = ''; diff --git a/src/Pool.php b/src/Pool.php index 05c854aeb..8c129f933 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -69,6 +69,10 @@ public function __construct( $this->each = new EachPromise($requests(), $config); } + /** + * Get promise + * @return GuzzleHttp\Promise\Promise + */ public function promise() { return $this->each->promise(); @@ -106,6 +110,13 @@ public static function batch( return $res; } + /** + * Execute callback(s) + * @param array $options + * @param string $name + * @param array $results + * @return void + */ private static function cmpCallback(array &$options, $name, array &$results) { if (!isset($options[$name])) { diff --git a/src/PrepareBodyMiddleware.php b/src/PrepareBodyMiddleware.php index 2eb95f9b2..3214b5477 100644 --- a/src/PrepareBodyMiddleware.php +++ b/src/PrepareBodyMiddleware.php @@ -66,6 +66,13 @@ public function __invoke(RequestInterface $request, array $options) return $fn(Psr7\modify_request($request, $modify), $options); } + /** + * Add expect header + * @param RequestInterface $request + * @param array $options + * @param array $modify + * @return void + */ private function addExpectHeader( RequestInterface $request, array $options, diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index 84f6785e6..7de9574c3 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -118,6 +118,13 @@ public function checkRedirect( return $promise; } + /** + * Enable tracking on promise. + * @param PromiseInterface $promise + * @param string $uri + * @param string $statusCode [description] + * @return PromiseInterface + */ private function withTracking(PromiseInterface $promise, $uri, $statusCode) { return $promise->then( @@ -135,6 +142,13 @@ function (ResponseInterface $response) use ($uri, $statusCode) { ); } + /** + * Check for too many redirects + * @param RequestInterface $request + * @param array $options + * @return void + * @throws TooManyRedirectsException Too many redirects. + */ private function guardMax(RequestInterface $request, array &$options) { $current = isset($options['__redirect_count']) diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php index 7d40ecaf8..355cd1057 100644 --- a/src/RetryMiddleware.php +++ b/src/RetryMiddleware.php @@ -74,6 +74,12 @@ public function __invoke(RequestInterface $request, array $options) ); } + /** + * Execute fulfilled closure + * @param RequestInterface $req + * @param array $options + * @return mixed + */ private function onFulfilled(RequestInterface $req, array $options) { return function ($value) use ($req, $options) { @@ -90,6 +96,12 @@ private function onFulfilled(RequestInterface $req, array $options) }; } + /** + * Execute rejected closure + * @param RequestInterface $req + * @param array $options + * @return mixed + */ private function onRejected(RequestInterface $req, array $options) { return function ($reason) use ($req, $options) { @@ -106,6 +118,13 @@ private function onRejected(RequestInterface $req, array $options) }; } + /** + * Retry + * @param RequestInterface $req + * @param array $options + * @param ResponseInterface $response + * @return self + */ private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) { $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); diff --git a/src/functions.php b/src/functions.php index 51d736d88..96dcef942 100644 --- a/src/functions.php +++ b/src/functions.php @@ -60,7 +60,7 @@ function describe_type($input) * format: "Name: Value" * @return array */ -function headers_from_lines($lines) +function headers_from_lines(array $lines) { $headers = []; From f9c53e0f998ee845ee33e8de8a2f270bb3e9c8aa Mon Sep 17 00:00:00 2001 From: Jesse Kramer Date: Mon, 22 Oct 2018 13:22:46 +0200 Subject: [PATCH 091/141] Update BC breaking typehints. --- src/RetryMiddleware.php | 2 +- src/functions.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php index 355cd1057..d1bdf49c2 100644 --- a/src/RetryMiddleware.php +++ b/src/RetryMiddleware.php @@ -100,7 +100,7 @@ private function onFulfilled(RequestInterface $req, array $options) * Execute rejected closure * @param RequestInterface $req * @param array $options - * @return mixed + * @return callable */ private function onRejected(RequestInterface $req, array $options) { diff --git a/src/functions.php b/src/functions.php index 96dcef942..aff69d557 100644 --- a/src/functions.php +++ b/src/functions.php @@ -56,11 +56,11 @@ function describe_type($input) /** * Parses an array of header lines into an associative array of headers. * - * @param array $lines Header lines array of strings in the following + * @param iterable $lines Header lines array of strings in the following * format: "Name: Value" * @return array */ -function headers_from_lines(array $lines) +function headers_from_lines($lines) { $headers = []; From fb6b954530552741125cb007a24f00b0841bb938 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 22:04:32 +0200 Subject: [PATCH 092/141] Removed comments not needed --- src/Client.php | 19 +++++++------------ src/MessageFormatter.php | 2 +- src/Pool.php | 4 +--- src/PrepareBodyMiddleware.php | 4 +--- src/RedirectMiddleware.php | 8 +++----- src/RetryMiddleware.php | 10 ++-------- 6 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/Client.php b/src/Client.php index 8ba0d0e80..3490d6a52 100644 --- a/src/Client.php +++ b/src/Client.php @@ -76,9 +76,8 @@ public function __construct(array $config = []) } /** - * PHP Magic method * @param string $method - * @param array $args + * * @return Promise\PromiseInterface */ public function __call($method, array $args) @@ -98,9 +97,8 @@ public function __call($method, array $args) /** * Asynchronously send an HTTP request. * - * @param RequestInterface $request Request to send * @param array $options Request options to apply to the given - * request and to the transfer. + * request and to the transfer. See \GuzzleHttp\RequestOptions. * * @return PromiseInterface */ @@ -118,9 +116,8 @@ public function sendAsync(RequestInterface $request, array $options = []) /** * Send an HTTP request. * - * @param RequestInterface $request Request to send * @param array $options Request options to apply to the given - * request and to the transfer. + * request and to the transfer. See \GuzzleHttp\RequestOptions. * * @return ResponseInterface * @throws GuzzleException @@ -141,7 +138,7 @@ public function send(RequestInterface $request, array $options = []) * * @param string $method HTTP method * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. + * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. * * @return PromiseInterface */ @@ -173,7 +170,7 @@ public function requestAsync($method, $uri = '', array $options = []) * * @param string $method HTTP method. * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. + * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. * * @return ResponseInterface * @throws GuzzleException @@ -203,9 +200,8 @@ public function getConfig($option = null) } /** - * Build URI object. * @param string|null $uri - * @param array $config + * * @return UriInterface */ private function buildUri($uri, array $config) @@ -322,8 +318,7 @@ private function prepareDefaults(array $options) * The URI of the request is not modified and the request options are used * as-is without merging in default options. * - * @param RequestInterface $request - * @param array $options + * @param array $options See \GuzzleHttp\RequestOptions. * * @return Promise\PromiseInterface */ diff --git a/src/MessageFormatter.php b/src/MessageFormatter.php index 8401f9936..dc36bb524 100644 --- a/src/MessageFormatter.php +++ b/src/MessageFormatter.php @@ -170,7 +170,7 @@ function (array $matches) use ($request, $response, $error, &$cache) { /** * Get headers from message as string - * @param MessageInterface $message + * * @return string */ private function headers(MessageInterface $message) diff --git a/src/Pool.php b/src/Pool.php index 8c129f933..2ff6796c7 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -112,9 +112,7 @@ public static function batch( /** * Execute callback(s) - * @param array $options - * @param string $name - * @param array $results + * * @return void */ private static function cmpCallback(array &$options, $name, array &$results) diff --git a/src/PrepareBodyMiddleware.php b/src/PrepareBodyMiddleware.php index 3214b5477..568a1e906 100644 --- a/src/PrepareBodyMiddleware.php +++ b/src/PrepareBodyMiddleware.php @@ -68,9 +68,7 @@ public function __invoke(RequestInterface $request, array $options) /** * Add expect header - * @param RequestInterface $request - * @param array $options - * @param array $modify + * * @return void */ private function addExpectHeader( diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index 7de9574c3..5a0edd572 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -120,9 +120,7 @@ public function checkRedirect( /** * Enable tracking on promise. - * @param PromiseInterface $promise - * @param string $uri - * @param string $statusCode [description] + * * @return PromiseInterface */ private function withTracking(PromiseInterface $promise, $uri, $statusCode) @@ -144,9 +142,9 @@ function (ResponseInterface $response) use ($uri, $statusCode) { /** * Check for too many redirects - * @param RequestInterface $request - * @param array $options + * * @return void + * * @throws TooManyRedirectsException Too many redirects. */ private function guardMax(RequestInterface $request, array &$options) diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php index d1bdf49c2..c8d72c200 100644 --- a/src/RetryMiddleware.php +++ b/src/RetryMiddleware.php @@ -76,8 +76,7 @@ public function __invoke(RequestInterface $request, array $options) /** * Execute fulfilled closure - * @param RequestInterface $req - * @param array $options + * * @return mixed */ private function onFulfilled(RequestInterface $req, array $options) @@ -98,8 +97,7 @@ private function onFulfilled(RequestInterface $req, array $options) /** * Execute rejected closure - * @param RequestInterface $req - * @param array $options + * * @return callable */ private function onRejected(RequestInterface $req, array $options) @@ -119,10 +117,6 @@ private function onRejected(RequestInterface $req, array $options) } /** - * Retry - * @param RequestInterface $req - * @param array $options - * @param ResponseInterface $response * @return self */ private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) From 2a9a0f007de33cf4251ec3f02683aaae921aea8c Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 22:14:15 +0200 Subject: [PATCH 093/141] PHPStan config --- phpstan.neon.dist | 4 ++++ src/Client.php | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 4ef4192d3..70d5cb32f 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,3 +7,7 @@ parameters: - message: '#Function uri_template not found#' path: %currentWorkingDirectory%/src/functions.php + + + # To be removed when we drop support for PHP5 + - '#Return typehint of method#' diff --git a/src/Client.php b/src/Client.php index 3490d6a52..5048bb406 100644 --- a/src/Client.php +++ b/src/Client.php @@ -76,7 +76,7 @@ public function __construct(array $config = []) } /** - * @param string $method + * @param string $method * * @return Promise\PromiseInterface */ @@ -97,8 +97,8 @@ public function __call($method, array $args) /** * Asynchronously send an HTTP request. * - * @param array $options Request options to apply to the given - * request and to the transfer. See \GuzzleHttp\RequestOptions. + * @param array $options Request options to apply to the given + * request and to the transfer. See \GuzzleHttp\RequestOptions. * * @return PromiseInterface */ @@ -116,8 +116,8 @@ public function sendAsync(RequestInterface $request, array $options = []) /** * Send an HTTP request. * - * @param array $options Request options to apply to the given - * request and to the transfer. See \GuzzleHttp\RequestOptions. + * @param array $options Request options to apply to the given + * request and to the transfer. See \GuzzleHttp\RequestOptions. * * @return ResponseInterface * @throws GuzzleException @@ -318,7 +318,7 @@ private function prepareDefaults(array $options) * The URI of the request is not modified and the request options are used * as-is without merging in default options. * - * @param array $options See \GuzzleHttp\RequestOptions. + * @param array $options See \GuzzleHttp\RequestOptions. * * @return Promise\PromiseInterface */ From 74923670dd2ceb476215dd2b8aec7242d8ecbc67 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 23 Oct 2019 22:27:38 +0200 Subject: [PATCH 094/141] Reverted BC break --- src/Client.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 5048bb406..7f80efcf0 100644 --- a/src/Client.php +++ b/src/Client.php @@ -77,10 +77,11 @@ public function __construct(array $config = []) /** * @param string $method + * @param array $args * * @return Promise\PromiseInterface */ - public function __call($method, array $args) + public function __call($method, $args) { if (count($args) < 1) { throw new \InvalidArgumentException('Magic request methods require a URI and optional options array'); From ac157c57f6f18bc6bd4d1e48ef080fc75e6b0a5c Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Thu, 24 Oct 2019 13:37:04 +0100 Subject: [PATCH 095/141] [CurlFactory] Prevent undefined offset when using array for ssl_key options (#2348) * Test & changes to CurlFactory * Code style and cleanup * Restore import order * Bugfix --- src/Handler/CurlFactory.php | 13 +++++++++---- tests/Handler/CurlFactoryTest.php | 8 ++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index e349bb4c4..66c952c04 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -454,11 +454,16 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf) } if (isset($options['ssl_key'])) { - $sslKey = $options['ssl_key']; - if (is_array($sslKey)) { - $conf[CURLOPT_SSLKEYPASSWD] = $sslKey[1]; - $sslKey = $sslKey[0]; + if (is_array($options['ssl_key'])) { + if (count($options['ssl_key']) === 2) { + list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key']; + } else { + list($sslKey) = $options['ssl_key']; + } } + + $sslKey = isset($sslKey) ? $sslKey: $options['ssl_key']; + if (!file_exists($sslKey)) { throw new \InvalidArgumentException( "SSL private key not found: {$sslKey}" diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index d1e4e9980..3f9456ad1 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -216,6 +216,14 @@ public function testAddsSslKeyWithPassword() $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLKEYPASSWD]); } + public function testAddsSslKeyWhenUsingArraySyntaxButNoPassword() + { + $f = new Handler\CurlFactory(3); + $f->create(new Psr7\Request('GET', Server::$url), ['ssl_key' => [__FILE__]]); + + $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); + } + /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage SSL certificate not found: /does/not/exist From 4ef5723c06c2fa7b3f07ea91c7e218925700c47a Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Thu, 24 Oct 2019 15:37:59 +0300 Subject: [PATCH 096/141] Deprecate ClientInterface::VERSION (#2382) --- src/ClientInterface.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 5b3708514..764ef3699 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -12,6 +12,9 @@ */ interface ClientInterface { + /** + * @deprecated Will be removed in Guzzle 7.0.0 + */ const VERSION = '6.4.1'; /** From 708835738383a3cc09ba00c77d43732940ba1380 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Thu, 24 Oct 2019 15:55:19 +0300 Subject: [PATCH 097/141] Use PHPStan baseline (#2387) * Use PHPStan baseline * Use max level * added more errors --- phpstan-baseline.neon | 230 ++++++++++++++++++++++++++++++++++++++++++ phpstan.neon.dist | 14 +-- 2 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 phpstan-baseline.neon diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 000000000..0a82f4bea --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,230 @@ + + +parameters: + ignoreErrors: + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:__call\\(\\) should return GuzzleHttp\\\\Promise\\\\PromiseInterface but returns GuzzleHttp\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Return typehint of method GuzzleHttp\\\\Client\\:\\:sendAsync\\(\\) has invalid type GuzzleHttp\\\\PromiseInterface\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:sendAsync\\(\\) should return GuzzleHttp\\\\PromiseInterface but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^PHPDoc tag @throws with type GuzzleHttp\\\\GuzzleException is not subtype of Throwable$#" + count: 2 + path: src/Client.php + + - + message: "#^Call to method wait\\(\\) on an unknown class GuzzleHttp\\\\PromiseInterface\\.$#" + count: 2 + path: src/Client.php + + - + message: "#^Return typehint of method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) has invalid type GuzzleHttp\\\\PromiseInterface\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) should return GuzzleHttp\\\\PromiseInterface but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Parameter \\#1 \\$str of function strtolower expects string, int\\|string given\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Parameter \\#2 \\$prefix of function http_build_query expects string, null given\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^PHPDoc tag @throws with type GuzzleHttp\\\\InvalidArgumentException is not subtype of Throwable$#" + count: 1 + path: src/Client.php + + - + message: "#^Result of \\|\\| is always false\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#" + count: 2 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:clear\\(\\) should return GuzzleHttp\\\\Cookie\\\\CookieJarInterface but empty return statement found\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Parameter \\#3 \\$length of function substr expects int, int\\|false given\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Property GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:\\$data \\(array\\) does not accept array\\|null\\.$#" + count: 1 + path: src/Cookie/SetCookie.php + + - + message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" + count: 1 + path: src/Cookie/SetCookie.php + + - + message: "#^Parameter \\#1 \\$str of function ltrim expects string, string\\|null given\\.$#" + count: 1 + path: src/Cookie/SetCookie.php + + - + message: "#^Negated boolean expression is always false\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^If condition is always true\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Parameter \\#1 \\$str1 of function strcasecmp expects string, int\\|string given\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$_mh \\(resource\\) does not accept resource\\|false\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Parameter \\#1 \\$mh of function curl_multi_setopt expects resource, resource\\|false given\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Parameter \\#1 \\$status of class GuzzleHttp\\\\Psr7\\\\Response constructor expects int, string given\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Parameter \\#2 \\$parameters of function call_user_func_array expects array\\, array given\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Binary operation \"\\*\" between float\\|int\\|string and 1000 results in an error\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Parameter \\#1 \\$status of class GuzzleHttp\\\\Psr7\\\\Response constructor expects int, string given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Argument of an invalid type array\\\\>\\|null supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#3 \\$use_include_path of function fopen expects bool, null given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#1 \\$stream of function stream_set_timeout expects resource, resource\\|false given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#3 \\$microseconds of function stream_set_timeout expects int, float\\|int given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#1 \\$obj of function spl_object_hash expects object, callable given\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\MessageFormatter\\:\\:format\\(\\) should return string but returns string\\|null\\.$#" + count: 1 + path: src/MessageFormatter.php + + - + message: "#^Result of && is always false\\.$#" + count: 1 + path: src/Middleware.php + + - + message: "#^Return typehint of method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) has invalid type GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) should return GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Call to method wait\\(\\) on an unknown class GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Parameter \\#1 \\$str of function substr expects string, int given\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Parameter \\#1 \\$promise of method GuzzleHttp\\\\RedirectMiddleware\\:\\:withTracking\\(\\) expects GuzzleHttp\\\\Promise\\\\PromiseInterface, GuzzleHttp\\\\Promise\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface given\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Parameter \\#2 \\$value of method Psr\\\\Http\\\\Message\\\\MessageInterface\\:\\:withHeader\\(\\) expects array\\\\|string, array given\\.$#" + count: 2 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:doRetry\\(\\) should return GuzzleHttp\\\\RetryMiddleware but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + count: 1 + path: src/RetryMiddleware.php + + - + message: "#^Function uri_template not found\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Parameter \\#1 \\$str of function rtrim expects string, string\\|false given\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\debug_resource\\(\\) should return resource but returns resource\\|false\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Parameter \\#1 \\$str of function substr expects string, string\\|null given\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\json_encode\\(\\) should return string but returns string\\|false\\.$#" + count: 1 + path: src/functions.php + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 70d5cb32f..2d83c9846 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,13 +1,7 @@ +includes: + - phpstan-baseline.neon + parameters: - level: 1 + level: max paths: - src - - ignoreErrors: - - - message: '#Function uri_template not found#' - path: %currentWorkingDirectory%/src/functions.php - - - # To be removed when we drop support for PHP5 - - '#Return typehint of method#' From 9d6e08028560c6a2f57d360e2c57e9d9c776165b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Sun, 27 Oct 2019 09:43:59 +0100 Subject: [PATCH 098/141] Change docs to match code (#2391) --- docs/handlers-and-middleware.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/handlers-and-middleware.rst b/docs/handlers-and-middleware.rst index 5c3b0bfc8..be81063c9 100644 --- a/docs/handlers-and-middleware.rst +++ b/docs/handlers-and-middleware.rst @@ -50,7 +50,7 @@ The ``create`` method adds default handlers to the ``HandlerStack``. When the 2. ``cookies`` - extracts response cookies into the cookie jar. 3. ``allow_redirects`` - Follows redirects. 4. ``http_errors`` - throws exceptions when the response status code ``>=`` - 300. + 400. When provided no ``$handler`` argument, ``GuzzleHttp\HandlerStack::create()`` will choose the most appropriate handler based on the extensions available on From cf2be08d0f08b0bbe4d9ab3f56a15194540eb02b Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 30 Oct 2019 09:27:27 +0000 Subject: [PATCH 099/141] Fixed branch alias (#2392) * Fixed branch alias * Bumped again --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c55325753..28f84b003 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ }, "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { From 4d71358b8f054dcb853a3ebe7cd2be08e9a0d451 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Wed, 30 Oct 2019 11:58:00 +0200 Subject: [PATCH 100/141] EOL version 5.3 (#2388) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a5ef18aee..5fdb6c5f4 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ composer update |---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------| | 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >= 5.3.3 | | 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >= 5.4 | -| 5.x | Maintained | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >= 5.4 | +| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >= 5.4 | | 6.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >= 5.5 | [guzzle-3-repo]: https://github.com/guzzle/guzzle3 From 411b0764b8e24ea872579316e656f9311d6846a0 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Wed, 30 Oct 2019 12:56:22 +0200 Subject: [PATCH 101/141] Fixed CS in tests (#2385) --- .php_cs | 3 +- src/Client.php | 2 +- src/ClientInterface.php | 2 +- src/Exception/RequestException.php | 2 +- src/Handler/CurlFactory.php | 2 +- src/Handler/StreamHandler.php | 2 +- src/Pool.php | 2 +- tests/ClientTest.php | 5 +- tests/Cookie/CookieJarTest.php | 66 +++---- tests/Cookie/FileCookieJarTest.php | 8 +- tests/Cookie/SessionCookieJarTest.php | 10 +- tests/Cookie/SetCookieTest.php | 144 +++++++-------- tests/Handler/CurlFactoryTest.php | 17 +- tests/Handler/CurlMultiHandlerTest.php | 2 +- tests/Handler/MockHandlerTest.php | 18 +- tests/Handler/ProxyTest.php | 32 +++- tests/Handler/StreamHandlerTest.php | 8 +- tests/HandlerStackTest.php | 20 ++- tests/MessageFormatterTest.php | 4 +- tests/MiddlewareTest.php | 2 +- tests/PoolTest.php | 38 ++-- tests/PrepareBodyMiddlewareTest.php | 6 +- tests/RedirectMiddlewareTest.php | 2 +- tests/RetryMiddlewareTest.php | 4 +- tests/TransferStatsTest.php | 2 +- tests/UriTemplateTest.php | 240 ++++++++++++------------- 26 files changed, 352 insertions(+), 291 deletions(-) diff --git a/.php_cs b/.php_cs index a8ace8aab..9d37edf9c 100644 --- a/.php_cs +++ b/.php_cs @@ -7,13 +7,14 @@ $config = PhpCsFixer\Config::create() 'array_syntax' => ['syntax' => 'short'], 'declare_strict_types' => false, 'concat_space' => ['spacing'=>'one'], - // 'ordered_imports' => true, + 'ordered_imports' => true, // 'phpdoc_align' => ['align'=>'vertical'], // 'native_function_invocation' => true, ]) ->setFinder( PhpCsFixer\Finder::create() ->in(__DIR__.'/src') + ->in(__DIR__.'/tests') ->name('*.php') ) ; diff --git a/src/Client.php b/src/Client.php index 7f80efcf0..57a0a75fc 100644 --- a/src/Client.php +++ b/src/Client.php @@ -4,9 +4,9 @@ use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Promise; use GuzzleHttp\Psr7; -use Psr\Http\Message\UriInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UriInterface; /** * @method ResponseInterface get(string|UriInterface $uri, array $options = []) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 764ef3699..24f566bb5 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -1,8 +1,8 @@ function () {}]); + $client = new Client(['handler' => function () { + }]); $client->post('http://foo.com', [ 'form_params' => ['foo' => 'bar bam'], 'multipart' => [] diff --git a/tests/Cookie/CookieJarTest.php b/tests/Cookie/CookieJarTest.php index f0fad497d..008ae1cef 100644 --- a/tests/Cookie/CookieJarTest.php +++ b/tests/Cookie/CookieJarTest.php @@ -128,58 +128,58 @@ public function testRemovesSelectively() public function testDoesNotAddIncompleteCookies() { $this->assertFalse($this->jar->setCookie(new SetCookie())); - $this->assertFalse($this->jar->setCookie(new SetCookie(array( + $this->assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => 'foo' - )))); - $this->assertFalse($this->jar->setCookie(new SetCookie(array( + ]))); + $this->assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => false - )))); - $this->assertFalse($this->jar->setCookie(new SetCookie(array( + ]))); + $this->assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => true - )))); - $this->assertFalse($this->jar->setCookie(new SetCookie(array( + ]))); + $this->assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com' - )))); + ]))); } public function testDoesNotAddEmptyCookies() { - $this->assertFalse($this->jar->setCookie(new SetCookie(array( + $this->assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => '', 'Domain' => 'foo.com', 'Value' => 0 - )))); + ]))); } public function testDoesAddValidCookies() { - $this->assertTrue($this->jar->setCookie(new SetCookie(array( + $this->assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => '0', 'Domain' => 'foo.com', 'Value' => 0 - )))); - $this->assertTrue($this->jar->setCookie(new SetCookie(array( + ]))); + $this->assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com', 'Value' => 0 - )))); - $this->assertTrue($this->jar->setCookie(new SetCookie(array( + ]))); + $this->assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com', 'Value' => 0.0 - )))); - $this->assertTrue($this->jar->setCookie(new SetCookie(array( + ]))); + $this->assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com', 'Value' => '0' - )))); + ]))); } public function testOverwritesCookiesThatAreOlderOrDiscardable() { $t = time() + 1000; - $data = array( + $data = [ 'Name' => 'foo', 'Value' => 'bar', 'Domain' => '.example.com', @@ -188,7 +188,7 @@ public function testOverwritesCookiesThatAreOlderOrDiscardable() 'Secure' => true, 'Discard' => true, 'Expires' => $t - ); + ]; // Make sure that the discard cookie is overridden with the non-discard $this->assertTrue($this->jar->setCookie(new SetCookie($data))); @@ -216,7 +216,7 @@ public function testOverwritesCookiesThatAreOlderOrDiscardable() public function testOverwritesCookiesThatHaveChanged() { $t = time() + 1000; - $data = array( + $data = [ 'Name' => 'foo', 'Value' => 'bar', 'Domain' => '.example.com', @@ -225,7 +225,7 @@ public function testOverwritesCookiesThatHaveChanged() 'Secure' => true, 'Discard' => true, 'Expires' => $t - ); + ]; // Make sure that the discard cookie is overridden with the non-discard $this->assertTrue($this->jar->setCookie(new SetCookie($data))); @@ -246,9 +246,9 @@ public function testOverwritesCookiesThatHaveChanged() public function testAddsCookiesFromResponseWithRequest() { - $response = new Response(200, array( + $response = new Response(200, [ 'Set-Cookie' => "fpc=d=.Hm.yh4.1XmJWjJfs4orLQzKzPImxklQoxXSHOZATHUSEFciRueW_7704iYUtsXNEXq0M92Px2glMdWypmJ7HIQl6XIUvrZimWjQ3vIdeuRbI.FNQMAfcxu_XN1zSx7l.AcPdKL6guHc2V7hIQFhnjRW0rxm2oHY1P4bGQxFNz7f.tHm12ZD3DbdMDiDy7TBXsuP4DM-&v=2; expires=Fri, 02-Mar-2019 02:17:40 GMT;" - )); + ]); $request = new Request('GET', 'http://www.example.com'); $this->jar->extractCookies($request, $response); $this->assertCount(1, $this->jar); @@ -256,13 +256,13 @@ public function testAddsCookiesFromResponseWithRequest() public function getMatchingCookiesDataProvider() { - return array( - array('https://example.com', 'foo=bar; baz=foobar'), - array('http://example.com', ''), - array('https://example.com:8912', 'foo=bar; baz=foobar'), - array('https://foo.example.com', 'foo=bar; baz=foobar'), - array('http://foo.example.com/test/acme/', 'googoo=gaga') - ); + return [ + ['https://example.com', 'foo=bar; baz=foobar'], + ['http://example.com', ''], + ['https://example.com:8912', 'foo=bar; baz=foobar'], + ['https://foo.example.com', 'foo=bar; baz=foobar'], + ['http://foo.example.com/test/acme/', 'googoo=gaga'] + ]; } /** @@ -368,9 +368,9 @@ public function testCanConvertToAndLoadFromArray() public function testAddsCookiesWithEmptyPathFromResponse() { - $response = new Response(200, array( + $response = new Response(200, [ 'Set-Cookie' => "fpc=foobar; expires={$this->futureExpirationDate()}; path=;" - )); + ]); $request = new Request('GET', 'http://www.example.com'); $this->jar->extractCookies($request, $response); $newRequest = $this->jar->withCookieHeader(new Request('GET', 'http://www.example.com/foo')); diff --git a/tests/Cookie/FileCookieJarTest.php b/tests/Cookie/FileCookieJarTest.php index 0fcf0ab3c..4a91c9ab5 100644 --- a/tests/Cookie/FileCookieJarTest.php +++ b/tests/Cookie/FileCookieJarTest.php @@ -80,9 +80,9 @@ public function testPersistsToFile($testSaveSessionCookie = false) public function providerPersistsToFileFileParameters() { - return array( - array(false), - array(true) - ); + return [ + [false], + [true] + ]; } } diff --git a/tests/Cookie/SessionCookieJarTest.php b/tests/Cookie/SessionCookieJarTest.php index 77c3816cf..ea855ba7d 100644 --- a/tests/Cookie/SessionCookieJarTest.php +++ b/tests/Cookie/SessionCookieJarTest.php @@ -17,7 +17,7 @@ public function setUp() $this->sessionVar = 'sessionKey'; if (!isset($_SESSION)) { - $_SESSION = array(); + $_SESSION = []; } } @@ -84,9 +84,9 @@ public function testPersistsToSession($testSaveSessionCookie = false) public function providerPersistsToSessionParameters() { - return array( - array(false), - array(true) - ); + return [ + [false], + [true] + ]; } } diff --git a/tests/Cookie/SetCookieTest.php b/tests/Cookie/SetCookieTest.php index 973de554a..29c837f7d 100644 --- a/tests/Cookie/SetCookieTest.php +++ b/tests/Cookie/SetCookieTest.php @@ -31,7 +31,7 @@ public function testAddsExpiresBasedOnMaxAge() public function testHoldsValues() { $t = time(); - $data = array( + $data = [ 'Name' => 'foo', 'Value' => 'baz', 'Path' => '/bar', @@ -43,7 +43,7 @@ public function testHoldsValues() 'HttpOnly' => true, 'foo' => 'baz', 'bar' => 'bam' - ); + ]; $cookie = new SetCookie($data); $this->assertEquals($data, $cookie->toArray()); @@ -154,15 +154,15 @@ public function testMatchesPath($cookiePath, $requestPath, $isMatch) public function cookieValidateProvider() { - return array( - array('foo', 'baz', 'bar', true), - array('0', '0', '0', true), - array('foo[bar]', 'baz', 'bar', true), - array('', 'baz', 'bar', 'The cookie name must not be empty'), - array('foo', '', 'bar', 'The cookie value must not be empty'), - array('foo', 'baz', '', 'The cookie domain must not be empty'), - array("foo\r", 'baz', '0', 'Cookie name must not contain invalid characters: ASCII Control characters (0-31;127), space, tab and the following characters: ()<>@,;:\"/?={}'), - ); + return [ + ['foo', 'baz', 'bar', true], + ['0', '0', '0', true], + ['foo[bar]', 'baz', 'bar', true], + ['', 'baz', 'bar', 'The cookie name must not be empty'], + ['foo', '', 'bar', 'The cookie value must not be empty'], + ['foo', 'baz', '', 'The cookie domain must not be empty'], + ["foo\r", 'baz', '0', 'Cookie name must not contain invalid characters: ASCII Control characters (0-31;127), space, tab and the following characters: ()<>@,;:\"/?={}'], + ]; } /** @@ -170,11 +170,11 @@ public function cookieValidateProvider() */ public function testValidatesCookies($name, $value, $domain, $result) { - $cookie = new SetCookie(array( + $cookie = new SetCookie([ 'Name' => $name, 'Value' => $value, 'Domain' => $domain - )); + ]); $this->assertSame($result, $cookie->validate()); } @@ -209,10 +209,10 @@ public function testConvertsToString() */ public function cookieParserDataProvider() { - return array( - array( + return [ + [ 'ASIHTTPRequestTestCookie=This+is+the+value; expires=Sat, 26-Jul-2008 17:00:42 GMT; path=/tests; domain=allseeing-i.com; PHPSESSID=6c951590e7a9359bcedde25cda73e43c; path=/;', - array( + [ 'Domain' => 'allseeing-i.com', 'Path' => '/', 'PHPSESSID' => '6c951590e7a9359bcedde25cda73e43c', @@ -223,12 +223,12 @@ public function cookieParserDataProvider() 'Name' => 'ASIHTTPRequestTestCookie', 'Value' => 'This+is+the+value', 'HttpOnly' => false - ) - ), - array('', []), - array('foo', []), - array('; foo', []), - array( + ] + ], + ['', []], + ['foo', []], + ['; foo', []], + [ 'foo="bar"', [ 'Name' => 'foo', @@ -241,11 +241,11 @@ public function cookieParserDataProvider() 'Secure' => null, 'HttpOnly' => false ] - ), + ], // Test setting a blank value for a cookie - array(array( - 'foo=', 'foo =', 'foo =;', 'foo= ;', 'foo =', 'foo= '), - array( + [[ + 'foo=', 'foo =', 'foo =;', 'foo= ;', 'foo =', 'foo= '], + [ 'Name' => 'foo', 'Value' => '', 'Discard' => null, @@ -255,12 +255,12 @@ public function cookieParserDataProvider() 'Path' => '/', 'Secure' => null, 'HttpOnly' => false - ) - ), + ] + ], // Test setting a value and removing quotes - array(array( - 'foo=1', 'foo =1', 'foo =1;', 'foo=1 ;', 'foo =1', 'foo= 1', 'foo = 1 ;'), - array( + [[ + 'foo=1', 'foo =1', 'foo =1;', 'foo=1 ;', 'foo =1', 'foo= 1', 'foo = 1 ;'], + [ 'Name' => 'foo', 'Value' => '1', 'Discard' => null, @@ -270,12 +270,12 @@ public function cookieParserDataProvider() 'Path' => '/', 'Secure' => null, 'HttpOnly' => false - ) - ), + ] + ], // Some of the following tests are based on http://framework.zend.com/svn/framework/standard/trunk/tests/Zend/Http/CookieTest.php - array( + [ 'justacookie=foo; domain=example.com', - array( + [ 'Name' => 'justacookie', 'Value' => 'foo', 'Domain' => 'example.com', @@ -285,11 +285,11 @@ public function cookieParserDataProvider() 'Path' => '/', 'Secure' => null, 'HttpOnly' => false - ) - ), - array( + ] + ], + [ 'expires=tomorrow; secure; path=/Space Out/; expires=Tue, 21-Nov-2006 08:33:44 GMT; domain=.example.com', - array( + [ 'Name' => 'expires', 'Value' => 'tomorrow', 'Domain' => '.example.com', @@ -299,11 +299,11 @@ public function cookieParserDataProvider() 'Secure' => true, 'Max-Age' => null, 'HttpOnly' => false - ) - ), - array( + ] + ], + [ 'domain=unittests; expires=Tue, 21-Nov-2006 08:33:44 GMT; domain=example.com; path=/some value/', - array( + [ 'Name' => 'domain', 'Value' => 'unittests', 'Domain' => 'example.com', @@ -313,11 +313,11 @@ public function cookieParserDataProvider() 'Discard' => null, 'Max-Age' => null, 'HttpOnly' => false - ) - ), - array( + ] + ], + [ 'path=indexAction; path=/; domain=.foo.com; expires=Tue, 21-Nov-2006 08:33:44 GMT', - array( + [ 'Name' => 'path', 'Value' => 'indexAction', 'Domain' => '.foo.com', @@ -327,11 +327,11 @@ public function cookieParserDataProvider() 'Discard' => null, 'Max-Age' => null, 'HttpOnly' => false - ) - ), - array( + ] + ], + [ 'secure=sha1; secure; SECURE; domain=some.really.deep.domain.com; version=1; Max-Age=86400', - array( + [ 'Name' => 'secure', 'Value' => 'sha1', 'Domain' => 'some.really.deep.domain.com', @@ -342,11 +342,11 @@ public function cookieParserDataProvider() 'Max-Age' => 86400, 'HttpOnly' => false, 'version' => '1' - ) - ), - array( + ] + ], + [ 'PHPSESSID=123456789+abcd%2Cef; secure; discard; domain=.localdomain; path=/foo/baz; expires=Tue, 21-Nov-2006 08:33:44 GMT;', - array( + [ 'Name' => 'PHPSESSID', 'Value' => '123456789+abcd%2Cef', 'Domain' => '.localdomain', @@ -356,9 +356,9 @@ public function cookieParserDataProvider() 'Discard' => true, 'Max-Age' => null, 'HttpOnly' => false - ) - ), - ); + ] + ], + ]; } /** @@ -408,28 +408,28 @@ public function testParseCookie($cookie, $parsed) */ public function isExpiredProvider() { - return array( - array( + return [ + [ 'FOO=bar; expires=Thu, 01 Jan 1970 00:00:00 GMT;', true, - ), - array( + ], + [ 'FOO=bar; expires=Thu, 01 Jan 1970 00:00:01 GMT;', true, - ), - array( - 'FOO=bar; expires='.date(\DateTime::RFC1123, time()+10).';', + ], + [ + 'FOO=bar; expires=' . date(\DateTime::RFC1123, time()+10) . ';', false, - ), - array( - 'FOO=bar; expires='.date(\DateTime::RFC1123, time()-10).';', + ], + [ + 'FOO=bar; expires=' . date(\DateTime::RFC1123, time()-10) . ';', true, - ), - array( + ], + [ 'FOO=bar;', false, - ), - ); + ], + ]; } /** diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index 3f9456ad1..845e7c236 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -1,14 +1,14 @@ function () { return 1; }, - 'rewind' => function () use (&$called) { $called = true; } + 'tell' => function () { + return 1; + }, + 'rewind' => function () use (&$called) { + $called = true; + } ]); $factory = new Handler\CurlFactory(1); @@ -539,7 +543,8 @@ public function testCreatesConnectException() $easy->errno = CURLE_COULDNT_CONNECT; $response = $m->invoke( null, - function () {}, + function () { + }, $easy, $factory ); diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 22db0dbca..4a9387633 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -70,7 +70,7 @@ public function testCanCancel() $responses[] = $response; } - foreach($responses as $r) { + foreach ($responses as $r) { $this->assertSame('rejected', $response->getState()); } } diff --git a/tests/Handler/MockHandlerTest.php b/tests/Handler/MockHandlerTest.php index 147e55235..6b3ebe3f4 100644 --- a/tests/Handler/MockHandlerTest.php +++ b/tests/Handler/MockHandlerTest.php @@ -70,7 +70,7 @@ public function testCanGetLastRequestAndOptions() public function testSinkFilename() { - $filename = sys_get_temp_dir().'/mock_test_'.uniqid(); + $filename = sys_get_temp_dir() . '/mock_test_' . uniqid(); $res = new Response(200, [], 'TEST CONTENT'); $mock = new MockHandler([$res]); $request = new Request('GET', '/'); @@ -113,7 +113,9 @@ public function testSinkStream() public function testCanEnqueueCallables() { $r = new Response(); - $fn = function ($req, $o) use ($r) { return $r; }; + $fn = function ($req, $o) use ($r) { + return $r; + }; $mock = new MockHandler([$fn]); $request = new Request('GET', 'http://example.com'); $p = $mock($request, ['foo' => 'bar']); @@ -164,7 +166,9 @@ public function testInvokesOnRejected() { $e = new \Exception('a'); $c = null; - $mock = new MockHandler([$e], null, function ($v) use (&$c) { $c = $v; }); + $mock = new MockHandler([$e], null, function ($v) use (&$c) { + $c = $v; + }); $request = new Request('GET', 'http://example.com'); $mock($request, [])->wait(false); $this->assertSame($e, $c); @@ -211,7 +215,9 @@ public function testInvokesOnStatsFunctionForError() { $e = new \Exception('a'); $c = null; - $mock = new MockHandler([$e], null, function ($v) use (&$c) { $c = $v; }); + $mock = new MockHandler([$e], null, function ($v) use (&$c) { + $c = $v; + }); $request = new Request('GET', 'http://example.com'); /** @var TransferStats|null $stats */ @@ -229,7 +235,9 @@ public function testTransferTime() { $e = new \Exception('a'); $c = null; - $mock = new MockHandler([$e], null, function ($v) use (&$c) { $c = $v; }); + $mock = new MockHandler([$e], null, function ($v) use (&$c) { + $c = $v; + }); $request = new Request('GET', 'http://example.com'); $stats = null; $onStats = function (TransferStats $s) use (&$stats) { diff --git a/tests/Handler/ProxyTest.php b/tests/Handler/ProxyTest.php index 34236afd3..ea3653f59 100644 --- a/tests/Handler/ProxyTest.php +++ b/tests/Handler/ProxyTest.php @@ -15,8 +15,12 @@ class ProxyTest extends TestCase public function testSendsToNonSync() { $a = $b = null; - $m1 = new MockHandler([function ($v) use (&$a) { $a = $v; }]); - $m2 = new MockHandler([function ($v) use (&$b) { $b = $v; }]); + $m1 = new MockHandler([function ($v) use (&$a) { + $a = $v; + }]); + $m2 = new MockHandler([function ($v) use (&$b) { + $b = $v; + }]); $h = Proxy::wrapSync($m1, $m2); $h(new Request('GET', 'http://foo.com'), []); $this->assertNotNull($a); @@ -26,8 +30,12 @@ public function testSendsToNonSync() public function testSendsToSync() { $a = $b = null; - $m1 = new MockHandler([function ($v) use (&$a) { $a = $v; }]); - $m2 = new MockHandler([function ($v) use (&$b) { $b = $v; }]); + $m1 = new MockHandler([function ($v) use (&$a) { + $a = $v; + }]); + $m2 = new MockHandler([function ($v) use (&$b) { + $b = $v; + }]); $h = Proxy::wrapSync($m1, $m2); $h(new Request('GET', 'http://foo.com'), [RequestOptions::SYNCHRONOUS => true]); $this->assertNull($a); @@ -37,8 +45,12 @@ public function testSendsToSync() public function testSendsToStreaming() { $a = $b = null; - $m1 = new MockHandler([function ($v) use (&$a) { $a = $v; }]); - $m2 = new MockHandler([function ($v) use (&$b) { $b = $v; }]); + $m1 = new MockHandler([function ($v) use (&$a) { + $a = $v; + }]); + $m2 = new MockHandler([function ($v) use (&$b) { + $b = $v; + }]); $h = Proxy::wrapStreaming($m1, $m2); $h(new Request('GET', 'http://foo.com'), []); $this->assertNotNull($a); @@ -48,8 +60,12 @@ public function testSendsToStreaming() public function testSendsToNonStreaming() { $a = $b = null; - $m1 = new MockHandler([function ($v) use (&$a) { $a = $v; }]); - $m2 = new MockHandler([function ($v) use (&$b) { $b = $v; }]); + $m1 = new MockHandler([function ($v) use (&$a) { + $a = $v; + }]); + $m2 = new MockHandler([function ($v) use (&$b) { + $b = $v; + }]); $h = Proxy::wrapStreaming($m1, $m2); $h(new Request('GET', 'http://foo.com'), ['stream' => true]); $this->assertNull($a); diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index f62994896..16ecbfaf7 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -4,14 +4,14 @@ use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Handler\StreamHandler; use GuzzleHttp\Psr7; +use GuzzleHttp\Psr7\FnStream; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; -use GuzzleHttp\Psr7\FnStream; use GuzzleHttp\RequestOptions; use GuzzleHttp\Tests\Server; use GuzzleHttp\TransferStats; -use Psr\Http\Message\ResponseInterface; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; /** * @covers \GuzzleHttp\Handler\StreamHandler @@ -379,7 +379,9 @@ public function testDebugAttributeWritesStreamInfoToBuffer() $this->queueRes(); $buffer = fopen('php://temp', 'r+'); $this->getSendResult([ - 'progress' => function () use (&$called) { $called = true; }, + 'progress' => function () use (&$called) { + $called = true; + }, 'debug' => $buffer, ]); fseek($buffer, 0); diff --git a/tests/HandlerStackTest.php b/tests/HandlerStackTest.php index 6856b6af4..47381dc5d 100644 --- a/tests/HandlerStackTest.php +++ b/tests/HandlerStackTest.php @@ -12,8 +12,10 @@ class HandlerStackTest extends TestCase { public function testSetsHandlerInCtor() { - $f = function () {}; - $m1 = function () {}; + $f = function () { + }; + $m1 = function () { + }; $h = new HandlerStack($f, [$m1]); $this->assertTrue($h->hasHandler()); } @@ -23,7 +25,8 @@ public function testSetsHandlerInCtor() */ public function testCanSetDifferentHandlerAfterConstruction() { - $f = function () {}; + $f = function () { + }; $h = new HandlerStack(); $h->setHandler($f); $h->resolve(); @@ -128,7 +131,8 @@ public function testCanAddBeforeByName() public function testEnsuresHandlerExistsByName() { $builder = new HandlerStack(); - $builder->before('foo', function () {}); + $builder->before('foo', function () { + }); } public function testCanAddAfterByName() @@ -201,6 +205,10 @@ private function getFunctions() return [&$calls, $handler, $a, $b, $c]; } - public static function foo() {} - public function bar () {} + public static function foo() + { + } + public function bar() + { + } } diff --git a/tests/MessageFormatterTest.php b/tests/MessageFormatterTest.php index e9054a1ac..301c8f6c1 100644 --- a/tests/MessageFormatterTest.php +++ b/tests/MessageFormatterTest.php @@ -2,10 +2,10 @@ namespace GuzzleHttp\Tests; use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\MessageFormatter; use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; -use GuzzleHttp\MessageFormatter; use PHPUnit\Framework\TestCase; /** @@ -88,6 +88,6 @@ public function formatProvider() public function testFormatsMessages($template, $args, $result) { $f = new MessageFormatter($template); - $this->assertSame((string) $result, call_user_func_array(array($f, 'format'), $args)); + $this->assertSame((string) $result, call_user_func_array([$f, 'format'], $args)); } } diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 1d5e276d2..4b9669077 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -11,9 +11,9 @@ use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; +use PHPUnit\Framework\TestCase; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use PHPUnit\Framework\TestCase; use Psr\Log\Test\TestLogger; class MiddlewareTest extends TestCase diff --git a/tests/PoolTest.php b/tests/PoolTest.php index 94b44fa47..e3f15c510 100644 --- a/tests/PoolTest.php +++ b/tests/PoolTest.php @@ -1,16 +1,16 @@ resolve(new Response()); }); - $r2 = new Promise(function () use (&$r2) { $r2->resolve(new Response()); }); - $r3 = new Promise(function () use (&$r3) { $r3->resolve(new Response()); }); + $r1 = new Promise(function () use (&$r1) { + $r1->resolve(new Response()); + }); + $r2 = new Promise(function () use (&$r2) { + $r2->resolve(new Response()); + }); + $r3 = new Promise(function () use (&$r3) { + $r3->resolve(new Response()); + }); $handler = new MockHandler([$r1, $r2, $r3]); $c = new Client(['handler' => $handler]); $p = new Pool($c, [ @@ -137,7 +143,9 @@ function (RequestInterface $request) { ]); $client = new Client(['handler' => $mock]); $results = Pool::batch($client, $requests, [ - 'fulfilled' => function ($value) use (&$called) { $called = true; } + 'fulfilled' => function ($value) use (&$called) { + $called = true; + } ]); $this->assertCount(2, $results); $this->assertTrue($called); @@ -145,9 +153,15 @@ function (RequestInterface $request) { public function testUsesYieldedKeyInFulfilledCallback() { - $r1 = new Promise(function () use (&$r1) { $r1->resolve(new Response()); }); - $r2 = new Promise(function () use (&$r2) { $r2->resolve(new Response()); }); - $r3 = new Promise(function () use (&$r3) { $r3->resolve(new Response()); }); + $r1 = new Promise(function () use (&$r1) { + $r1->resolve(new Response()); + }); + $r2 = new Promise(function () use (&$r2) { + $r2->resolve(new Response()); + }); + $r3 = new Promise(function () use (&$r3) { + $r3->resolve(new Response()); + }); $handler = new MockHandler([$r1, $r2, $r3]); $c = new Client(['handler' => $handler]); $keys = []; @@ -158,7 +172,9 @@ public function testUsesYieldedKeyInFulfilledCallback() ]; $p = new Pool($c, $requests, [ 'pool_size' => 2, - 'fulfilled' => function($res, $index) use (&$keys) { $keys[] = $index; } + 'fulfilled' => function ($res, $index) use (&$keys) { + $keys[] = $index; + } ]); $p->promise()->wait(); $this->assertCount(3, $keys); diff --git a/tests/PrepareBodyMiddlewareTest.php b/tests/PrepareBodyMiddlewareTest.php index 53d2316e5..bff4be003 100644 --- a/tests/PrepareBodyMiddlewareTest.php +++ b/tests/PrepareBodyMiddlewareTest.php @@ -9,8 +9,8 @@ use GuzzleHttp\Psr7\FnStream; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; -use Psr\Http\Message\RequestInterface; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\RequestInterface; class PrepareBodyMiddlewareTest extends TestCase { @@ -53,7 +53,9 @@ function (RequestInterface $request) use ($body) { public function testAddsTransferEncodingWhenNoContentLength() { $body = FnStream::decorate(Psr7\stream_for('foo'), [ - 'getSize' => function () { return null; } + 'getSize' => function () { + return null; + } ]); $h = new MockHandler([ function (RequestInterface $request) { diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index 39fbb5c3e..e168abd06 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -8,8 +8,8 @@ use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\RedirectMiddleware; -use Psr\Http\Message\RequestInterface; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\RequestInterface; /** * @covers GuzzleHttp\RedirectMiddleware diff --git a/tests/RetryMiddlewareTest.php b/tests/RetryMiddlewareTest.php index 3189340f5..be3e277cd 100644 --- a/tests/RetryMiddlewareTest.php +++ b/tests/RetryMiddlewareTest.php @@ -39,7 +39,9 @@ public function testRetriesWhenDeciderReturnsTrue() public function testDoesNotRetryWhenDeciderReturnsFalse() { - $decider = function () { return false; }; + $decider = function () { + return false; + }; $m = Middleware::retry($decider); $h = new MockHandler([new Response(200)]); $c = new Client(['handler' => $m($h)]); diff --git a/tests/TransferStatsTest.php b/tests/TransferStatsTest.php index 9ef891794..76506fb27 100644 --- a/tests/TransferStatsTest.php +++ b/tests/TransferStatsTest.php @@ -1,8 +1,8 @@ 'value', 'hello' => 'Hello World!', 'empty' => '', @@ -22,97 +22,97 @@ public function templateProvider() 'x' => '1024', 'y' => '768', 'null' => null, - 'list' => array('red', 'green', 'blue'), - 'keys' => array( + 'list' => ['red', 'green', 'blue'], + 'keys' => [ "semi" => ';', "dot" => '.', "comma" => ',' - ), - 'empty_keys' => array(), - ); + ], + 'empty_keys' => [], + ]; return array_map(function ($t) use ($params) { $t[] = $params; return $t; - }, array( - array('foo', 'foo'), - array('{var}', 'value'), - array('{hello}', 'Hello%20World%21'), - array('{+var}', 'value'), - array('{+hello}', 'Hello%20World!'), - array('{+path}/here', '/foo/bar/here'), - array('here?ref={+path}', 'here?ref=/foo/bar'), - array('X{#var}', 'X#value'), - array('X{#hello}', 'X#Hello%20World!'), - array('map?{x,y}', 'map?1024,768'), - array('{x,hello,y}', '1024,Hello%20World%21,768'), - array('{+x,hello,y}', '1024,Hello%20World!,768'), - array('{+path,x}/here', '/foo/bar,1024/here'), - array('{#x,hello,y}', '#1024,Hello%20World!,768'), - array('{#path,x}/here', '#/foo/bar,1024/here'), - array('X{.var}', 'X.value'), - array('X{.x,y}', 'X.1024.768'), - array('{/var}', '/value'), - array('{/var,x}/here', '/value/1024/here'), - array('{;x,y}', ';x=1024;y=768'), - array('{;x,y,empty}', ';x=1024;y=768;empty'), - array('{?x,y}', '?x=1024&y=768'), - array('{?x,y,empty}', '?x=1024&y=768&empty='), - array('?fixed=yes{&x}', '?fixed=yes&x=1024'), - array('{&x,y,empty}', '&x=1024&y=768&empty='), - array('{var:3}', 'val'), - array('{var:30}', 'value'), - array('{list}', 'red,green,blue'), - array('{list*}', 'red,green,blue'), - array('{keys}', 'semi,%3B,dot,.,comma,%2C'), - array('{keys*}', 'semi=%3B,dot=.,comma=%2C'), - array('{+path:6}/here', '/foo/b/here'), - array('{+list}', 'red,green,blue'), - array('{+list*}', 'red,green,blue'), - array('{+keys}', 'semi,;,dot,.,comma,,'), - array('{+keys*}', 'semi=;,dot=.,comma=,'), - array('{#path:6}/here', '#/foo/b/here'), - array('{#list}', '#red,green,blue'), - array('{#list*}', '#red,green,blue'), - array('{#keys}', '#semi,;,dot,.,comma,,'), - array('{#keys*}', '#semi=;,dot=.,comma=,'), - array('X{.var:3}', 'X.val'), - array('X{.list}', 'X.red,green,blue'), - array('X{.list*}', 'X.red.green.blue'), - array('X{.keys}', 'X.semi,%3B,dot,.,comma,%2C'), - array('X{.keys*}', 'X.semi=%3B.dot=..comma=%2C'), - array('{/var:1,var}', '/v/value'), - array('{/list}', '/red,green,blue'), - array('{/list*}', '/red/green/blue'), - array('{/list*,path:4}', '/red/green/blue/%2Ffoo'), - array('{/keys}', '/semi,%3B,dot,.,comma,%2C'), - array('{/keys*}', '/semi=%3B/dot=./comma=%2C'), - array('{;hello:5}', ';hello=Hello'), - array('{;list}', ';list=red,green,blue'), - array('{;list*}', ';list=red;list=green;list=blue'), - array('{;keys}', ';keys=semi,%3B,dot,.,comma,%2C'), - array('{;keys*}', ';semi=%3B;dot=.;comma=%2C'), - array('{?var:3}', '?var=val'), - array('{?list}', '?list=red,green,blue'), - array('{?list*}', '?list=red&list=green&list=blue'), - array('{?keys}', '?keys=semi,%3B,dot,.,comma,%2C'), - array('{?keys*}', '?semi=%3B&dot=.&comma=%2C'), - array('{&var:3}', '&var=val'), - array('{&list}', '&list=red,green,blue'), - array('{&list*}', '&list=red&list=green&list=blue'), - array('{&keys}', '&keys=semi,%3B,dot,.,comma,%2C'), - array('{&keys*}', '&semi=%3B&dot=.&comma=%2C'), - array('{.null}', ''), - array('{.null,var}', '.value'), - array('X{.empty_keys*}', 'X'), - array('X{.empty_keys}', 'X'), + }, [ + ['foo', 'foo'], + ['{var}', 'value'], + ['{hello}', 'Hello%20World%21'], + ['{+var}', 'value'], + ['{+hello}', 'Hello%20World!'], + ['{+path}/here', '/foo/bar/here'], + ['here?ref={+path}', 'here?ref=/foo/bar'], + ['X{#var}', 'X#value'], + ['X{#hello}', 'X#Hello%20World!'], + ['map?{x,y}', 'map?1024,768'], + ['{x,hello,y}', '1024,Hello%20World%21,768'], + ['{+x,hello,y}', '1024,Hello%20World!,768'], + ['{+path,x}/here', '/foo/bar,1024/here'], + ['{#x,hello,y}', '#1024,Hello%20World!,768'], + ['{#path,x}/here', '#/foo/bar,1024/here'], + ['X{.var}', 'X.value'], + ['X{.x,y}', 'X.1024.768'], + ['{/var}', '/value'], + ['{/var,x}/here', '/value/1024/here'], + ['{;x,y}', ';x=1024;y=768'], + ['{;x,y,empty}', ';x=1024;y=768;empty'], + ['{?x,y}', '?x=1024&y=768'], + ['{?x,y,empty}', '?x=1024&y=768&empty='], + ['?fixed=yes{&x}', '?fixed=yes&x=1024'], + ['{&x,y,empty}', '&x=1024&y=768&empty='], + ['{var:3}', 'val'], + ['{var:30}', 'value'], + ['{list}', 'red,green,blue'], + ['{list*}', 'red,green,blue'], + ['{keys}', 'semi,%3B,dot,.,comma,%2C'], + ['{keys*}', 'semi=%3B,dot=.,comma=%2C'], + ['{+path:6}/here', '/foo/b/here'], + ['{+list}', 'red,green,blue'], + ['{+list*}', 'red,green,blue'], + ['{+keys}', 'semi,;,dot,.,comma,,'], + ['{+keys*}', 'semi=;,dot=.,comma=,'], + ['{#path:6}/here', '#/foo/b/here'], + ['{#list}', '#red,green,blue'], + ['{#list*}', '#red,green,blue'], + ['{#keys}', '#semi,;,dot,.,comma,,'], + ['{#keys*}', '#semi=;,dot=.,comma=,'], + ['X{.var:3}', 'X.val'], + ['X{.list}', 'X.red,green,blue'], + ['X{.list*}', 'X.red.green.blue'], + ['X{.keys}', 'X.semi,%3B,dot,.,comma,%2C'], + ['X{.keys*}', 'X.semi=%3B.dot=..comma=%2C'], + ['{/var:1,var}', '/v/value'], + ['{/list}', '/red,green,blue'], + ['{/list*}', '/red/green/blue'], + ['{/list*,path:4}', '/red/green/blue/%2Ffoo'], + ['{/keys}', '/semi,%3B,dot,.,comma,%2C'], + ['{/keys*}', '/semi=%3B/dot=./comma=%2C'], + ['{;hello:5}', ';hello=Hello'], + ['{;list}', ';list=red,green,blue'], + ['{;list*}', ';list=red;list=green;list=blue'], + ['{;keys}', ';keys=semi,%3B,dot,.,comma,%2C'], + ['{;keys*}', ';semi=%3B;dot=.;comma=%2C'], + ['{?var:3}', '?var=val'], + ['{?list}', '?list=red,green,blue'], + ['{?list*}', '?list=red&list=green&list=blue'], + ['{?keys}', '?keys=semi,%3B,dot,.,comma,%2C'], + ['{?keys*}', '?semi=%3B&dot=.&comma=%2C'], + ['{&var:3}', '&var=val'], + ['{&list}', '&list=red,green,blue'], + ['{&list*}', '&list=red&list=green&list=blue'], + ['{&keys}', '&keys=semi,%3B,dot,.,comma,%2C'], + ['{&keys*}', '&semi=%3B&dot=.&comma=%2C'], + ['{.null}', ''], + ['{.null,var}', '.value'], + ['X{.empty_keys*}', 'X'], + ['X{.empty_keys}', 'X'], // Test that missing expansions are skipped - array('test{&missing*}', 'test'), + ['test{&missing*}', 'test'], // Test that multiple expansions can be set - array('http://{var}/{var:2}{?keys*}', 'http://value/va?semi=%3B&dot=.&comma=%2C'), + ['http://{var}/{var:2}{?keys*}', 'http://value/va?semi=%3B&dot=.&comma=%2C'], // Test more complex query string stuff - array('http://www.test.com{+path}{?var,keys*}', 'http://www.test.com/foo/bar?var=value&semi=%3B&dot=.&comma=%2C') - )); + ['http://www.test.com{+path}{?var,keys*}', 'http://www.test.com/foo/bar?var=value&semi=%3B&dot=.&comma=%2C'] + ]); } /** @@ -126,36 +126,36 @@ public function testExpandsUriTemplates($template, $expansion, $params) public function expressionProvider() { - return array( - array( - '{+var*}', array( + return [ + [ + '{+var*}', [ 'operator' => '+', - 'values' => array( - array('modifier' => '*', 'value' => 'var') - ) - ), - ), - array( - '{?keys,var,val}', array( + 'values' => [ + ['modifier' => '*', 'value' => 'var'] + ] + ], + ], + [ + '{?keys,var,val}', [ 'operator' => '?', - 'values' => array( - array('value' => 'keys', 'modifier' => ''), - array('value' => 'var', 'modifier' => ''), - array('value' => 'val', 'modifier' => '') - ) - ), - ), - array( - '{+x,hello,y}', array( + 'values' => [ + ['value' => 'keys', 'modifier' => ''], + ['value' => 'var', 'modifier' => ''], + ['value' => 'val', 'modifier' => ''] + ] + ], + ], + [ + '{+x,hello,y}', [ 'operator' => '+', - 'values' => array( - array('value' => 'x', 'modifier' => ''), - array('value' => 'hello', 'modifier' => ''), - array('value' => 'y', 'modifier' => '') - ) - ) - ) - ); + 'values' => [ + ['value' => 'x', 'modifier' => ''], + ['value' => 'hello', 'modifier' => ''], + ['value' => 'y', 'modifier' => ''] + ] + ] + ] + ]; } /** @@ -171,7 +171,7 @@ public function testParsesExpressions($exp, $data) $method->setAccessible(true); $exp = substr($exp, 1, -1); - $this->assertSame($data, $method->invokeArgs($template, array($exp))); + $this->assertSame($data, $method->invokeArgs($template, [$exp])); } /** @@ -181,21 +181,21 @@ public function testAllowsNestedArrayExpansion() { $template = new UriTemplate(); - $result = $template->expand('http://example.com{+path}{/segments}{?query,data*,foo*}', array( + $result = $template->expand('http://example.com{+path}{/segments}{?query,data*,foo*}', [ 'path' => '/foo/bar', - 'segments' => array('one', 'two'), + 'segments' => ['one', 'two'], 'query' => 'test', - 'data' => array( - 'more' => array('fun', 'ice cream') - ), - 'foo' => array( - 'baz' => array( + 'data' => [ + 'more' => ['fun', 'ice cream'] + ], + 'foo' => [ + 'baz' => [ 'bar' => 'fizz', 'test' => 'buzz' - ), + ], 'bam' => 'boo' - ) - )); + ] + ]); $this->assertSame('http://example.com/foo/bar/one,two?query=test&more%5B0%5D=fun&more%5B1%5D=ice%20cream&baz%5Bbar%5D=fizz&baz%5Btest%5D=buzz&bam=boo', $result); } From df36d8dae3979cf927d5bbbed6f0427f39aadfec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Podlipsk=C3=BD?= Date: Wed, 30 Oct 2019 12:22:04 +0100 Subject: [PATCH 102/141] Use PHPUnit static assertions (#2314) * Call PHPUnit assertions property * Fix CS --- .php_cs | 1 + phpunit.xml.dist | 10 +- tests/ClientTest.php | 152 ++++++++-------- tests/Cookie/CookieJarTest.php | 102 +++++------ tests/Cookie/FileCookieJarTest.php | 10 +- tests/Cookie/SessionCookieJarTest.php | 10 +- tests/Cookie/SetCookieTest.php | 94 +++++----- tests/Exception/ConnectExceptionTest.php | 12 +- tests/Exception/RequestExceptionTest.php | 58 +++--- tests/Exception/SeekExceptionTest.php | 4 +- tests/Handler/CurlFactoryTest.php | 222 +++++++++++------------ tests/Handler/CurlHandlerTest.php | 14 +- tests/Handler/CurlMultiHandlerTest.php | 16 +- tests/Handler/MockHandlerTest.php | 50 ++--- tests/Handler/ProxyTest.php | 16 +- tests/Handler/StreamHandlerTest.php | 202 ++++++++++----------- tests/HandlerStackTest.php | 52 +++--- tests/MessageFormatterTest.php | 8 +- tests/MiddlewareTest.php | 58 +++--- tests/PoolTest.php | 28 +-- tests/PrepareBodyMiddlewareTest.php | 36 ++-- tests/RedirectMiddlewareTest.php | 34 ++-- tests/RetryMiddlewareTest.php | 38 ++-- tests/TransferStatsTest.php | 16 +- tests/UriTemplateTest.php | 6 +- tests/functionsTest.php | 22 +-- 26 files changed, 638 insertions(+), 633 deletions(-) diff --git a/.php_cs b/.php_cs index 9d37edf9c..2dd5036c1 100644 --- a/.php_cs +++ b/.php_cs @@ -7,6 +7,7 @@ $config = PhpCsFixer\Config::create() 'array_syntax' => ['syntax' => 'short'], 'declare_strict_types' => false, 'concat_space' => ['spacing'=>'one'], + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], 'ordered_imports' => true, // 'phpdoc_align' => ['align'=>'vertical'], // 'native_function_invocation' => true, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5369af3f9..6316581c3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,11 @@ - + tests diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 7e8a69580..05c0d3a7d 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -20,7 +20,7 @@ public function testUsesDefaultHandler() $client = new Client(); Server::enqueue([new Response(200, ['Content-Length' => 0])]); $response = $client->get(Server::$url); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } /** @@ -39,11 +39,11 @@ public function testCanSendMagicAsyncRequests() Server::flush(); Server::enqueue([new Response(200, ['Content-Length' => 2], 'hi')]); $p = $client->getAsync(Server::$url, ['query' => ['test' => 'foo']]); - $this->assertInstanceOf(PromiseInterface::class, $p); - $this->assertSame(200, $p->wait()->getStatusCode()); + self::assertInstanceOf(PromiseInterface::class, $p); + self::assertSame(200, $p->wait()->getStatusCode()); $received = Server::received(true); - $this->assertCount(1, $received); - $this->assertSame('test=foo', $received[0]->getUri()->getQuery()); + self::assertCount(1, $received); + self::assertSame('test=foo', $received[0]->getUri()->getQuery()); } public function testCanSendSynchronously() @@ -51,8 +51,8 @@ public function testCanSendSynchronously() $client = new Client(['handler' => new MockHandler([new Response()])]); $request = new Request('GET', 'http://example.com'); $r = $client->send($request); - $this->assertInstanceOf(ResponseInterface::class, $r); - $this->assertSame(200, $r->getStatusCode()); + self::assertInstanceOf(ResponseInterface::class, $r); + self::assertSame(200, $r->getStatusCode()); } public function testClientHasOptions() @@ -64,12 +64,12 @@ public function testClientHasOptions() 'handler' => new MockHandler() ]); $base = $client->getConfig('base_uri'); - $this->assertSame('http://foo.com', (string) $base); - $this->assertInstanceOf(Uri::class, $base); - $this->assertNotNull($client->getConfig('handler')); - $this->assertSame(2, $client->getConfig('timeout')); - $this->assertArrayHasKey('timeout', $client->getConfig()); - $this->assertArrayHasKey('headers', $client->getConfig()); + self::assertSame('http://foo.com', (string) $base); + self::assertInstanceOf(Uri::class, $base); + self::assertNotNull($client->getConfig('handler')); + self::assertSame(2, $client->getConfig('timeout')); + self::assertArrayHasKey('timeout', $client->getConfig()); + self::assertArrayHasKey('headers', $client->getConfig()); } public function testCanMergeOnBaseUri() @@ -80,7 +80,7 @@ public function testCanMergeOnBaseUri() 'handler' => $mock ]); $client->get('baz'); - $this->assertSame( + self::assertSame( 'http://foo.com/bar/baz', (string)$mock->getLastRequest()->getUri() ); @@ -94,13 +94,13 @@ public function testCanMergeOnBaseUriWithRequest() 'base_uri' => 'http://foo.com/bar/' ]); $client->request('GET', new Uri('baz')); - $this->assertSame( + self::assertSame( 'http://foo.com/bar/baz', (string) $mock->getLastRequest()->getUri() ); $client->request('GET', new Uri('baz'), ['base_uri' => 'http://example.com/foo/']); - $this->assertSame( + self::assertSame( 'http://example.com/foo/baz', (string) $mock->getLastRequest()->getUri(), 'Can overwrite the base_uri through the request options' @@ -114,10 +114,10 @@ public function testCanUseRelativeUriWithSend() 'handler' => $mock, 'base_uri' => 'http://bar.com' ]); - $this->assertSame('http://bar.com', (string) $client->getConfig('base_uri')); + self::assertSame('http://bar.com', (string) $client->getConfig('base_uri')); $request = new Request('GET', '/baz'); $client->send($request); - $this->assertSame( + self::assertSame( 'http://bar.com/baz', (string) $mock->getLastRequest()->getUri() ); @@ -126,11 +126,11 @@ public function testCanUseRelativeUriWithSend() public function testMergesDefaultOptionsAndDoesNotOverwriteUa() { $c = new Client(['headers' => ['User-agent' => 'foo']]); - $this->assertSame(['User-agent' => 'foo'], $c->getConfig('headers')); - $this->assertInternalType('array', $c->getConfig('allow_redirects')); - $this->assertTrue($c->getConfig('http_errors')); - $this->assertTrue($c->getConfig('decode_content')); - $this->assertTrue($c->getConfig('verify')); + self::assertSame(['User-agent' => 'foo'], $c->getConfig('headers')); + self::assertInternalType('array', $c->getConfig('allow_redirects')); + self::assertTrue($c->getConfig('http_errors')); + self::assertTrue($c->getConfig('decode_content')); + self::assertTrue($c->getConfig('verify')); } public function testDoesNotOverwriteHeaderWithDefault() @@ -141,7 +141,7 @@ public function testDoesNotOverwriteHeaderWithDefault() 'handler' => $mock ]); $c->get('http://example.com', ['headers' => ['User-Agent' => 'bar']]); - $this->assertSame('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); + self::assertSame('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); } public function testDoesNotOverwriteHeaderWithDefaultInRequest() @@ -153,7 +153,7 @@ public function testDoesNotOverwriteHeaderWithDefaultInRequest() ]); $request = new Request('GET', Server::$url, ['User-Agent' => 'bar']); $c->send($request); - $this->assertSame('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); + self::assertSame('bar', $mock->getLastRequest()->getHeaderLine('User-Agent')); } public function testDoesOverwriteHeaderWithSetRequestOption() @@ -165,7 +165,7 @@ public function testDoesOverwriteHeaderWithSetRequestOption() ]); $request = new Request('GET', Server::$url, ['User-Agent' => 'bar']); $c->send($request, ['headers' => ['User-Agent' => 'YO']]); - $this->assertSame('YO', $mock->getLastRequest()->getHeaderLine('User-Agent')); + self::assertSame('YO', $mock->getLastRequest()->getHeaderLine('User-Agent')); } public function testCanUnsetRequestOptionWithNull() @@ -176,14 +176,14 @@ public function testCanUnsetRequestOptionWithNull() 'handler' => $mock ]); $c->get('http://example.com', ['headers' => null]); - $this->assertFalse($mock->getLastRequest()->hasHeader('foo')); + self::assertFalse($mock->getLastRequest()->hasHeader('foo')); } public function testRewriteExceptionsToHttpErrors() { $client = new Client(['handler' => new MockHandler([new Response(404)])]); $res = $client->get('http://foo.com', ['exceptions' => false]); - $this->assertSame(404, $res->getStatusCode()); + self::assertSame(404, $res->getStatusCode()); } public function testRewriteSaveToToSink() @@ -192,7 +192,7 @@ public function testRewriteSaveToToSink() $mock = new MockHandler([new Response(200, [], 'foo')]); $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['save_to' => $r]); - $this->assertSame($r, $mock->getLastOptions()['sink']); + self::assertSame($r, $mock->getLastOptions()['sink']); } public function testAllowRedirectsCanBeTrue() @@ -201,7 +201,7 @@ public function testAllowRedirectsCanBeTrue() $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); $client->get('http://foo.com', ['allow_redirects' => true]); - $this->assertInternalType('array', $mock->getLastOptions()['allow_redirects']); + self::assertInternalType('array', $mock->getLastOptions()['allow_redirects']); } /** @@ -249,7 +249,7 @@ public function testSetCookieToTrueUsesSharedJar() $client = new Client(['handler' => $handler, 'cookies' => true]); $client->get('http://foo.com'); $client->get('http://foo.com'); - $this->assertSame('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); + self::assertSame('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); } public function testSetCookieToJar() @@ -263,7 +263,7 @@ public function testSetCookieToJar() $jar = new CookieJar(); $client->get('http://foo.com', ['cookies' => $jar]); $client->get('http://foo.com', ['cookies' => $jar]); - $this->assertSame('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); + self::assertSame('foo=bar', $mock->getLastRequest()->getHeaderLine('Cookie')); } public function testCanDisableContentDecoding() @@ -272,8 +272,8 @@ public function testCanDisableContentDecoding() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['decode_content' => false]); $last = $mock->getLastRequest(); - $this->assertFalse($last->hasHeader('Accept-Encoding')); - $this->assertFalse($mock->getLastOptions()['decode_content']); + self::assertFalse($last->hasHeader('Accept-Encoding')); + self::assertFalse($mock->getLastOptions()['decode_content']); } public function testCanSetContentDecodingToValue() @@ -282,8 +282,8 @@ public function testCanSetContentDecodingToValue() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['decode_content' => 'gzip']); $last = $mock->getLastRequest(); - $this->assertSame('gzip', $last->getHeaderLine('Accept-Encoding')); - $this->assertSame('gzip', $mock->getLastOptions()['decode_content']); + self::assertSame('gzip', $last->getHeaderLine('Accept-Encoding')); + self::assertSame('gzip', $mock->getLastOptions()['decode_content']); } /** @@ -303,7 +303,7 @@ public function testAddsBody() $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['body' => 'foo']); $last = $mock->getLastRequest(); - $this->assertSame('foo', (string) $last->getBody()); + self::assertSame('foo', (string) $last->getBody()); } /** @@ -323,7 +323,7 @@ public function testQueryCanBeString() $client = new Client(['handler' => $mock]); $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['query' => 'foo']); - $this->assertSame('foo', $mock->getLastRequest()->getUri()->getQuery()); + self::assertSame('foo', $mock->getLastRequest()->getUri()->getQuery()); } public function testQueryCanBeArray() @@ -332,7 +332,7 @@ public function testQueryCanBeArray() $client = new Client(['handler' => $mock]); $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['query' => ['foo' => 'bar baz']]); - $this->assertSame('foo=bar%20baz', $mock->getLastRequest()->getUri()->getQuery()); + self::assertSame('foo=bar%20baz', $mock->getLastRequest()->getUri()->getQuery()); } public function testCanAddJsonData() @@ -342,8 +342,8 @@ public function testCanAddJsonData() $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['json' => ['foo' => 'bar']]); $last = $mock->getLastRequest(); - $this->assertSame('{"foo":"bar"}', (string) $mock->getLastRequest()->getBody()); - $this->assertSame('application/json', $last->getHeaderLine('Content-Type')); + self::assertSame('{"foo":"bar"}', (string) $mock->getLastRequest()->getBody()); + self::assertSame('application/json', $last->getHeaderLine('Content-Type')); } public function testCanAddJsonDataWithoutOverwritingContentType() @@ -356,8 +356,8 @@ public function testCanAddJsonDataWithoutOverwritingContentType() 'json' => 'a' ]); $last = $mock->getLastRequest(); - $this->assertSame('"a"', (string) $mock->getLastRequest()->getBody()); - $this->assertSame('foo', $last->getHeaderLine('Content-Type')); + self::assertSame('"a"', (string) $mock->getLastRequest()->getBody()); + self::assertSame('foo', $last->getHeaderLine('Content-Type')); } public function testCanAddJsonDataWithNullHeader() @@ -370,8 +370,8 @@ public function testCanAddJsonDataWithNullHeader() 'json' => 'a' ]); $last = $mock->getLastRequest(); - $this->assertSame('"a"', (string) $mock->getLastRequest()->getBody()); - $this->assertSame('application/json', $last->getHeaderLine('Content-Type')); + self::assertSame('"a"', (string) $mock->getLastRequest()->getBody()); + self::assertSame('application/json', $last->getHeaderLine('Content-Type')); } public function testAuthCanBeTrue() @@ -380,7 +380,7 @@ public function testAuthCanBeTrue() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => false]); $last = $mock->getLastRequest(); - $this->assertFalse($last->hasHeader('Authorization')); + self::assertFalse($last->hasHeader('Authorization')); } public function testAuthCanBeArrayForBasicAuth() @@ -389,7 +389,7 @@ public function testAuthCanBeArrayForBasicAuth() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => ['a', 'b']]); $last = $mock->getLastRequest(); - $this->assertSame('Basic YTpi', $last->getHeaderLine('Authorization')); + self::assertSame('Basic YTpi', $last->getHeaderLine('Authorization')); } public function testAuthCanBeArrayForDigestAuth() @@ -398,7 +398,7 @@ public function testAuthCanBeArrayForDigestAuth() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => ['a', 'b', 'digest']]); $last = $mock->getLastOptions(); - $this->assertSame([ + self::assertSame([ CURLOPT_HTTPAUTH => 2, CURLOPT_USERPWD => 'a:b' ], $last['curl']); @@ -410,7 +410,7 @@ public function testAuthCanBeArrayForNtlmAuth() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => ['a', 'b', 'ntlm']]); $last = $mock->getLastOptions(); - $this->assertSame([ + self::assertSame([ CURLOPT_HTTPAUTH => 8, CURLOPT_USERPWD => 'a:b' ], $last['curl']); @@ -422,7 +422,7 @@ public function testAuthCanBeCustomType() $client = new Client(['handler' => $mock]); $client->get('http://foo.com', ['auth' => 'foo']); $last = $mock->getLastOptions(); - $this->assertSame('foo', $last['auth']); + self::assertSame('foo', $last['auth']); } public function testCanAddFormParams() @@ -436,11 +436,11 @@ public function testCanAddFormParams() ] ]); $last = $mock->getLastRequest(); - $this->assertSame( + self::assertSame( 'application/x-www-form-urlencoded', $last->getHeaderLine('Content-Type') ); - $this->assertSame( + self::assertSame( 'foo=bar+bam&baz%5Bboo%5D=qux', (string) $last->getBody() ); @@ -459,7 +459,7 @@ public function testFormParamsEncodedProperly() ] ]); $last = $mock->getLastRequest(); - $this->assertSame( + self::assertSame( 'foo=bar+bam&baz%5Bboo%5D=qux', (string) $last->getBody() ); @@ -498,22 +498,22 @@ public function testCanSendMultipart() ]); $last = $mock->getLastRequest(); - $this->assertContains( + self::assertContains( 'multipart/form-data; boundary=', $last->getHeaderLine('Content-Type') ); - $this->assertContains( + self::assertContains( 'Content-Disposition: form-data; name="foo"', (string) $last->getBody() ); - $this->assertContains('bar', (string) $last->getBody()); - $this->assertContains( + self::assertContains('bar', (string) $last->getBody()); + self::assertContains( 'Content-Disposition: form-data; name="foo"' . "\r\n", (string) $last->getBody() ); - $this->assertContains( + self::assertContains( 'Content-Disposition: form-data; name="test"; filename="ClientTest.php"', (string) $last->getBody() ); @@ -544,22 +544,22 @@ public function testCanSendMultipartWithExplicitBody() ); $last = $mock->getLastRequest(); - $this->assertContains( + self::assertContains( 'multipart/form-data; boundary=', $last->getHeaderLine('Content-Type') ); - $this->assertContains( + self::assertContains( 'Content-Disposition: form-data; name="foo"', (string) $last->getBody() ); - $this->assertContains('bar', (string) $last->getBody()); - $this->assertContains( + self::assertContains('bar', (string) $last->getBody()); + self::assertContains( 'Content-Disposition: form-data; name="foo"' . "\r\n", (string) $last->getBody() ); - $this->assertContains( + self::assertContains( 'Content-Disposition: form-data; name="test"; filename="ClientTest.php"', (string) $last->getBody() ); @@ -571,17 +571,17 @@ public function testUsesProxyEnvironmentVariables() $https = getenv('HTTPS_PROXY'); $no = getenv('NO_PROXY'); $client = new Client(); - $this->assertNull($client->getConfig('proxy')); + self::assertNull($client->getConfig('proxy')); putenv('HTTP_PROXY=127.0.0.1'); $client = new Client(); - $this->assertSame( + self::assertSame( ['http' => '127.0.0.1'], $client->getConfig('proxy') ); putenv('HTTPS_PROXY=127.0.0.2'); putenv('NO_PROXY=127.0.0.3, 127.0.0.4'); $client = new Client(); - $this->assertSame( + self::assertSame( ['http' => '127.0.0.1', 'https' => '127.0.0.2', 'no' => ['127.0.0.3','127.0.0.4']], $client->getConfig('proxy') ); @@ -595,7 +595,7 @@ public function testRequestSendsWithSync() $mock = new MockHandler([new Response()]); $client = new Client(['handler' => $mock]); $client->request('GET', 'http://foo.com'); - $this->assertTrue($mock->getLastOptions()['synchronous']); + self::assertTrue($mock->getLastOptions()['synchronous']); } public function testSendSendsWithSync() @@ -603,7 +603,7 @@ public function testSendSendsWithSync() $mock = new MockHandler([new Response()]); $client = new Client(['handler' => $mock]); $client->send(new Request('GET', 'http://foo.com')); - $this->assertTrue($mock->getLastOptions()['synchronous']); + self::assertTrue($mock->getLastOptions()['synchronous']); } public function testCanSetCustomHandler() @@ -611,7 +611,7 @@ public function testCanSetCustomHandler() $mock = new MockHandler([new Response(500)]); $client = new Client(['handler' => $mock]); $mock2 = new MockHandler([new Response(200)]); - $this->assertSame( + self::assertSame( 200, $client->send(new Request('GET', 'http://foo.com'), [ 'handler' => $mock2 @@ -625,7 +625,7 @@ public function testProperlyBuildsQuery() $client = new Client(['handler' => $mock]); $request = new Request('PUT', 'http://foo.com'); $client->send($request, ['query' => ['foo' => 'bar', 'john' => 'doe']]); - $this->assertSame('foo=bar&john=doe', $mock->getLastRequest()->getUri()->getQuery()); + self::assertSame('foo=bar&john=doe', $mock->getLastRequest()->getUri()->getQuery()); } public function testSendSendsWithIpAddressAndPortAndHostHeaderInRequestTheHostShouldBePreserved() @@ -636,7 +636,7 @@ public function testSendSendsWithIpAddressAndPortAndHostHeaderInRequestTheHostSh $client->send($request); - $this->assertSame('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); + self::assertSame('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); } public function testSendSendsWithDomainAndHostHeaderInRequestTheHostShouldBePreserved() @@ -647,7 +647,7 @@ public function testSendSendsWithDomainAndHostHeaderInRequestTheHostShouldBePres $client->send($request); - $this->assertSame('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); + self::assertSame('foo.com', $mockHandler->getLastRequest()->getHeader('Host')[0]); } /** @@ -667,7 +667,7 @@ public function testHttpDefaultSchemeIfUriHasNone() $client->request('GET', '//example.org/test'); - $this->assertSame('http://example.org/test', (string) $mockHandler->getLastRequest()->getUri()); + self::assertSame('http://example.org/test', (string) $mockHandler->getLastRequest()->getUri()); } public function testOnlyAddSchemeWhenHostIsPresent() @@ -676,7 +676,7 @@ public function testOnlyAddSchemeWhenHostIsPresent() $client = new Client(['handler' => $mockHandler]); $client->request('GET', 'baz'); - $this->assertSame( + self::assertSame( 'baz', (string) $mockHandler->getLastRequest()->getUri() ); @@ -698,7 +698,7 @@ public function testResponseBodyAsString() $request = new Request('GET', 'http://foo.com'); $response = $client->send($request, ['json' => ['a' => 'b']]); - $this->assertSame($responseBody, (string) $response->getBody()); + self::assertSame($responseBody, (string) $response->getBody()); } public function testResponseContent() @@ -709,6 +709,6 @@ public function testResponseContent() $request = new Request('POST', 'http://foo.com'); $response = $client->send($request, ['json' => ['a' => 'b']]); - $this->assertSame($responseBody, $response->getBody()->getContents()); + self::assertSame($responseBody, $response->getBody()->getContents()); } } diff --git a/tests/Cookie/CookieJarTest.php b/tests/Cookie/CookieJarTest.php index 008ae1cef..873999cf9 100644 --- a/tests/Cookie/CookieJarTest.php +++ b/tests/Cookie/CookieJarTest.php @@ -38,12 +38,12 @@ public function testCreatesFromArray() 'foo' => 'bar', 'baz' => 'bam' ], 'example.com'); - $this->assertCount(2, $jar); + self::assertCount(2, $jar); } public function testEmptyJarIsCountable() { - $this->assertCount(0, new CookieJar()); + self::assertCount(0, new CookieJar()); } public function testGetsCookiesByName() @@ -54,9 +54,9 @@ public function testGetsCookiesByName() } $testCookie = $cookies[0]; - $this->assertEquals($testCookie, $this->jar->getCookieByName($testCookie->getName())); - $this->assertNull($this->jar->getCookieByName("doesnotexist")); - $this->assertNull($this->jar->getCookieByName("")); + self::assertEquals($testCookie, $this->jar->getCookieByName($testCookie->getName())); + self::assertNull($this->jar->getCookieByName("doesnotexist")); + self::assertNull($this->jar->getCookieByName("")); } /** @@ -82,12 +82,12 @@ public function testStoresAndRetrievesCookies() { $cookies = $this->getTestCookies(); foreach ($cookies as $cookie) { - $this->assertTrue($this->jar->setCookie($cookie)); + self::assertTrue($this->jar->setCookie($cookie)); } - $this->assertCount(3, $this->jar); - $this->assertCount(3, $this->jar->getIterator()); - $this->assertEquals($cookies, $this->jar->getIterator()->getArrayCopy()); + self::assertCount(3, $this->jar); + self::assertCount(3, $this->jar->getIterator()); + self::assertEquals($cookies, $this->jar->getIterator()->getArrayCopy()); } public function testRemovesTemporaryCookies() @@ -97,7 +97,7 @@ public function testRemovesTemporaryCookies() $this->jar->setCookie($cookie); } $this->jar->clearSessionCookies(); - $this->assertEquals( + self::assertEquals( [$cookies[1], $cookies[2]], $this->jar->getIterator()->getArrayCopy() ); @@ -111,33 +111,33 @@ public function testRemovesSelectively() // Remove foo.com cookies $this->jar->clear('foo.com'); - $this->assertCount(2, $this->jar); + self::assertCount(2, $this->jar); // Try again, removing no further cookies $this->jar->clear('foo.com'); - $this->assertCount(2, $this->jar); + self::assertCount(2, $this->jar); // Remove bar.com cookies with path of /boo $this->jar->clear('bar.com', '/boo'); - $this->assertCount(1, $this->jar); + self::assertCount(1, $this->jar); // Remove cookie by name $this->jar->clear(null, null, 'test'); - $this->assertCount(0, $this->jar); + self::assertCount(0, $this->jar); } public function testDoesNotAddIncompleteCookies() { - $this->assertFalse($this->jar->setCookie(new SetCookie())); - $this->assertFalse($this->jar->setCookie(new SetCookie([ + self::assertFalse($this->jar->setCookie(new SetCookie())); + self::assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => 'foo' ]))); - $this->assertFalse($this->jar->setCookie(new SetCookie([ + self::assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => false ]))); - $this->assertFalse($this->jar->setCookie(new SetCookie([ + self::assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => true ]))); - $this->assertFalse($this->jar->setCookie(new SetCookie([ + self::assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com' ]))); @@ -145,7 +145,7 @@ public function testDoesNotAddIncompleteCookies() public function testDoesNotAddEmptyCookies() { - $this->assertFalse($this->jar->setCookie(new SetCookie([ + self::assertFalse($this->jar->setCookie(new SetCookie([ 'Name' => '', 'Domain' => 'foo.com', 'Value' => 0 @@ -154,22 +154,22 @@ public function testDoesNotAddEmptyCookies() public function testDoesAddValidCookies() { - $this->assertTrue($this->jar->setCookie(new SetCookie([ + self::assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => '0', 'Domain' => 'foo.com', 'Value' => 0 ]))); - $this->assertTrue($this->jar->setCookie(new SetCookie([ + self::assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com', 'Value' => 0 ]))); - $this->assertTrue($this->jar->setCookie(new SetCookie([ + self::assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com', 'Value' => 0.0 ]))); - $this->assertTrue($this->jar->setCookie(new SetCookie([ + self::assertTrue($this->jar->setCookie(new SetCookie([ 'Name' => 'foo', 'Domain' => 'foo.com', 'Value' => '0' @@ -191,26 +191,26 @@ public function testOverwritesCookiesThatAreOlderOrDiscardable() ]; // Make sure that the discard cookie is overridden with the non-discard - $this->assertTrue($this->jar->setCookie(new SetCookie($data))); - $this->assertCount(1, $this->jar); + self::assertTrue($this->jar->setCookie(new SetCookie($data))); + self::assertCount(1, $this->jar); $data['Discard'] = false; - $this->assertTrue($this->jar->setCookie(new SetCookie($data))); - $this->assertCount(1, $this->jar); + self::assertTrue($this->jar->setCookie(new SetCookie($data))); + self::assertCount(1, $this->jar); $c = $this->jar->getIterator()->getArrayCopy(); - $this->assertFalse($c[0]->getDiscard()); + self::assertFalse($c[0]->getDiscard()); // Make sure it doesn't duplicate the cookie $this->jar->setCookie(new SetCookie($data)); - $this->assertCount(1, $this->jar); + self::assertCount(1, $this->jar); // Make sure the more future-ful expiration date supersede the other $data['Expires'] = time() + 2000; - $this->assertTrue($this->jar->setCookie(new SetCookie($data))); - $this->assertCount(1, $this->jar); + self::assertTrue($this->jar->setCookie(new SetCookie($data))); + self::assertCount(1, $this->jar); $c = $this->jar->getIterator()->getArrayCopy(); - $this->assertNotEquals($t, $c[0]->getExpires()); + self::assertNotEquals($t, $c[0]->getExpires()); } public function testOverwritesCookiesThatHaveChanged() @@ -228,20 +228,20 @@ public function testOverwritesCookiesThatHaveChanged() ]; // Make sure that the discard cookie is overridden with the non-discard - $this->assertTrue($this->jar->setCookie(new SetCookie($data))); + self::assertTrue($this->jar->setCookie(new SetCookie($data))); $data['Value'] = 'boo'; - $this->assertTrue($this->jar->setCookie(new SetCookie($data))); - $this->assertCount(1, $this->jar); + self::assertTrue($this->jar->setCookie(new SetCookie($data))); + self::assertCount(1, $this->jar); // Changing the value plus a parameter also must overwrite the existing one $data['Value'] = 'zoo'; $data['Secure'] = false; - $this->assertTrue($this->jar->setCookie(new SetCookie($data))); - $this->assertCount(1, $this->jar); + self::assertTrue($this->jar->setCookie(new SetCookie($data))); + self::assertCount(1, $this->jar); $c = $this->jar->getIterator()->getArrayCopy(); - $this->assertSame('zoo', $c[0]->getValue()); + self::assertSame('zoo', $c[0]->getValue()); } public function testAddsCookiesFromResponseWithRequest() @@ -251,7 +251,7 @@ public function testAddsCookiesFromResponseWithRequest() ]); $request = new Request('GET', 'http://www.example.com'); $this->jar->extractCookies($request, $response); - $this->assertCount(1, $this->jar); + self::assertCount(1, $this->jar); } public function getMatchingCookiesDataProvider() @@ -316,7 +316,7 @@ public function testReturnsCookiesMatchingRequests($url, $cookies) $request = new Request('GET', $url); $request = $this->jar->withCookieHeader($request); - $this->assertSame($cookies, $request->getHeaderLine('Cookie')); + self::assertSame($cookies, $request->getHeaderLine('Cookie')); } /** @@ -343,13 +343,13 @@ public function testDeletesCookiesByName() foreach ($cookies as $cookie) { $jar->setCookie($cookie); } - $this->assertCount(4, $jar); + self::assertCount(4, $jar); $jar->clear('bar.com', '/boo', 'other'); - $this->assertCount(3, $jar); + self::assertCount(3, $jar); $names = array_map(function (SetCookie $c) { return $c->getName(); }, $jar->getIterator()->getArrayCopy()); - $this->assertSame(['foo', 'test', 'you'], $names); + self::assertSame(['foo', 'test', 'you'], $names); } public function testCanConvertToAndLoadFromArray() @@ -358,12 +358,12 @@ public function testCanConvertToAndLoadFromArray() foreach ($this->getTestCookies() as $cookie) { $jar->setCookie($cookie); } - $this->assertCount(3, $jar); + self::assertCount(3, $jar); $arr = $jar->toArray(); - $this->assertCount(3, $arr); + self::assertCount(3, $arr); $newCookieJar = new CookieJar(false, $arr); - $this->assertCount(3, $newCookieJar); - $this->assertSame($jar->toArray(), $newCookieJar->toArray()); + self::assertCount(3, $newCookieJar); + self::assertSame($jar->toArray(), $newCookieJar->toArray()); } public function testAddsCookiesWithEmptyPathFromResponse() @@ -374,7 +374,7 @@ public function testAddsCookiesWithEmptyPathFromResponse() $request = new Request('GET', 'http://www.example.com'); $this->jar->extractCookies($request, $response); $newRequest = $this->jar->withCookieHeader(new Request('GET', 'http://www.example.com/foo')); - $this->assertTrue($newRequest->hasHeader('Cookie')); + self::assertTrue($newRequest->hasHeader('Cookie')); } public function getCookiePathsDataProvider() @@ -409,8 +409,8 @@ public function testCookiePathWithEmptySetCookiePath($uriPath, $cookiePath) $request = (new Request('GET', $uriPath))->withHeader('Host', 'www.example.com'); $this->jar->extractCookies($request, $response); - $this->assertSame($cookiePath, $this->jar->toArray()[0]['Path']); - $this->assertSame($cookiePath, $this->jar->toArray()[1]['Path']); + self::assertSame($cookiePath, $this->jar->toArray()[0]['Path']); + self::assertSame($cookiePath, $this->jar->toArray()[1]['Path']); } private function futureExpirationDate() diff --git a/tests/Cookie/FileCookieJarTest.php b/tests/Cookie/FileCookieJarTest.php index 4a91c9ab5..6391c2013 100644 --- a/tests/Cookie/FileCookieJarTest.php +++ b/tests/Cookie/FileCookieJarTest.php @@ -29,7 +29,7 @@ public function testValidatesCookieFile() public function testLoadsFromFile() { $jar = new FileCookieJar($this->file); - $this->assertSame([], $jar->getIterator()->getArrayCopy()); + self::assertSame([], $jar->getIterator()->getArrayCopy()); unlink($this->file); } @@ -57,21 +57,21 @@ public function testPersistsToFile($testSaveSessionCookie = false) 'Domain' => 'foo.com', ])); - $this->assertCount(3, $jar); + self::assertCount(3, $jar); unset($jar); // Make sure it wrote to the file $contents = file_get_contents($this->file); - $this->assertNotEmpty($contents); + self::assertNotEmpty($contents); // Load the cookieJar from the file $jar = new FileCookieJar($this->file); if ($testSaveSessionCookie) { - $this->assertCount(3, $jar); + self::assertCount(3, $jar); } else { // Weeds out temporary and session cookies - $this->assertCount(2, $jar); + self::assertCount(2, $jar); } unset($jar); diff --git a/tests/Cookie/SessionCookieJarTest.php b/tests/Cookie/SessionCookieJarTest.php index ea855ba7d..2f29bdc15 100644 --- a/tests/Cookie/SessionCookieJarTest.php +++ b/tests/Cookie/SessionCookieJarTest.php @@ -33,7 +33,7 @@ public function testValidatesCookieSession() public function testLoadsFromSession() { $jar = new SessionCookieJar($this->sessionVar); - $this->assertSame([], $jar->getIterator()->getArrayCopy()); + self::assertSame([], $jar->getIterator()->getArrayCopy()); unset($_SESSION[$this->sessionVar]); } @@ -61,21 +61,21 @@ public function testPersistsToSession($testSaveSessionCookie = false) 'Domain' => 'foo.com', ])); - $this->assertCount(3, $jar); + self::assertCount(3, $jar); unset($jar); // Make sure it wrote to the sessionVar in $_SESSION $contents = $_SESSION[$this->sessionVar]; - $this->assertNotEmpty($contents); + self::assertNotEmpty($contents); // Load the cookieJar from the file $jar = new SessionCookieJar($this->sessionVar); if ($testSaveSessionCookie) { - $this->assertCount(3, $jar); + self::assertCount(3, $jar); } else { // Weeds out temporary and session cookies - $this->assertCount(2, $jar); + self::assertCount(2, $jar); } unset($jar); diff --git a/tests/Cookie/SetCookieTest.php b/tests/Cookie/SetCookieTest.php index 29c837f7d..335e44baa 100644 --- a/tests/Cookie/SetCookieTest.php +++ b/tests/Cookie/SetCookieTest.php @@ -12,20 +12,20 @@ class SetCookieTest extends TestCase public function testInitializesDefaultValues() { $cookie = new SetCookie(); - $this->assertSame('/', $cookie->getPath()); + self::assertSame('/', $cookie->getPath()); } public function testConvertsDateTimeMaxAgeToUnixTimestamp() { $cookie = new SetCookie(['Expires' => 'November 20, 1984']); - $this->assertInternalType('integer', $cookie->getExpires()); + self::assertInternalType('integer', $cookie->getExpires()); } public function testAddsExpiresBasedOnMaxAge() { $t = time(); $cookie = new SetCookie(['Max-Age' => 100]); - $this->assertEquals($t + 100, $cookie->getExpires()); + self::assertEquals($t + 100, $cookie->getExpires()); } public function testHoldsValues() @@ -46,19 +46,19 @@ public function testHoldsValues() ]; $cookie = new SetCookie($data); - $this->assertEquals($data, $cookie->toArray()); + self::assertEquals($data, $cookie->toArray()); - $this->assertSame('foo', $cookie->getName()); - $this->assertSame('baz', $cookie->getValue()); - $this->assertSame('baz.com', $cookie->getDomain()); - $this->assertSame('/bar', $cookie->getPath()); - $this->assertSame($t, $cookie->getExpires()); - $this->assertSame(100, $cookie->getMaxAge()); - $this->assertTrue($cookie->getSecure()); - $this->assertTrue($cookie->getDiscard()); - $this->assertTrue($cookie->getHttpOnly()); - $this->assertSame('baz', $cookie->toArray()['foo']); - $this->assertSame('bam', $cookie->toArray()['bar']); + self::assertSame('foo', $cookie->getName()); + self::assertSame('baz', $cookie->getValue()); + self::assertSame('baz.com', $cookie->getDomain()); + self::assertSame('/bar', $cookie->getPath()); + self::assertSame($t, $cookie->getExpires()); + self::assertSame(100, $cookie->getMaxAge()); + self::assertTrue($cookie->getSecure()); + self::assertTrue($cookie->getDiscard()); + self::assertTrue($cookie->getHttpOnly()); + self::assertSame('baz', $cookie->toArray()['foo']); + self::assertSame('bam', $cookie->toArray()['bar']); $cookie->setName('a'); $cookie->setValue('b'); @@ -70,55 +70,55 @@ public function testHoldsValues() $cookie->setHttpOnly(false); $cookie->setDiscard(false); - $this->assertSame('a', $cookie->getName()); - $this->assertSame('b', $cookie->getValue()); - $this->assertSame('c', $cookie->getPath()); - $this->assertSame('bar.com', $cookie->getDomain()); - $this->assertSame(10, $cookie->getExpires()); - $this->assertSame(200, $cookie->getMaxAge()); - $this->assertFalse($cookie->getSecure()); - $this->assertFalse($cookie->getDiscard()); - $this->assertFalse($cookie->getHttpOnly()); + self::assertSame('a', $cookie->getName()); + self::assertSame('b', $cookie->getValue()); + self::assertSame('c', $cookie->getPath()); + self::assertSame('bar.com', $cookie->getDomain()); + self::assertSame(10, $cookie->getExpires()); + self::assertSame(200, $cookie->getMaxAge()); + self::assertFalse($cookie->getSecure()); + self::assertFalse($cookie->getDiscard()); + self::assertFalse($cookie->getHttpOnly()); } public function testDeterminesIfExpired() { $c = new SetCookie(); $c->setExpires(10); - $this->assertTrue($c->isExpired()); + self::assertTrue($c->isExpired()); $c->setExpires(time() + 10000); - $this->assertFalse($c->isExpired()); + self::assertFalse($c->isExpired()); } public function testMatchesDomain() { $cookie = new SetCookie(); - $this->assertTrue($cookie->matchesDomain('baz.com')); + self::assertTrue($cookie->matchesDomain('baz.com')); $cookie->setDomain('baz.com'); - $this->assertTrue($cookie->matchesDomain('baz.com')); - $this->assertFalse($cookie->matchesDomain('bar.com')); + self::assertTrue($cookie->matchesDomain('baz.com')); + self::assertFalse($cookie->matchesDomain('bar.com')); $cookie->setDomain('.baz.com'); - $this->assertTrue($cookie->matchesDomain('.baz.com')); - $this->assertTrue($cookie->matchesDomain('foo.baz.com')); - $this->assertFalse($cookie->matchesDomain('baz.bar.com')); - $this->assertTrue($cookie->matchesDomain('baz.com')); + self::assertTrue($cookie->matchesDomain('.baz.com')); + self::assertTrue($cookie->matchesDomain('foo.baz.com')); + self::assertFalse($cookie->matchesDomain('baz.bar.com')); + self::assertTrue($cookie->matchesDomain('baz.com')); $cookie->setDomain('.127.0.0.1'); - $this->assertTrue($cookie->matchesDomain('127.0.0.1')); + self::assertTrue($cookie->matchesDomain('127.0.0.1')); $cookie->setDomain('127.0.0.1'); - $this->assertTrue($cookie->matchesDomain('127.0.0.1')); + self::assertTrue($cookie->matchesDomain('127.0.0.1')); $cookie->setDomain('.com.'); - $this->assertFalse($cookie->matchesDomain('baz.com')); + self::assertFalse($cookie->matchesDomain('baz.com')); $cookie->setDomain('.local'); - $this->assertTrue($cookie->matchesDomain('example.local')); + self::assertTrue($cookie->matchesDomain('example.local')); $cookie->setDomain('example.com/'); // malformed domain - $this->assertFalse($cookie->matchesDomain('example.com')); + self::assertFalse($cookie->matchesDomain('example.com')); } public function pathMatchProvider() @@ -149,7 +149,7 @@ public function testMatchesPath($cookiePath, $requestPath, $isMatch) { $cookie = new SetCookie(); $cookie->setPath($cookiePath); - $this->assertSame($isMatch, $cookie->matchesPath($requestPath)); + self::assertSame($isMatch, $cookie->matchesPath($requestPath)); } public function cookieValidateProvider() @@ -173,15 +173,15 @@ public function testValidatesCookies($name, $value, $domain, $result) $cookie = new SetCookie([ 'Name' => $name, 'Value' => $value, - 'Domain' => $domain + 'Domain' => $domain, ]); - $this->assertSame($result, $cookie->validate()); + self::assertSame($result, $cookie->validate()); } public function testDoesNotMatchIp() { $cookie = new SetCookie(['Domain' => '192.168.16.']); - $this->assertFalse($cookie->matchesDomain('192.168.16.121')); + self::assertFalse($cookie->matchesDomain('192.168.16.121')); } public function testConvertsToString() @@ -196,7 +196,7 @@ public function testConvertsToString() 'HttpOnly' => true, 'Secure' => true ]); - $this->assertSame( + self::assertSame( 'test=123; Domain=foo.com; Path=/abc; Expires=Sun, 27 Oct 2013 23:20:08 GMT; Secure; HttpOnly', (string) $cookie ); @@ -380,13 +380,13 @@ public function testParseCookie($cookie, $parsed) if (!empty($parsed)) { foreach ($parsed as $key => $value) { - $this->assertEquals($parsed[$key], $p[$key], 'Comparing ' . $key . ' ' . var_export($value, true) . ' : ' . var_export($parsed, true) . ' | ' . var_export($p, true)); + self::assertEquals($parsed[$key], $p[$key], 'Comparing ' . $key . ' ' . var_export($value, true) . ' : ' . var_export($parsed, true) . ' | ' . var_export($p, true)); } foreach ($p as $key => $value) { - $this->assertEquals($p[$key], $parsed[$key], 'Comparing ' . $key . ' ' . var_export($value, true) . ' : ' . var_export($parsed, true) . ' | ' . var_export($p, true)); + self::assertEquals($p[$key], $parsed[$key], 'Comparing ' . $key . ' ' . var_export($value, true) . ' : ' . var_export($parsed, true) . ' | ' . var_export($p, true)); } } else { - $this->assertSame([ + self::assertSame([ 'Name' => null, 'Value' => null, 'Domain' => null, @@ -437,7 +437,7 @@ public function isExpiredProvider() */ public function testIsExpired($cookie, $expired) { - $this->assertSame( + self::assertSame( $expired, SetCookie::fromString($cookie)->isExpired() ); diff --git a/tests/Exception/ConnectExceptionTest.php b/tests/Exception/ConnectExceptionTest.php index dd5df027b..553af403e 100644 --- a/tests/Exception/ConnectExceptionTest.php +++ b/tests/Exception/ConnectExceptionTest.php @@ -15,11 +15,11 @@ public function testHasNoResponse() $req = new Request('GET', '/'); $prev = new \Exception(); $e = new ConnectException('foo', $req, $prev, ['foo' => 'bar']); - $this->assertSame($req, $e->getRequest()); - $this->assertNull($e->getResponse()); - $this->assertFalse($e->hasResponse()); - $this->assertSame('foo', $e->getMessage()); - $this->assertSame('bar', $e->getHandlerContext()['foo']); - $this->assertSame($prev, $e->getPrevious()); + self::assertSame($req, $e->getRequest()); + self::assertNull($e->getResponse()); + self::assertFalse($e->hasResponse()); + self::assertSame('foo', $e->getMessage()); + self::assertSame('bar', $e->getHandlerContext()['foo']); + self::assertSame($prev, $e->getPrevious()); } } diff --git a/tests/Exception/RequestExceptionTest.php b/tests/Exception/RequestExceptionTest.php index 55c25c6e7..d52a0be80 100644 --- a/tests/Exception/RequestExceptionTest.php +++ b/tests/Exception/RequestExceptionTest.php @@ -17,59 +17,59 @@ public function testHasRequestAndResponse() $req = new Request('GET', '/'); $res = new Response(200); $e = new RequestException('foo', $req, $res); - $this->assertSame($req, $e->getRequest()); - $this->assertSame($res, $e->getResponse()); - $this->assertTrue($e->hasResponse()); - $this->assertSame('foo', $e->getMessage()); + self::assertSame($req, $e->getRequest()); + self::assertSame($res, $e->getResponse()); + self::assertTrue($e->hasResponse()); + self::assertSame('foo', $e->getMessage()); } public function testCreatesGenerateException() { $e = RequestException::create(new Request('GET', '/')); - $this->assertSame('Error completing request', $e->getMessage()); - $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); + self::assertSame('Error completing request', $e->getMessage()); + self::assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); } public function testCreatesClientErrorResponseException() { $e = RequestException::create(new Request('GET', '/'), new Response(400)); - $this->assertContains( + self::assertContains( 'GET /', $e->getMessage() ); - $this->assertContains( + self::assertContains( '400 Bad Request', $e->getMessage() ); - $this->assertInstanceOf('GuzzleHttp\Exception\ClientException', $e); + self::assertInstanceOf('GuzzleHttp\Exception\ClientException', $e); } public function testCreatesServerErrorResponseException() { $e = RequestException::create(new Request('GET', '/'), new Response(500)); - $this->assertContains( + self::assertContains( 'GET /', $e->getMessage() ); - $this->assertContains( + self::assertContains( '500 Internal Server Error', $e->getMessage() ); - $this->assertInstanceOf('GuzzleHttp\Exception\ServerException', $e); + self::assertInstanceOf('GuzzleHttp\Exception\ServerException', $e); } public function testCreatesGenericErrorResponseException() { $e = RequestException::create(new Request('GET', '/'), new Response(300)); - $this->assertContains( + self::assertContains( 'GET /', $e->getMessage() ); - $this->assertContains( + self::assertContains( '300 ', $e->getMessage() ); - $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); + self::assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); } /** @@ -104,11 +104,11 @@ public function testCreatesExceptionWithPrintableBodySummary($content) $content ); $e = RequestException::create(new Request('GET', '/'), $response); - $this->assertContains( + self::assertContains( $content, $e->getMessage() ); - $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); + self::assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); } public function testCreatesExceptionWithTruncatedSummary() @@ -117,13 +117,13 @@ public function testCreatesExceptionWithTruncatedSummary() $response = new Response(500, [], $content); $e = RequestException::create(new Request('GET', '/'), $response); $expected = str_repeat('+', 120) . ' (truncated...)'; - $this->assertContains($expected, $e->getMessage()); + self::assertContains($expected, $e->getMessage()); } public function testExceptionMessageIgnoresEmptyBody() { $e = RequestException::create(new Request('GET', '/'), new Response(500)); - $this->assertStringEndsWith('response', $e->getMessage()); + self::assertStringEndsWith('response', $e->getMessage()); } public function testCreatesExceptionWithoutPrintableBody() @@ -134,17 +134,17 @@ public function testCreatesExceptionWithoutPrintableBody() $content = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7') // 1x1 gif ); $e = RequestException::create(new Request('GET', '/'), $response); - $this->assertNotContains( + self::assertNotContains( $content, $e->getMessage() ); - $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); + self::assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); } public function testHasStatusCodeAsExceptionCode() { $e = RequestException::create(new Request('GET', '/'), new Response(442)); - $this->assertSame(442, $e->getCode()); + self::assertSame(442, $e->getCode()); } public function testWrapsRequestExceptions() @@ -152,8 +152,8 @@ public function testWrapsRequestExceptions() $e = new \Exception('foo'); $r = new Request('GET', 'http://www.oo.com'); $ex = RequestException::wrapException($r, $e); - $this->assertInstanceOf('GuzzleHttp\Exception\RequestException', $ex); - $this->assertSame($e, $ex->getPrevious()); + self::assertInstanceOf('GuzzleHttp\Exception\RequestException', $ex); + self::assertSame($e, $ex->getPrevious()); } public function testDoesNotWrapExistingRequestExceptions() @@ -161,33 +161,33 @@ public function testDoesNotWrapExistingRequestExceptions() $r = new Request('GET', 'http://www.oo.com'); $e = new RequestException('foo', $r); $e2 = RequestException::wrapException($r, $e); - $this->assertSame($e, $e2); + self::assertSame($e, $e2); } public function testCanProvideHandlerContext() { $r = new Request('GET', 'http://www.oo.com'); $e = new RequestException('foo', $r, null, null, ['bar' => 'baz']); - $this->assertSame(['bar' => 'baz'], $e->getHandlerContext()); + self::assertSame(['bar' => 'baz'], $e->getHandlerContext()); } public function testObfuscateUrlWithUsername() { $r = new Request('GET', 'http://username@www.oo.com'); $e = RequestException::create($r, new Response(500)); - $this->assertContains('http://username@www.oo.com', $e->getMessage()); + self::assertContains('http://username@www.oo.com', $e->getMessage()); } public function testObfuscateUrlWithUsernameAndPassword() { $r = new Request('GET', 'http://user:password@www.oo.com'); $e = RequestException::create($r, new Response(500)); - $this->assertContains('http://user:***@www.oo.com', $e->getMessage()); + self::assertContains('http://user:***@www.oo.com', $e->getMessage()); } public function testGetResponseBodySummaryOfNonReadableStream() { - $this->assertNull(RequestException::getResponseBodySummary(new Response(500, [], new ReadSeekOnlyStream()))); + self::assertNull(RequestException::getResponseBodySummary(new Response(500, [], new ReadSeekOnlyStream()))); } } diff --git a/tests/Exception/SeekExceptionTest.php b/tests/Exception/SeekExceptionTest.php index 81b7db3b6..f12ac5904 100644 --- a/tests/Exception/SeekExceptionTest.php +++ b/tests/Exception/SeekExceptionTest.php @@ -11,7 +11,7 @@ public function testHasStream() { $s = Psr7\stream_for('foo'); $e = new SeekException($s, 10); - $this->assertSame($s, $e->getStream()); - $this->assertContains('10', $e->getMessage()); + self::assertSame($s, $e->getStream()); + self::assertContains('10', $e->getMessage()); } } diff --git a/tests/Handler/CurlFactoryTest.php b/tests/Handler/CurlFactoryTest.php index 845e7c236..a4cb3c4e9 100644 --- a/tests/Handler/CurlFactoryTest.php +++ b/tests/Handler/CurlFactoryTest.php @@ -43,33 +43,33 @@ public function testCreatesCurlHandle() ], 'testing'); $f = new Handler\CurlFactory(3); $result = $f->create($request, ['sink' => $stream]); - $this->assertInstanceOf(EasyHandle::class, $result); - $this->assertInternalType('resource', $result->handle); - $this->assertInternalType('array', $result->headers); - $this->assertSame($stream, $result->sink); + self::assertInstanceOf(EasyHandle::class, $result); + self::assertInternalType('resource', $result->handle); + self::assertInternalType('array', $result->headers); + self::assertSame($stream, $result->sink); curl_close($result->handle); - $this->assertSame('PUT', $_SERVER['_curl'][CURLOPT_CUSTOMREQUEST]); - $this->assertSame( + self::assertSame('PUT', $_SERVER['_curl'][CURLOPT_CUSTOMREQUEST]); + self::assertSame( 'http://127.0.0.1:8126/', $_SERVER['_curl'][CURLOPT_URL] ); // Sends via post fields when the request is small enough - $this->assertSame('testing', $_SERVER['_curl'][CURLOPT_POSTFIELDS]); - $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_RETURNTRANSFER]); - $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_HEADER]); - $this->assertSame(150, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT]); - $this->assertInstanceOf('Closure', $_SERVER['_curl'][CURLOPT_HEADERFUNCTION]); + self::assertSame('testing', $_SERVER['_curl'][CURLOPT_POSTFIELDS]); + self::assertEquals(0, $_SERVER['_curl'][CURLOPT_RETURNTRANSFER]); + self::assertEquals(0, $_SERVER['_curl'][CURLOPT_HEADER]); + self::assertSame(150, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT]); + self::assertInstanceOf('Closure', $_SERVER['_curl'][CURLOPT_HEADERFUNCTION]); if (defined('CURLOPT_PROTOCOLS')) { - $this->assertSame( + self::assertSame( CURLPROTO_HTTP | CURLPROTO_HTTPS, $_SERVER['_curl'][CURLOPT_PROTOCOLS] ); } - $this->assertContains('Expect:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); - $this->assertContains('Accept:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); - $this->assertContains('Content-Type:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); - $this->assertContains('Hi: 123', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); - $this->assertContains('Host: 127.0.0.1:8126', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + self::assertContains('Expect:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + self::assertContains('Accept:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + self::assertContains('Content-Type:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + self::assertContains('Hi: 123', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + self::assertContains('Host: 127.0.0.1:8126', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); } public function testSendsHeadRequests() @@ -79,12 +79,12 @@ public function testSendsHeadRequests() $a = new Handler\CurlMultiHandler(); $response = $a(new Psr7\Request('HEAD', Server::$url), []); $response->wait(); - $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_NOBODY]); + self::assertEquals(true, $_SERVER['_curl'][CURLOPT_NOBODY]); $checks = [CURLOPT_WRITEFUNCTION, CURLOPT_READFUNCTION, CURLOPT_INFILE]; foreach ($checks as $check) { - $this->assertArrayNotHasKey($check, $_SERVER['_curl']); + self::assertArrayNotHasKey($check, $_SERVER['_curl']); } - $this->assertEquals('HEAD', Server::received()[0]->getMethod()); + self::assertEquals('HEAD', Server::received()[0]->getMethod()); } public function testCanAddCustomCurlOptions() @@ -94,7 +94,7 @@ public function testCanAddCustomCurlOptions() $a = new Handler\CurlMultiHandler(); $req = new Psr7\Request('GET', Server::$url); $a($req, ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]]); - $this->assertEquals(10, $_SERVER['_curl'][CURLOPT_LOW_SPEED_LIMIT]); + self::assertEquals(10, $_SERVER['_curl'][CURLOPT_LOW_SPEED_LIMIT]); } public function testCanChangeCurlOptions() @@ -104,7 +104,7 @@ public function testCanChangeCurlOptions() $a = new Handler\CurlMultiHandler(); $req = new Psr7\Request('GET', Server::$url); $a($req, ['curl' => [CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0]]); - $this->assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]); + self::assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]); } /** @@ -121,42 +121,42 @@ public function testCanSetVerifyToFile() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', 'http://foo.com'), ['verify' => __FILE__]); - $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_CAINFO]); - $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); - $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + self::assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_CAINFO]); + self::assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + self::assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); } public function testCanSetVerifyToDir() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', 'http://foo.com'), ['verify' => __DIR__]); - $this->assertEquals(__DIR__, $_SERVER['_curl'][CURLOPT_CAPATH]); - $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); - $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + self::assertEquals(__DIR__, $_SERVER['_curl'][CURLOPT_CAPATH]); + self::assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + self::assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); } public function testAddsVerifyAsTrue() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['verify' => true]); - $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); - $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); - $this->assertArrayNotHasKey(CURLOPT_CAINFO, $_SERVER['_curl']); + self::assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + self::assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + self::assertArrayNotHasKey(CURLOPT_CAINFO, $_SERVER['_curl']); } public function testCanDisableVerify() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['verify' => false]); - $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); - $this->assertEquals(false, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + self::assertEquals(0, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + self::assertEquals(false, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); } public function testAddsProxy() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['proxy' => 'http://bar.com']); - $this->assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]); + self::assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]); } public function testAddsViaScheme() @@ -165,7 +165,7 @@ public function testAddsViaScheme() $f->create(new Psr7\Request('GET', Server::$url), [ 'proxy' => ['http' => 'http://bar.com', 'https' => 'https://t'], ]); - $this->assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]); + self::assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]); $this->checkNoProxyForHost('http://test.test.com', ['test.test.com'], false); $this->checkNoProxyForHost('http://test.test.com', ['.test.com'], false); $this->checkNoProxyForHost('http://test.test.com', ['*.test.com'], true); @@ -184,9 +184,9 @@ private function checkNoProxyForHost($url, $noProxy, $assertUseProxy) ], ]); if ($assertUseProxy) { - $this->assertArrayHasKey(CURLOPT_PROXY, $_SERVER['_curl']); + self::assertArrayHasKey(CURLOPT_PROXY, $_SERVER['_curl']); } else { - $this->assertArrayNotHasKey(CURLOPT_PROXY, $_SERVER['_curl']); + self::assertArrayNotHasKey(CURLOPT_PROXY, $_SERVER['_curl']); } } @@ -205,15 +205,15 @@ public function testAddsSslKey() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['ssl_key' => __FILE__]); - $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); + self::assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); } public function testAddsSslKeyWithPassword() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['ssl_key' => [__FILE__, 'test']]); - $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); - $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLKEYPASSWD]); + self::assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); + self::assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLKEYPASSWD]); } public function testAddsSslKeyWhenUsingArraySyntaxButNoPassword() @@ -221,7 +221,7 @@ public function testAddsSslKeyWhenUsingArraySyntaxButNoPassword() $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['ssl_key' => [__FILE__]]); - $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); + self::assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); } /** @@ -238,15 +238,15 @@ public function testAddsCert() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['cert' => __FILE__]); - $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]); + self::assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]); } public function testAddsCertWithPassword() { $f = new Handler\CurlFactory(3); $f->create(new Psr7\Request('GET', Server::$url), ['cert' => [__FILE__, 'test']]); - $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]); - $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLCERTPASSWD]); + self::assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]); + self::assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLCERTPASSWD]); } /** @@ -269,8 +269,8 @@ public function testEmitsDebugInfoToStream() $response->wait(); rewind($res); $output = str_replace("\r", '', stream_get_contents($res)); - $this->assertContains("> HEAD / HTTP/1.1", $output); - $this->assertContains("< HTTP/1.1 200", $output); + self::assertContains("> HEAD / HTTP/1.1", $output); + self::assertContains("< HTTP/1.1 200", $output); fclose($res); } @@ -287,9 +287,9 @@ public function testEmitsProgressToFunction() }, ]); $response->wait(); - $this->assertNotEmpty($called); + self::assertNotEmpty($called); foreach ($called as $call) { - $this->assertCount(4, $call); + self::assertCount(4, $call); } } @@ -313,10 +313,10 @@ public function testDecodesGzippedResponses() $request = new Psr7\Request('GET', Server::$url); $response = $handler($request, ['decode_content' => true]); $response = $response->wait(); - $this->assertEquals('test', (string) $response->getBody()); - $this->assertEquals('', $_SERVER['_curl'][CURLOPT_ENCODING]); + self::assertEquals('test', (string) $response->getBody()); + self::assertEquals('', $_SERVER['_curl'][CURLOPT_ENCODING]); $sent = Server::received()[0]; - $this->assertFalse($sent->hasHeader('Accept-Encoding')); + self::assertFalse($sent->hasHeader('Accept-Encoding')); } public function testReportsOriginalSizeAndContentEncodingAfterDecoding() @@ -326,11 +326,11 @@ public function testReportsOriginalSizeAndContentEncodingAfterDecoding() $request = new Psr7\Request('GET', Server::$url); $response = $handler($request, ['decode_content' => true]); $response = $response->wait(); - $this->assertSame( + self::assertSame( 'gzip', $response->getHeaderLine('x-encoded-content-encoding') ); - $this->assertSame( + self::assertSame( strlen(gzencode('test')), (int) $response->getHeaderLine('x-encoded-content-length') ); @@ -343,12 +343,12 @@ public function testDecodesGzippedResponsesWithHeader() $request = new Psr7\Request('GET', Server::$url, ['Accept-Encoding' => 'gzip']); $response = $handler($request, ['decode_content' => true]); $response = $response->wait(); - $this->assertEquals('gzip', $_SERVER['_curl'][CURLOPT_ENCODING]); + self::assertEquals('gzip', $_SERVER['_curl'][CURLOPT_ENCODING]); $sent = Server::received()[0]; - $this->assertEquals('gzip', $sent->getHeaderLine('Accept-Encoding')); - $this->assertEquals('test', (string) $response->getBody()); - $this->assertFalse($response->hasHeader('content-encoding')); - $this->assertTrue( + self::assertEquals('gzip', $sent->getHeaderLine('Accept-Encoding')); + self::assertEquals('test', (string) $response->getBody()); + self::assertFalse($response->hasHeader('content-encoding')); + self::assertTrue( !$response->hasHeader('content-length') || $response->getHeaderLine('content-length') == $response->getBody()->getSize() ); @@ -362,8 +362,8 @@ public function testDoesNotForceDecode() $response = $handler($request, ['decode_content' => false]); $response = $response->wait(); $sent = Server::received()[0]; - $this->assertFalse($sent->hasHeader('Accept-Encoding')); - $this->assertEquals($content, (string) $response->getBody()); + self::assertFalse($sent->hasHeader('Accept-Encoding')); + self::assertEquals($content, (string) $response->getBody()); } public function testProtocolVersion() @@ -373,7 +373,7 @@ public function testProtocolVersion() $a = new Handler\CurlMultiHandler(); $request = new Psr7\Request('GET', Server::$url, [], null, '1.0'); $a($request, []); - $this->assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]); + self::assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]); } public function testSavesToStream() @@ -388,7 +388,7 @@ public function testSavesToStream() ]); $response->wait(); rewind($stream); - $this->assertEquals('test', stream_get_contents($stream)); + self::assertEquals('test', stream_get_contents($stream)); } public function testSavesToGuzzleStream() @@ -402,7 +402,7 @@ public function testSavesToGuzzleStream() 'sink' => $stream, ]); $response->wait(); - $this->assertEquals('test', (string) $stream); + self::assertEquals('test', (string) $stream); } public function testSavesToFileOnDisk() @@ -416,7 +416,7 @@ public function testSavesToFileOnDisk() 'sink' => $tmpfile, ]); $response->wait(); - $this->assertStringEqualsFile($tmpfile, 'test'); + self::assertStringEqualsFile($tmpfile, 'test'); unlink($tmpfile); } @@ -428,9 +428,9 @@ public function testDoesNotAddMultipleContentLengthHeaders() $response = $handler($request, []); $response->wait(); $sent = Server::received()[0]; - $this->assertEquals(3, $sent->getHeaderLine('Content-Length')); - $this->assertFalse($sent->hasHeader('Transfer-Encoding')); - $this->assertEquals('foo', (string) $sent->getBody()); + self::assertEquals(3, $sent->getHeaderLine('Content-Length')); + self::assertFalse($sent->hasHeader('Transfer-Encoding')); + self::assertEquals('foo', (string) $sent->getBody()); } public function testSendsPostWithNoBodyOrDefaultContentType() @@ -442,9 +442,9 @@ public function testSendsPostWithNoBodyOrDefaultContentType() $response = $handler($request, []); $response->wait(); $received = Server::received()[0]; - $this->assertEquals('POST', $received->getMethod()); - $this->assertFalse($received->hasHeader('content-type')); - $this->assertSame('0', $received->getHeaderLine('content-length')); + self::assertEquals('POST', $received->getMethod()); + self::assertFalse($received->hasHeader('content-type')); + self::assertSame('0', $received->getHeaderLine('content-length')); } /** @@ -488,9 +488,9 @@ public function testRetriesWhenBodyCanBeRewound() $easy = $factory->create($req, []); $res = Handler\CurlFactory::finish($fn, $easy, $factory); $res = $res->wait(); - $this->assertTrue($callHandler); - $this->assertTrue($called); - $this->assertEquals('200', $res->getStatusCode()); + self::assertTrue($callHandler); + self::assertTrue($called); + self::assertEquals('200', $res->getStatusCode()); } /** @@ -509,7 +509,7 @@ public function testFailsWhenRetryMoreThanThreeTimes() $mock = new Handler\MockHandler([$fn, $fn, $fn]); $p = $mock(new Psr7\Request('PUT', Server::$url, [], 'test'), []); $p->wait(false); - $this->assertEquals(3, $call); + self::assertEquals(3, $call); $p->wait(true); } @@ -524,11 +524,11 @@ public function testHandles100Continue() ], 'test'); $handler = new Handler\CurlMultiHandler(); $response = $handler($request, [])->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('OK', $response->getReasonPhrase()); - $this->assertSame('Hello', $response->getHeaderLine('Test')); - $this->assertSame('4', $response->getHeaderLine('Content-Length')); - $this->assertSame('test', (string) $response->getBody()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('OK', $response->getReasonPhrase()); + self::assertSame('Hello', $response->getHeaderLine('Test')); + self::assertSame('4', $response->getHeaderLine('Content-Length')); + self::assertSame('test', (string) $response->getBody()); } /** @@ -558,8 +558,8 @@ public function testAddsTimeouts() 'timeout' => 0.1, 'connect_timeout' => 0.2 ]); - $this->assertEquals(100, $_SERVER['_curl'][CURLOPT_TIMEOUT_MS]); - $this->assertEquals(200, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT_MS]); + self::assertEquals(100, $_SERVER['_curl'][CURLOPT_TIMEOUT_MS]); + self::assertEquals(200, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT_MS]); } public function testAddsStreamingBody() @@ -572,8 +572,8 @@ public function testAddsStreamingBody() ]); $request = new Psr7\Request('PUT', Server::$url, [], $bd); $f->create($request, []); - $this->assertEquals(1, $_SERVER['_curl'][CURLOPT_UPLOAD]); - $this->assertInternalType('callable', $_SERVER['_curl'][CURLOPT_READFUNCTION]); + self::assertEquals(1, $_SERVER['_curl'][CURLOPT_UPLOAD]); + self::assertInternalType('callable', $_SERVER['_curl'][CURLOPT_READFUNCTION]); } /** @@ -595,20 +595,20 @@ public function testClosesIdleHandles() $easy = $f->create($req, []); $h1 = $easy->handle; $f->release($easy); - $this->assertCount(1, $this->readAttribute($f, 'handles')); + self::assertCount(1, self::readAttribute($f, 'handles')); $easy = $f->create($req, []); - $this->assertSame($easy->handle, $h1); + self::assertSame($easy->handle, $h1); $easy2 = $f->create($req, []); $easy3 = $f->create($req, []); $easy4 = $f->create($req, []); $f->release($easy); - $this->assertCount(1, $this->readAttribute($f, 'handles')); + self::assertCount(1, self::readAttribute($f, 'handles')); $f->release($easy2); - $this->assertCount(2, $this->readAttribute($f, 'handles')); + self::assertCount(2, self::readAttribute($f, 'handles')); $f->release($easy3); - $this->assertCount(3, $this->readAttribute($f, 'handles')); + self::assertCount(3, self::readAttribute($f, 'handles')); $f->release($easy4); - $this->assertCount(3, $this->readAttribute($f, 'handles')); + self::assertCount(3, self::readAttribute($f, 'handles')); } /** @@ -654,7 +654,7 @@ public function testSuccessfullyCallsOnHeadersBeforeWritingToSink() $stream = Psr7\stream_for(); $stream = Psr7\FnStream::decorate($stream, [ 'write' => function ($data) use ($stream, &$got) { - $this->assertNotNull($got); + self::assertNotNull($got); return $stream->write($data); } ]); @@ -664,14 +664,14 @@ public function testSuccessfullyCallsOnHeadersBeforeWritingToSink() 'sink' => $stream, 'on_headers' => function (ResponseInterface $res) use (&$got) { $got = $res; - $this->assertEquals('bar', $res->getHeaderLine('X-Foo')); + self::assertEquals('bar', $res->getHeaderLine('X-Foo')); } ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('bar', $response->getHeaderLine('X-Foo')); - $this->assertSame('abc 123', (string) $response->getBody()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('bar', $response->getHeaderLine('X-Foo')); + self::assertSame('abc 123', (string) $response->getBody()); } public function testInvokesOnStatsOnSuccess() @@ -687,18 +687,18 @@ public function testInvokesOnStatsOnSuccess() } ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame(200, $gotStats->getResponse()->getStatusCode()); - $this->assertSame( + self::assertSame(200, $response->getStatusCode()); + self::assertSame(200, $gotStats->getResponse()->getStatusCode()); + self::assertSame( Server::$url, (string) $gotStats->getEffectiveUri() ); - $this->assertSame( + self::assertSame( Server::$url, (string) $gotStats->getRequest()->getUri() ); - $this->assertGreaterThan(0, $gotStats->getTransferTime()); - $this->assertArrayHasKey('appconnect_time', $gotStats->getHandlerStats()); + self::assertGreaterThan(0, $gotStats->getTransferTime()); + self::assertArrayHasKey('appconnect_time', $gotStats->getHandlerStats()); } public function testInvokesOnStatsOnError() @@ -714,25 +714,25 @@ public function testInvokesOnStatsOnError() } ]); $promise->wait(false); - $this->assertFalse($gotStats->hasResponse()); - $this->assertSame( + self::assertFalse($gotStats->hasResponse()); + self::assertSame( 'http://127.0.0.1:123', (string) $gotStats->getEffectiveUri() ); - $this->assertSame( + self::assertSame( 'http://127.0.0.1:123', (string) $gotStats->getRequest()->getUri() ); - $this->assertInternalType('float', $gotStats->getTransferTime()); - $this->assertInternalType('int', $gotStats->getHandlerErrorData()); - $this->assertArrayHasKey('appconnect_time', $gotStats->getHandlerStats()); + self::assertInternalType('float', $gotStats->getTransferTime()); + self::assertInternalType('int', $gotStats->getHandlerErrorData()); + self::assertArrayHasKey('appconnect_time', $gotStats->getHandlerStats()); } public function testRewindsBodyIfPossible() { $body = Psr7\stream_for(str_repeat('x', 1024 * 1024 * 2)); $body->seek(1024 * 1024); - $this->assertSame(1024 * 1024, $body->tell()); + self::assertSame(1024 * 1024, $body->tell()); $req = new Psr7\Request('POST', 'https://www.example.com', [ 'Content-Length' => 1024 * 1024 * 2, @@ -740,7 +740,7 @@ public function testRewindsBodyIfPossible() $factory = new CurlFactory(1); $factory->create($req, []); - $this->assertSame(0, $body->tell()); + self::assertSame(0, $body->tell()); } public function testDoesNotRewindUnseekableBody() @@ -748,7 +748,7 @@ public function testDoesNotRewindUnseekableBody() $body = Psr7\stream_for(str_repeat('x', 1024 * 1024 * 2)); $body->seek(1024 * 1024); $body = new Psr7\NoSeekStream($body); - $this->assertSame(1024 * 1024, $body->tell()); + self::assertSame(1024 * 1024, $body->tell()); $req = new Psr7\Request('POST', 'https://www.example.com', [ 'Content-Length' => 1024 * 1024, @@ -756,7 +756,7 @@ public function testDoesNotRewindUnseekableBody() $factory = new CurlFactory(1); $factory->create($req, []); - $this->assertSame(1024 * 1024, $body->tell()); + self::assertSame(1024 * 1024, $body->tell()); } public function testRelease() @@ -765,6 +765,6 @@ public function testRelease() $easyHandle = new EasyHandle(); $easyHandle->handle = curl_init(); - $this->assertEmpty($factory->release($easyHandle)); + self::assertEmpty($factory->release($easyHandle)); } } diff --git a/tests/Handler/CurlHandlerTest.php b/tests/Handler/CurlHandlerTest.php index 6a4d233a0..8bbb81734 100644 --- a/tests/Handler/CurlHandlerTest.php +++ b/tests/Handler/CurlHandlerTest.php @@ -37,8 +37,8 @@ public function testReusesHandles() Server::enqueue([$response, $response]); $a = new CurlHandler(); $request = new Request('GET', Server::$url); - $this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $a($request, [])); - $this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $a($request, [])); + self::assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $a($request, [])); + self::assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $a($request, [])); } public function testDoesSleep() @@ -49,7 +49,7 @@ public function testDoesSleep() $request = new Request('GET', Server::$url); $s = \GuzzleHttp\_current_time(); $a($request, ['delay' => 0.1])->wait(); - $this->assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); + self::assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); } public function testCreatesCurlErrorsWithContext() @@ -60,10 +60,10 @@ public function testCreatesCurlErrorsWithContext() $p = $handler($request, ['timeout' => 0.001, 'connect_timeout' => 0.001]) ->otherwise(function (ConnectException $e) use (&$called) { $called = true; - $this->assertArrayHasKey('errno', $e->getHandlerContext()); + self::assertArrayHasKey('errno', $e->getHandlerContext()); }); $p->wait(); - $this->assertTrue($called); + self::assertTrue($called); } public function testUsesContentLengthWhenOverInMemorySize() @@ -80,7 +80,7 @@ public function testUsesContentLengthWhenOverInMemorySize() ); $handler($request, [])->wait(); $received = Server::received()[0]; - $this->assertEquals(1000000, $received->getHeaderLine('Content-Length')); - $this->assertFalse($received->hasHeader('Transfer-Encoding')); + self::assertEquals(1000000, $received->getHeaderLine('Content-Length')); + self::assertFalse($received->hasHeader('Transfer-Encoding')); } } diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 4a9387633..9db4f5622 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -29,7 +29,7 @@ public function testCanAddCustomCurlOptions() ]]); $request = new Request('GET', Server::$url); $a($request, []); - $this->assertEquals(5, $_SERVER['_curl_multi'][CURLMOPT_MAXCONNECTS]); + self::assertEquals(5, $_SERVER['_curl_multi'][CURLMOPT_MAXCONNECTS]); } public function testSendsRequest() @@ -38,7 +38,7 @@ public function testSendsRequest() $a = new CurlMultiHandler(); $request = new Request('GET', Server::$url); $response = $a($request, [])->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } /** @@ -54,7 +54,7 @@ public function testCreatesExceptions() public function testCanSetSelectTimeout() { $a = new CurlMultiHandler(['select_timeout' => 2]); - $this->assertEquals(2, $this->readAttribute($a, 'selectTimeout')); + self::assertEquals(2, self::readAttribute($a, 'selectTimeout')); } public function testCanCancel() @@ -71,7 +71,7 @@ public function testCanCancel() } foreach ($responses as $r) { - $this->assertSame('rejected', $response->getState()); + self::assertSame('rejected', $response->getState()); } } @@ -83,7 +83,7 @@ public function testCannotCancelFinished() $response = $a(new Request('GET', Server::$url), []); $response->wait(); $response->cancel(); - $this->assertSame('fulfilled', $response->getState()); + self::assertSame('fulfilled', $response->getState()); } public function testDelaysConcurrently() @@ -94,7 +94,7 @@ public function testDelaysConcurrently() $expected = \GuzzleHttp\_current_time() + (100 / 1000); $response = $a(new Request('GET', Server::$url), ['delay' => 100]); $response->wait(); - $this->assertGreaterThanOrEqual($expected, \GuzzleHttp\_current_time()); + self::assertGreaterThanOrEqual($expected, \GuzzleHttp\_current_time()); } public function testUsesTimeoutEnvironmentVariables() @@ -102,13 +102,13 @@ public function testUsesTimeoutEnvironmentVariables() $a = new CurlMultiHandler(); //default if no options are given and no environment variable is set - $this->assertEquals(1, $this->readAttribute($a, 'selectTimeout')); + self::assertEquals(1, self::readAttribute($a, 'selectTimeout')); putenv("GUZZLE_CURL_SELECT_TIMEOUT=3"); $a = new CurlMultiHandler(); $selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT'); //Handler reads from the environment if no options are given - $this->assertEquals($selectTimeout, $this->readAttribute($a, 'selectTimeout')); + self::assertEquals($selectTimeout, self::readAttribute($a, 'selectTimeout')); } /** diff --git a/tests/Handler/MockHandlerTest.php b/tests/Handler/MockHandlerTest.php index 6b3ebe3f4..b63ee46be 100644 --- a/tests/Handler/MockHandlerTest.php +++ b/tests/Handler/MockHandlerTest.php @@ -19,19 +19,19 @@ public function testReturnsMockResponse() $mock = new MockHandler([$res]); $request = new Request('GET', 'http://example.com'); $p = $mock($request, []); - $this->assertSame($res, $p->wait()); + self::assertSame($res, $p->wait()); } public function testIsCountable() { $res = new Response(); $mock = new MockHandler([$res, $res]); - $this->assertCount(2, $mock); + self::assertCount(2, $mock); } public function testEmptyHandlerIsCountable() { - $this->assertCount(0, new MockHandler()); + self::assertCount(0, new MockHandler()); } /** @@ -52,9 +52,9 @@ public function testCanQueueExceptions() $p = $mock($request, []); try { $p->wait(); - $this->fail(); + self::fail(); } catch (\Exception $e2) { - $this->assertSame($e, $e2); + self::assertSame($e, $e2); } } @@ -64,8 +64,8 @@ public function testCanGetLastRequestAndOptions() $mock = new MockHandler([$res]); $request = new Request('GET', 'http://example.com'); $mock($request, ['foo' => 'bar']); - $this->assertSame($request, $mock->getLastRequest()); - $this->assertSame(['foo' => 'bar'], $mock->getLastOptions()); + self::assertSame($request, $mock->getLastRequest()); + self::assertSame(['foo' => 'bar'], $mock->getLastOptions()); } public function testSinkFilename() @@ -77,8 +77,8 @@ public function testSinkFilename() $p = $mock($request, ['sink' => $filename]); $p->wait(); - $this->assertFileExists($filename); - $this->assertStringEqualsFile($filename, 'TEST CONTENT'); + self::assertFileExists($filename); + self::assertStringEqualsFile($filename, 'TEST CONTENT'); unlink($filename); } @@ -93,8 +93,8 @@ public function testSinkResource() $p = $mock($request, ['sink' => $file]); $p->wait(); - $this->assertFileExists($meta['uri']); - $this->assertStringEqualsFile($meta['uri'], 'TEST CONTENT'); + self::assertFileExists($meta['uri']); + self::assertStringEqualsFile($meta['uri'], 'TEST CONTENT'); } public function testSinkStream() @@ -106,8 +106,8 @@ public function testSinkStream() $p = $mock($request, ['sink' => $stream]); $p->wait(); - $this->assertFileExists($stream->getMetadata('uri')); - $this->assertStringEqualsFile($stream->getMetadata('uri'), 'TEST CONTENT'); + self::assertFileExists($stream->getMetadata('uri')); + self::assertStringEqualsFile($stream->getMetadata('uri'), 'TEST CONTENT'); } public function testCanEnqueueCallables() @@ -119,7 +119,7 @@ public function testCanEnqueueCallables() $mock = new MockHandler([$fn]); $request = new Request('GET', 'http://example.com'); $p = $mock($request, ['foo' => 'bar']); - $this->assertSame($r, $p->wait()); + self::assertSame($r, $p->wait()); } /** @@ -159,7 +159,7 @@ public function testInvokesOnFulfilled() }); $request = new Request('GET', 'http://example.com'); $mock($request, [])->wait(); - $this->assertSame($res, $c); + self::assertSame($res, $c); } public function testInvokesOnRejected() @@ -171,7 +171,7 @@ public function testInvokesOnRejected() }); $request = new Request('GET', 'http://example.com'); $mock($request, [])->wait(false); - $this->assertSame($e, $c); + self::assertSame($e, $c); } /** @@ -207,8 +207,8 @@ public function testInvokesOnStatsFunctionForResponse() }; $p = $mock($request, ['on_stats' => $onStats]); $p->wait(); - $this->assertSame($res, $stats->getResponse()); - $this->assertSame($request, $stats->getRequest()); + self::assertSame($res, $stats->getResponse()); + self::assertSame($request, $stats->getRequest()); } public function testInvokesOnStatsFunctionForError() @@ -226,9 +226,9 @@ public function testInvokesOnStatsFunctionForError() $stats = $s; }; $mock($request, ['on_stats' => $onStats])->wait(false); - $this->assertSame($e, $stats->getHandlerErrorData()); - $this->assertNull($stats->getResponse()); - $this->assertSame($request, $stats->getRequest()); + self::assertSame($e, $stats->getHandlerErrorData()); + self::assertNull($stats->getResponse()); + self::assertSame($request, $stats->getRequest()); } public function testTransferTime() @@ -244,18 +244,18 @@ public function testTransferTime() $stats = $s; }; $mock($request, [ 'on_stats' => $onStats, 'transfer_time' => 0.4 ])->wait(false); - $this->assertEquals(0.4, $stats->getTransferTime()); + self::assertEquals(0.4, $stats->getTransferTime()); } public function testResetQueue() { $mock = new MockHandler([new Response(200), new Response(204)]); - $this->assertCount(2, $mock); + self::assertCount(2, $mock); $mock->reset(); - $this->assertEmpty($mock); + self::assertEmpty($mock); $mock->append(new Response(500)); - $this->assertCount(1, $mock); + self::assertCount(1, $mock); } } diff --git a/tests/Handler/ProxyTest.php b/tests/Handler/ProxyTest.php index ea3653f59..c5e8b1e5a 100644 --- a/tests/Handler/ProxyTest.php +++ b/tests/Handler/ProxyTest.php @@ -23,8 +23,8 @@ public function testSendsToNonSync() }]); $h = Proxy::wrapSync($m1, $m2); $h(new Request('GET', 'http://foo.com'), []); - $this->assertNotNull($a); - $this->assertNull($b); + self::assertNotNull($a); + self::assertNull($b); } public function testSendsToSync() @@ -38,8 +38,8 @@ public function testSendsToSync() }]); $h = Proxy::wrapSync($m1, $m2); $h(new Request('GET', 'http://foo.com'), [RequestOptions::SYNCHRONOUS => true]); - $this->assertNull($a); - $this->assertNotNull($b); + self::assertNull($a); + self::assertNotNull($b); } public function testSendsToStreaming() @@ -53,8 +53,8 @@ public function testSendsToStreaming() }]); $h = Proxy::wrapStreaming($m1, $m2); $h(new Request('GET', 'http://foo.com'), []); - $this->assertNotNull($a); - $this->assertNull($b); + self::assertNotNull($a); + self::assertNull($b); } public function testSendsToNonStreaming() @@ -68,7 +68,7 @@ public function testSendsToNonStreaming() }]); $h = Proxy::wrapStreaming($m1, $m2); $h(new Request('GET', 'http://foo.com'), ['stream' => true]); - $this->assertNull($a); - $this->assertNotNull($b); + self::assertNull($a); + self::assertNotNull($b); } } diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index 16ecbfaf7..5571dd844 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -37,16 +37,16 @@ public function testReturnsResponseForSuccessfulRequest() new Request('GET', Server::$url, ['Foo' => 'Bar']), [] )->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('OK', $response->getReasonPhrase()); - $this->assertSame('Bar', $response->getHeaderLine('Foo')); - $this->assertSame('8', $response->getHeaderLine('Content-Length')); - $this->assertSame('hi there', (string) $response->getBody()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('OK', $response->getReasonPhrase()); + self::assertSame('Bar', $response->getHeaderLine('Foo')); + self::assertSame('8', $response->getHeaderLine('Content-Length')); + self::assertSame('hi there', (string) $response->getBody()); $sent = Server::received()[0]; - $this->assertSame('GET', $sent->getMethod()); - $this->assertSame('/', $sent->getUri()->getPath()); - $this->assertSame('127.0.0.1:8126', $sent->getHeaderLine('Host')); - $this->assertSame('Bar', $sent->getHeaderLine('foo')); + self::assertSame('GET', $sent->getMethod()); + self::assertSame('/', $sent->getUri()->getPath()); + self::assertSame('127.0.0.1:8126', $sent->getHeaderLine('Host')); + self::assertSame('Bar', $sent->getHeaderLine('foo')); } /** @@ -72,20 +72,20 @@ public function testStreamAttributeKeepsStreamOpen() 'test' ); $response = $handler($request, ['stream' => true])->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('OK', $response->getReasonPhrase()); - $this->assertSame('8', $response->getHeaderLine('Content-Length')); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('OK', $response->getReasonPhrase()); + self::assertSame('8', $response->getHeaderLine('Content-Length')); $body = $response->getBody(); $stream = $body->detach(); - $this->assertInternalType('resource', $stream); - $this->assertSame('http', stream_get_meta_data($stream)['wrapper_type']); - $this->assertSame('hi there', stream_get_contents($stream)); + self::assertInternalType('resource', $stream); + self::assertSame('http', stream_get_meta_data($stream)['wrapper_type']); + self::assertSame('hi there', stream_get_contents($stream)); fclose($stream); $sent = Server::received()[0]; - $this->assertSame('PUT', $sent->getMethod()); - $this->assertSame('http://127.0.0.1:8126/foo?baz=bar', (string) $sent->getUri()); - $this->assertSame('Bar', $sent->getHeaderLine('Foo')); - $this->assertSame('test', (string) $sent->getBody()); + self::assertSame('PUT', $sent->getMethod()); + self::assertSame('http://127.0.0.1:8126/foo?baz=bar', (string) $sent->getUri()); + self::assertSame('Bar', $sent->getHeaderLine('Foo')); + self::assertSame('test', (string) $sent->getBody()); } public function testDrainsResponseIntoTempStream() @@ -96,8 +96,8 @@ public function testDrainsResponseIntoTempStream() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertSame('php://temp', stream_get_meta_data($stream)['uri']); - $this->assertSame('hi', fread($stream, 2)); + self::assertSame('php://temp', stream_get_meta_data($stream)['uri']); + self::assertSame('hi', fread($stream, 2)); fclose($stream); } @@ -109,9 +109,9 @@ public function testDrainsResponseIntoSaveToBody() $request = new Request('GET', Server::$url); $response = $handler($request, ['sink' => $r])->wait(); $body = $response->getBody()->detach(); - $this->assertSame('php://temp', stream_get_meta_data($body)['uri']); - $this->assertSame('hi', fread($body, 2)); - $this->assertSame(' there', stream_get_contents($r)); + self::assertSame('php://temp', stream_get_meta_data($body)['uri']); + self::assertSame('hi', fread($body, 2)); + self::assertSame(' there', stream_get_contents($r)); fclose($r); } @@ -123,8 +123,8 @@ public function testDrainsResponseIntoSaveToBodyAtPath() $request = new Request('GET', Server::$url); $response = $handler($request, ['sink' => $tmpfname])->wait(); $body = $response->getBody(); - $this->assertSame($tmpfname, $body->getMetadata('uri')); - $this->assertSame('hi', $body->read(2)); + self::assertSame($tmpfname, $body->getMetadata('uri')); + self::assertSame('hi', $body->read(2)); $body->close(); unlink($tmpfname); } @@ -138,8 +138,8 @@ public function testDrainsResponseIntoSaveToBodyAtNonExistentPath() $request = new Request('GET', Server::$url); $response = $handler($request, ['sink' => $tmpfname])->wait(); $body = $response->getBody(); - $this->assertSame($tmpfname, $body->getMetadata('uri')); - $this->assertSame('hi', $body->read(2)); + self::assertSame($tmpfname, $body->getMetadata('uri')); + self::assertSame('hi', $body->read(2)); $body->close(); unlink($tmpfname); } @@ -158,7 +158,7 @@ public function testDrainsResponseAndReadsOnlyContentLengthBytes() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertSame('hi there', stream_get_contents($stream)); + self::assertSame('hi there', stream_get_contents($stream)); fclose($stream); } @@ -177,7 +177,7 @@ public function testDoesNotDrainWhenHeadRequest() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertSame('', stream_get_contents($stream)); + self::assertSame('', stream_get_contents($stream)); fclose($stream); } @@ -194,9 +194,9 @@ public function testAutomaticallyDecompressGzip() $handler = new StreamHandler(); $request = new Request('GET', Server::$url); $response = $handler($request, ['decode_content' => true])->wait(); - $this->assertSame('test', (string) $response->getBody()); - $this->assertFalse($response->hasHeader('content-encoding')); - $this->assertTrue(!$response->hasHeader('content-length') || $response->getHeaderLine('content-length') == $response->getBody()->getSize()); + self::assertSame('test', (string) $response->getBody()); + self::assertFalse($response->hasHeader('content-encoding')); + self::assertTrue(!$response->hasHeader('content-length') || $response->getHeaderLine('content-length') == $response->getBody()->getSize()); } public function testReportsOriginalSizeAndContentEncodingAfterDecoding() @@ -213,11 +213,11 @@ public function testReportsOriginalSizeAndContentEncodingAfterDecoding() $request = new Request('GET', Server::$url); $response = $handler($request, ['decode_content' => true])->wait(); - $this->assertSame( + self::assertSame( 'gzip', $response->getHeaderLine('x-encoded-content-encoding') ); - $this->assertSame( + self::assertSame( strlen($content), (int) $response->getHeaderLine('x-encoded-content-length') ); @@ -236,9 +236,9 @@ public function testDoesNotForceGzipDecode() $handler = new StreamHandler(); $request = new Request('GET', Server::$url); $response = $handler($request, ['decode_content' => false])->wait(); - $this->assertSame($content, (string) $response->getBody()); - $this->assertSame('gzip', $response->getHeaderLine('content-encoding')); - $this->assertEquals(strlen($content), $response->getHeaderLine('content-length')); + self::assertSame($content, (string) $response->getBody()); + self::assertSame('gzip', $response->getHeaderLine('content-encoding')); + self::assertEquals(strlen($content), $response->getHeaderLine('content-length')); } public function testProtocolVersion() @@ -247,7 +247,7 @@ public function testProtocolVersion() $handler = new StreamHandler(); $request = new Request('GET', Server::$url, [], null, '1.0'); $handler($request, []); - $this->assertSame('1.0', Server::received()[0]->getProtocolVersion()); + self::assertSame('1.0', Server::received()[0]->getProtocolVersion()); } protected function getSendResult(array $opts) @@ -275,7 +275,7 @@ public function testAddsProxyByProtocol() $url = rtrim($url, '/'); $res = $this->getSendResult(['proxy' => ['http' => $url]]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertSame($url, $opts['http']['proxy']); + self::assertSame($url, $opts['http']['proxy']); } public function testAddsProxyButHonorsNoProxy() @@ -286,14 +286,14 @@ public function testAddsProxyButHonorsNoProxy() 'no' => ['*'] ]]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertArrayNotHasKey('proxy', $opts['http']); + self::assertArrayNotHasKey('proxy', $opts['http']); } public function testAddsTimeout() { $res = $this->getSendResult(['stream' => true, 'timeout' => 200]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertEquals(200, $opts['http']['timeout']); + self::assertEquals(200, $opts['http']['timeout']); } /** @@ -308,7 +308,7 @@ public function testVerifiesVerifyIsValidIfPath() public function testVerifyCanBeDisabled() { $handler = $this->getSendResult(['verify' => false]); - $this->assertInstanceOf('GuzzleHttp\Psr7\Response', $handler); + self::assertInstanceOf('GuzzleHttp\Psr7\Response', $handler); } /** @@ -325,10 +325,10 @@ public function testVerifyCanBeSetToPath() $path = $path = \GuzzleHttp\default_ca_bundle(); $res = $this->getSendResult(['verify' => $path]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertTrue($opts['ssl']['verify_peer']); - $this->assertTrue($opts['ssl']['verify_peer_name']); - $this->assertSame($path, $opts['ssl']['cafile']); - $this->assertFileExists($opts['ssl']['cafile']); + self::assertTrue($opts['ssl']['verify_peer']); + self::assertTrue($opts['ssl']['verify_peer_name']); + self::assertSame($path, $opts['ssl']['cafile']); + self::assertFileExists($opts['ssl']['cafile']); } public function testUsesSystemDefaultBundle() @@ -337,9 +337,9 @@ public function testUsesSystemDefaultBundle() $res = $this->getSendResult(['verify' => true]); $opts = stream_context_get_options($res->getBody()->detach()); if (PHP_VERSION_ID < 50600) { - $this->assertSame($path, $opts['ssl']['cafile']); + self::assertSame($path, $opts['ssl']['cafile']); } else { - $this->assertArrayNotHasKey('cafile', $opts['ssl']); + self::assertArrayNotHasKey('cafile', $opts['ssl']); } } @@ -357,8 +357,8 @@ public function testCanSetPasswordWhenSettingCert() $path = __FILE__; $res = $this->getSendResult(['cert' => [$path, 'foo']]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertSame($path, $opts['ssl']['local_cert']); - $this->assertSame('foo', $opts['ssl']['passphrase']); + self::assertSame($path, $opts['ssl']['local_cert']); + self::assertSame('foo', $opts['ssl']['passphrase']); } public function testDebugAttributeWritesToStream() @@ -368,9 +368,9 @@ public function testDebugAttributeWritesToStream() $this->getSendResult(['debug' => $f]); fseek($f, 0); $contents = stream_get_contents($f); - $this->assertContains(' [CONNECT]', $contents); - $this->assertContains(' [FILE_SIZE_IS]', $contents); - $this->assertContains(' [PROGRESS]', $contents); + self::assertContains(' [CONNECT]', $contents); + self::assertContains(' [FILE_SIZE_IS]', $contents); + self::assertContains(' [PROGRESS]', $contents); } public function testDebugAttributeWritesStreamInfoToBuffer() @@ -386,10 +386,10 @@ public function testDebugAttributeWritesStreamInfoToBuffer() ]); fseek($buffer, 0); $contents = stream_get_contents($buffer); - $this->assertContains(' [CONNECT]', $contents); - $this->assertContains(' [FILE_SIZE_IS] message: "Content-Length: 8"', $contents); - $this->assertContains(' [PROGRESS] bytes_max: "8"', $contents); - $this->assertTrue($called); + self::assertContains(' [CONNECT]', $contents); + self::assertContains(' [FILE_SIZE_IS] message: "Content-Length: 8"', $contents); + self::assertContains(' [PROGRESS] bytes_max: "8"', $contents); + self::assertTrue($called); } public function testEmitsProgressInformation() @@ -401,9 +401,9 @@ public function testEmitsProgressInformation() $called[] = func_get_args(); }, ]); - $this->assertNotEmpty($called); - $this->assertEquals(8, $called[0][0]); - $this->assertEquals(0, $called[0][1]); + self::assertNotEmpty($called); + self::assertEquals(8, $called[0][0]); + self::assertEquals(0, $called[0][1]); } public function testEmitsProgressInformationAndDebugInformation() @@ -417,11 +417,11 @@ public function testEmitsProgressInformationAndDebugInformation() $called[] = func_get_args(); }, ]); - $this->assertNotEmpty($called); - $this->assertEquals(8, $called[0][0]); - $this->assertEquals(0, $called[0][1]); + self::assertNotEmpty($called); + self::assertEquals(8, $called[0][0]); + self::assertEquals(0, $called[0][1]); rewind($buffer); - $this->assertNotEmpty(stream_get_contents($buffer)); + self::assertNotEmpty(stream_get_contents($buffer)); fclose($buffer); } @@ -442,10 +442,10 @@ public function testPerformsShallowMergeOfCustomContextOptions() ], ]); $opts = stream_context_get_options($res->getBody()->detach()); - $this->assertSame('HEAD', $opts['http']['method']); - $this->assertTrue($opts['http']['request_fulluri']); - $this->assertSame('127.0.0.1:0', $opts['socket']['bindto']); - $this->assertFalse($opts['ssl']['verify_peer']); + self::assertSame('HEAD', $opts['http']['method']); + self::assertTrue($opts['http']['request_fulluri']); + self::assertSame('127.0.0.1:0', $opts['socket']['bindto']); + self::assertFalse($opts['ssl']['verify_peer']); } /** @@ -464,8 +464,8 @@ public function testDoesNotAddContentTypeByDefault() $request = new Request('PUT', Server::$url, ['Content-Length' => 3], 'foo'); $handler($request, []); $req = Server::received()[0]; - $this->assertEquals('', $req->getHeaderLine('Content-Type')); - $this->assertEquals(3, $req->getHeaderLine('Content-Length')); + self::assertEquals('', $req->getHeaderLine('Content-Type')); + self::assertEquals(3, $req->getHeaderLine('Content-Length')); } public function testAddsContentLengthByDefault() @@ -475,7 +475,7 @@ public function testAddsContentLengthByDefault() $request = new Request('PUT', Server::$url, [], 'foo'); $handler($request, []); $req = Server::received()[0]; - $this->assertEquals(3, $req->getHeaderLine('Content-Length')); + self::assertEquals(3, $req->getHeaderLine('Content-Length')); } public function testAddsContentLengthEvenWhenEmpty() @@ -485,7 +485,7 @@ public function testAddsContentLengthEvenWhenEmpty() $request = new Request('PUT', Server::$url, [], ''); $handler($request, []); $req = Server::received()[0]; - $this->assertEquals(0, $req->getHeaderLine('Content-Length')); + self::assertEquals(0, $req->getHeaderLine('Content-Length')); } public function testSupports100Continue() @@ -496,10 +496,10 @@ public function testSupports100Continue() $request = new Request('PUT', Server::$url, ['Expect' => '100-Continue'], 'test'); $handler = new StreamHandler(); $response = $handler($request, [])->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('Hello', $response->getHeaderLine('Test')); - $this->assertSame('4', $response->getHeaderLine('Content-Length')); - $this->assertSame('test', (string) $response->getBody()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('Hello', $response->getHeaderLine('Test')); + self::assertSame('4', $response->getHeaderLine('Content-Length')); + self::assertSame('test', (string) $response->getBody()); } public function testDoesSleep() @@ -510,7 +510,7 @@ public function testDoesSleep() $request = new Request('GET', Server::$url); $s = \GuzzleHttp\_current_time(); $a($request, ['delay' => 0.1])->wait(); - $this->assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); + self::assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); } /** @@ -556,7 +556,7 @@ public function testSuccessfullyCallsOnHeadersBeforeWritingToSink() $stream = Psr7\stream_for(); $stream = FnStream::decorate($stream, [ 'write' => function ($data) use ($stream, &$got) { - $this->assertNotNull($got); + self::assertNotNull($got); return $stream->write($data); } ]); @@ -566,14 +566,14 @@ public function testSuccessfullyCallsOnHeadersBeforeWritingToSink() 'sink' => $stream, 'on_headers' => function (ResponseInterface $res) use (&$got) { $got = $res; - $this->assertSame('bar', $res->getHeaderLine('X-Foo')); + self::assertSame('bar', $res->getHeaderLine('X-Foo')); } ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('bar', $response->getHeaderLine('X-Foo')); - $this->assertSame('abc 123', (string) $response->getBody()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('bar', $response->getHeaderLine('X-Foo')); + self::assertSame('abc 123', (string) $response->getBody()); } public function testInvokesOnStatsOnSuccess() @@ -589,17 +589,17 @@ public function testInvokesOnStatsOnSuccess() } ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame(200, $gotStats->getResponse()->getStatusCode()); - $this->assertSame( + self::assertSame(200, $response->getStatusCode()); + self::assertSame(200, $gotStats->getResponse()->getStatusCode()); + self::assertSame( Server::$url, (string) $gotStats->getEffectiveUri() ); - $this->assertSame( + self::assertSame( Server::$url, (string) $gotStats->getRequest()->getUri() ); - $this->assertGreaterThan(0, $gotStats->getTransferTime()); + self::assertGreaterThan(0, $gotStats->getTransferTime()); } public function testInvokesOnStatsOnError() @@ -615,17 +615,17 @@ public function testInvokesOnStatsOnError() } ]); $promise->wait(false); - $this->assertFalse($gotStats->hasResponse()); - $this->assertSame( + self::assertFalse($gotStats->hasResponse()); + self::assertSame( 'http://127.0.0.1:123', (string) $gotStats->getEffectiveUri() ); - $this->assertSame( + self::assertSame( 'http://127.0.0.1:123', (string) $gotStats->getRequest()->getUri() ); - $this->assertInternalType('float', $gotStats->getTransferTime()); - $this->assertInstanceOf( + self::assertInternalType('float', $gotStats->getTransferTime()); + self::assertInstanceOf( ConnectException::class, $gotStats->getHandlerErrorData() ); @@ -643,7 +643,7 @@ public function testStreamIgnoresZeroTimeout() 'timeout' => 0 ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } public function testDrainsResponseAndReadsAllContentWhenContentLengthIsZero() @@ -660,7 +660,7 @@ public function testDrainsResponseAndReadsAllContentWhenContentLengthIsZero() $response = $handler($request, [])->wait(); $body = $response->getBody(); $stream = $body->detach(); - $this->assertSame('hi there... This has a lot of data!', stream_get_contents($stream)); + self::assertSame('hi there... This has a lot of data!', stream_get_contents($stream)); fclose($stream); } @@ -675,14 +675,14 @@ public function testHonorsReadTimeout() RequestOptions::STREAM => true, ] )->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('OK', $response->getReasonPhrase()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('OK', $response->getReasonPhrase()); $body = $response->getBody()->detach(); $line = fgets($body); - $this->assertSame("sleeping 60 seconds ...\n", $line); + self::assertSame("sleeping 60 seconds ...\n", $line); $line = fgets($body); - $this->assertFalse($line); - $this->assertTrue(stream_get_meta_data($body)['timed_out']); - $this->assertFalse(feof($body)); + self::assertFalse($line); + self::assertTrue(stream_get_meta_data($body)['timed_out']); + self::assertFalse(feof($body)); } } diff --git a/tests/HandlerStackTest.php b/tests/HandlerStackTest.php index 47381dc5d..af7ba8c37 100644 --- a/tests/HandlerStackTest.php +++ b/tests/HandlerStackTest.php @@ -17,7 +17,7 @@ public function testSetsHandlerInCtor() $m1 = function () { }; $h = new HandlerStack($f, [$m1]); - $this->assertTrue($h->hasHandler()); + self::assertTrue($h->hasHandler()); } /** @@ -50,8 +50,8 @@ public function testPushInOrder() $builder->push($meths[3]); $builder->push($meths[4]); $composed = $builder->resolve(); - $this->assertSame('Hello - test123', $composed('test')); - $this->assertSame( + self::assertSame('Hello - test123', $composed('test')); + self::assertSame( [['a', 'test'], ['b', 'test1'], ['c', 'test12']], $meths[0] ); @@ -66,8 +66,8 @@ public function testUnshiftsInReverseOrder() $builder->unshift($meths[3]); $builder->unshift($meths[4]); $composed = $builder->resolve(); - $this->assertSame('Hello - test321', $composed('test')); - $this->assertSame( + self::assertSame('Hello - test321', $composed('test')); + self::assertSame( [['c', 'test'], ['b', 'test3'], ['a', 'test32']], $meths[0] ); @@ -85,7 +85,7 @@ public function testCanRemoveMiddlewareByInstance() $builder->push($meths[2]); $builder->remove($meths[3]); $composed = $builder->resolve(); - $this->assertSame('Hello - test1131', $composed('test')); + self::assertSame('Hello - test1131', $composed('test')); } public function testCanPrintMiddleware() @@ -98,15 +98,15 @@ public function testCanPrintMiddleware() $builder->push([$this, 'bar']); $builder->push(__CLASS__ . '::' . 'foo'); $lines = explode("\n", (string) $builder); - $this->assertContains("> 4) Name: 'a', Function: callable(", $lines[0]); - $this->assertContains("> 3) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[1]); - $this->assertContains("> 2) Name: '', Function: callable(['GuzzleHttp\\Tests\\HandlerStackTest', 'bar'])", $lines[2]); - $this->assertContains("> 1) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[3]); - $this->assertContains("< 0) Handler: callable(", $lines[4]); - $this->assertContains("< 1) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[5]); - $this->assertContains("< 2) Name: '', Function: callable(['GuzzleHttp\\Tests\\HandlerStackTest', 'bar'])", $lines[6]); - $this->assertContains("< 3) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[7]); - $this->assertContains("< 4) Name: 'a', Function: callable(", $lines[8]); + self::assertContains("> 4) Name: 'a', Function: callable(", $lines[0]); + self::assertContains("> 3) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[1]); + self::assertContains("> 2) Name: '', Function: callable(['GuzzleHttp\\Tests\\HandlerStackTest', 'bar'])", $lines[2]); + self::assertContains("> 1) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[3]); + self::assertContains("< 0) Handler: callable(", $lines[4]); + self::assertContains("< 1) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[5]); + self::assertContains("< 2) Name: '', Function: callable(['GuzzleHttp\\Tests\\HandlerStackTest', 'bar'])", $lines[6]); + self::assertContains("< 3) Name: '', Function: callable(GuzzleHttp\\Tests\\HandlerStackTest::foo)", $lines[7]); + self::assertContains("< 4) Name: 'a', Function: callable(", $lines[8]); } public function testCanAddBeforeByName() @@ -119,10 +119,10 @@ public function testCanAddBeforeByName() $builder->before('baz', $meths[4], 'bar'); $builder->before('baz', $meths[4], 'qux'); $lines = explode("\n", (string) $builder); - $this->assertContains('> 4) Name: \'bar\'', $lines[0]); - $this->assertContains('> 3) Name: \'qux\'', $lines[1]); - $this->assertContains('> 2) Name: \'baz\'', $lines[2]); - $this->assertContains('> 1) Name: \'foo\'', $lines[3]); + self::assertContains('> 4) Name: \'bar\'', $lines[0]); + self::assertContains('> 3) Name: \'qux\'', $lines[1]); + self::assertContains('> 2) Name: \'baz\'', $lines[2]); + self::assertContains('> 1) Name: \'foo\'', $lines[3]); } /** @@ -145,10 +145,10 @@ public function testCanAddAfterByName() $builder->after('a', $meths[4], 'c'); $builder->after('b', $meths[4], 'd'); $lines = explode("\n", (string) $builder); - $this->assertContains('4) Name: \'a\'', $lines[0]); - $this->assertContains('3) Name: \'c\'', $lines[1]); - $this->assertContains('2) Name: \'b\'', $lines[2]); - $this->assertContains('1) Name: \'d\'', $lines[3]); + self::assertContains('4) Name: \'a\'', $lines[0]); + self::assertContains('3) Name: \'c\'', $lines[1]); + self::assertContains('2) Name: \'b\'', $lines[2]); + self::assertContains('1) Name: \'d\'', $lines[3]); } public function testPicksUpCookiesFromRedirects() @@ -167,10 +167,10 @@ public function testPicksUpCookiesFromRedirects() 'allow_redirects' => true, 'cookies' => $jar ])->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); $lastRequest = $mock->getLastRequest(); - $this->assertSame('http://foo.com/baz', (string) $lastRequest->getUri()); - $this->assertSame('foo=bar', $lastRequest->getHeaderLine('Cookie')); + self::assertSame('http://foo.com/baz', (string) $lastRequest->getUri()); + self::assertSame('foo=bar', $lastRequest->getHeaderLine('Cookie')); } private function getFunctions() diff --git a/tests/MessageFormatterTest.php b/tests/MessageFormatterTest.php index 301c8f6c1..44d4e5a5d 100644 --- a/tests/MessageFormatterTest.php +++ b/tests/MessageFormatterTest.php @@ -16,9 +16,9 @@ class MessageFormatterTest extends TestCase public function testCreatesWithClfByDefault() { $f = new MessageFormatter(); - $this->assertEquals(MessageFormatter::CLF, $this->readAttribute($f, 'template')); + self::assertEquals(MessageFormatter::CLF, self::readAttribute($f, 'template')); $f = new MessageFormatter(null); - $this->assertEquals(MessageFormatter::CLF, $this->readAttribute($f, 'template')); + self::assertEquals(MessageFormatter::CLF, self::readAttribute($f, 'template')); } public function dateProvider() @@ -38,7 +38,7 @@ public function testFormatsTimestamps($format, $pattern) $f = new MessageFormatter($format); $request = new Request('GET', '/'); $result = $f->format($request); - $this->assertRegExp($pattern, $result); + self::assertRegExp($pattern, $result); } public function formatProvider() @@ -88,6 +88,6 @@ public function formatProvider() public function testFormatsMessages($template, $args, $result) { $f = new MessageFormatter($template); - $this->assertSame((string) $result, call_user_func_array([$f, 'format'], $args)); + self::assertSame((string) $result, call_user_func_array([$f, 'format'], $args)); } } diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 4b9669077..b80888e95 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -37,7 +37,7 @@ function (RequestInterface $request) { ); $f = $m($h); $f(new Request('GET', 'http://foo.com'), ['cookies' => $jar])->wait(); - $this->assertCount(1, $jar); + self::assertCount(1, $jar); } /** @@ -49,9 +49,9 @@ public function testThrowsExceptionOnHttpClientError() $h = new MockHandler([new Response(404)]); $f = $m($h); $p = $f(new Request('GET', 'http://foo.com'), ['http_errors' => true]); - $this->assertSame('pending', $p->getState()); + self::assertSame('pending', $p->getState()); $p->wait(); - $this->assertSame('rejected', $p->getState()); + self::assertSame('rejected', $p->getState()); } /** @@ -63,9 +63,9 @@ public function testThrowsExceptionOnHttpServerError() $h = new MockHandler([new Response(500)]); $f = $m($h); $p = $f(new Request('GET', 'http://foo.com'), ['http_errors' => true]); - $this->assertSame('pending', $p->getState()); + self::assertSame('pending', $p->getState()); $p->wait(); - $this->assertSame('rejected', $p->getState()); + self::assertSame('rejected', $p->getState()); } /** @@ -80,13 +80,13 @@ public function testTracksHistory($container) $p2 = $f(new Request('HEAD', 'http://foo.com'), ['headers' => ['foo' => 'baz']]); $p1->wait(); $p2->wait(); - $this->assertCount(2, $container); - $this->assertSame(200, $container[0]['response']->getStatusCode()); - $this->assertSame(201, $container[1]['response']->getStatusCode()); - $this->assertSame('GET', $container[0]['request']->getMethod()); - $this->assertSame('HEAD', $container[1]['request']->getMethod()); - $this->assertSame('bar', $container[0]['options']['headers']['foo']); - $this->assertSame('baz', $container[1]['options']['headers']['foo']); + self::assertCount(2, $container); + self::assertSame(200, $container[0]['response']->getStatusCode()); + self::assertSame(201, $container[1]['response']->getStatusCode()); + self::assertSame('GET', $container[0]['request']->getMethod()); + self::assertSame('HEAD', $container[1]['request']->getMethod()); + self::assertSame('bar', $container[0]['options']['headers']['foo']); + self::assertSame('baz', $container[1]['options']['headers']['foo']); } public function getHistoryUseCases() @@ -105,9 +105,9 @@ public function testTracksHistoryForFailures() $h = new MockHandler([new RequestException('error', $request)]); $f = $m($h); $f($request, [])->wait(false); - $this->assertCount(1, $container); - $this->assertSame('GET', $container[0]['request']->getMethod()); - $this->assertInstanceOf(RequestException::class, $container[0]['error']); + self::assertCount(1, $container); + self::assertSame('GET', $container[0]['request']->getMethod()); + self::assertInstanceOf(RequestException::class, $container[0]['error']); } public function testTapsBeforeAndAfter() @@ -135,16 +135,16 @@ function (RequestInterface $request, array $options, PromiseInterface $p) use (& $b->push($m); $comp = $b->resolve(); $p = $comp(new Request('GET', 'http://foo.com'), []); - $this->assertSame('123', implode('', $calls)); - $this->assertInstanceOf(PromiseInterface::class, $p); - $this->assertSame(200, $p->wait()->getStatusCode()); + self::assertSame('123', implode('', $calls)); + self::assertInstanceOf(PromiseInterface::class, $p); + self::assertSame(200, $p->wait()->getStatusCode()); } public function testMapsRequest() { $h = new MockHandler([ function (RequestInterface $request, array $options) { - $this->assertSame('foo', $request->getHeaderLine('Bar')); + self::assertSame('foo', $request->getHeaderLine('Bar')); return new Response(200); } ]); @@ -154,7 +154,7 @@ function (RequestInterface $request, array $options) { })); $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); - $this->assertInstanceOf(PromiseInterface::class, $p); + self::assertInstanceOf(PromiseInterface::class, $p); } public function testMapsResponse() @@ -167,7 +167,7 @@ public function testMapsResponse() $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); $p->wait(); - $this->assertSame('foo', $p->wait()->getHeaderLine('Bar')); + self::assertSame('foo', $p->wait()->getHeaderLine('Bar')); } public function testLogsRequestsAndResponses() @@ -180,8 +180,8 @@ public function testLogsRequestsAndResponses() $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); $p->wait(); - $this->assertCount(1, $logger->records); - $this->assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']); + self::assertCount(1, $logger->records); + self::assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']); } public function testLogsRequestsAndResponsesCustomLevel() @@ -194,9 +194,9 @@ public function testLogsRequestsAndResponsesCustomLevel() $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), []); $p->wait(); - $this->assertCount(1, $logger->records); - $this->assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']); - $this->assertSame('debug', $logger->records[0]['level']); + self::assertCount(1, $logger->records); + self::assertContains('"PUT / HTTP/1.1" 200', $logger->records[0]['message']); + self::assertSame('debug', $logger->records[0]['level']); } public function testLogsRequestsAndErrors() @@ -210,8 +210,8 @@ public function testLogsRequestsAndErrors() $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com'), ['http_errors' => true]); $p->wait(false); - $this->assertCount(1, $logger->records); - $this->assertContains('PUT http://www.google.com', $logger->records[0]['message']); - $this->assertContains('404 Not Found', $logger->records[0]['message']); + self::assertCount(1, $logger->records); + self::assertContains('PUT http://www.google.com', $logger->records[0]['message']); + self::assertContains('404 Not Found', $logger->records[0]['message']); } } diff --git a/tests/PoolTest.php b/tests/PoolTest.php index e3f15c510..43a0796e6 100644 --- a/tests/PoolTest.php +++ b/tests/PoolTest.php @@ -81,8 +81,8 @@ function (RequestInterface $request) use (&$h) { $opts = ['options' => ['headers' => ['x-foo' => 'bar']]]; $p = new Pool($c, [new Request('GET', 'http://example.com')], $opts); $p->promise()->wait(); - $this->assertCount(1, $h); - $this->assertTrue($h[0]->hasHeader('x-foo')); + self::assertCount(1, $h); + self::assertTrue($h[0]->hasHeader('x-foo')); } public function testCanProvideCallablesThatReturnResponses() @@ -103,8 +103,8 @@ function (RequestInterface $request) use (&$h) { $opts = ['options' => ['headers' => ['x-foo' => 'bar']]]; $p = new Pool($c, [$fn], $opts); $p->promise()->wait(); - $this->assertCount(1, $h); - $this->assertTrue($h[0]->hasHeader('x-foo')); + self::assertCount(1, $h); + self::assertTrue($h[0]->hasHeader('x-foo')); } public function testBatchesResults() @@ -122,12 +122,12 @@ public function testBatchesResults() $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); $results = Pool::batch($client, $requests); - $this->assertCount(4, $results); - $this->assertSame([0, 1, 2, 3], array_keys($results)); - $this->assertSame(200, $results[0]->getStatusCode()); - $this->assertSame(201, $results[1]->getStatusCode()); - $this->assertSame(202, $results[2]->getStatusCode()); - $this->assertInstanceOf(ClientException::class, $results[3]); + self::assertCount(4, $results); + self::assertSame([0, 1, 2, 3], array_keys($results)); + self::assertSame(200, $results[0]->getStatusCode()); + self::assertSame(201, $results[1]->getStatusCode()); + self::assertSame(202, $results[2]->getStatusCode()); + self::assertInstanceOf(ClientException::class, $results[3]); } public function testBatchesResultsWithCallbacks() @@ -147,8 +147,8 @@ function (RequestInterface $request) { $called = true; } ]); - $this->assertCount(2, $results); - $this->assertTrue($called); + self::assertCount(2, $results); + self::assertTrue($called); } public function testUsesYieldedKeyInFulfilledCallback() @@ -177,8 +177,8 @@ public function testUsesYieldedKeyInFulfilledCallback() } ]); $p->promise()->wait(); - $this->assertCount(3, $keys); - $this->assertSame($keys, array_keys($requests)); + self::assertCount(3, $keys); + self::assertSame($keys, array_keys($requests)); } private function getClient($total = 1) diff --git a/tests/PrepareBodyMiddlewareTest.php b/tests/PrepareBodyMiddlewareTest.php index bff4be003..883c0771c 100644 --- a/tests/PrepareBodyMiddlewareTest.php +++ b/tests/PrepareBodyMiddlewareTest.php @@ -33,9 +33,9 @@ public function testAddsContentLengthWhenMissingAndPossible($method, $body) function (RequestInterface $request) use ($body) { $length = strlen($body); if ($length > 0) { - $this->assertEquals($length, $request->getHeaderLine('Content-Length')); + self::assertEquals($length, $request->getHeaderLine('Content-Length')); } else { - $this->assertFalse($request->hasHeader('Content-Length')); + self::assertFalse($request->hasHeader('Content-Length')); } return new Response(200); } @@ -45,9 +45,9 @@ function (RequestInterface $request) use ($body) { $stack->push($m); $comp = $stack->resolve(); $p = $comp(new Request($method, 'http://www.google.com', [], $body), []); - $this->assertInstanceOf(PromiseInterface::class, $p); + self::assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } public function testAddsTransferEncodingWhenNoContentLength() @@ -59,8 +59,8 @@ public function testAddsTransferEncodingWhenNoContentLength() ]); $h = new MockHandler([ function (RequestInterface $request) { - $this->assertFalse($request->hasHeader('Content-Length')); - $this->assertSame('chunked', $request->getHeaderLine('Transfer-Encoding')); + self::assertFalse($request->hasHeader('Content-Length')); + self::assertSame('chunked', $request->getHeaderLine('Transfer-Encoding')); return new Response(200); } ]); @@ -69,9 +69,9 @@ function (RequestInterface $request) { $stack->push($m); $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com', [], $body), []); - $this->assertInstanceOf(PromiseInterface::class, $p); + self::assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } public function testAddsContentTypeWhenMissingAndPossible() @@ -79,8 +79,8 @@ public function testAddsContentTypeWhenMissingAndPossible() $bd = Psr7\stream_for(fopen(__DIR__ . '/../composer.json', 'r')); $h = new MockHandler([ function (RequestInterface $request) { - $this->assertSame('application/json', $request->getHeaderLine('Content-Type')); - $this->assertTrue($request->hasHeader('Content-Length')); + self::assertSame('application/json', $request->getHeaderLine('Content-Type')); + self::assertTrue($request->hasHeader('Content-Length')); return new Response(200); } ]); @@ -89,9 +89,9 @@ function (RequestInterface $request) { $stack->push($m); $comp = $stack->resolve(); $p = $comp(new Request('PUT', 'http://www.google.com', [], $bd), []); - $this->assertInstanceOf(PromiseInterface::class, $p); + self::assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } public function expectProvider() @@ -113,7 +113,7 @@ public function testAddsExpect($value, $result) $h = new MockHandler([ function (RequestInterface $request) use ($result) { - $this->assertSame($result, $request->getHeader('Expect')); + self::assertSame($result, $request->getHeader('Expect')); return new Response(200); } ]); @@ -125,9 +125,9 @@ function (RequestInterface $request) use ($result) { $p = $comp(new Request('PUT', 'http://www.google.com', [], $bd), [ 'expect' => $value ]); - $this->assertInstanceOf(PromiseInterface::class, $p); + self::assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } public function testIgnoresIfExpectIsPresent() @@ -135,7 +135,7 @@ public function testIgnoresIfExpectIsPresent() $bd = Psr7\stream_for(fopen(__DIR__ . '/../composer.json', 'r')); $h = new MockHandler([ function (RequestInterface $request) { - $this->assertSame(['Foo'], $request->getHeader('Expect')); + self::assertSame(['Foo'], $request->getHeader('Expect')); return new Response(200); } ]); @@ -148,8 +148,8 @@ function (RequestInterface $request) { new Request('PUT', 'http://www.google.com', ['Expect' => 'Foo'], $bd), ['expect' => true] ); - $this->assertInstanceOf(PromiseInterface::class, $p); + self::assertInstanceOf(PromiseInterface::class, $p); $response = $p->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } } diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index e168abd06..e74f713d2 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -25,7 +25,7 @@ public function testIgnoresNonRedirects() $request = new Request('GET', 'http://example.com'); $promise = $handler($request, []); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); + self::assertSame(200, $response->getStatusCode()); } public function testIgnoresWhenNoLocation() @@ -37,7 +37,7 @@ public function testIgnoresWhenNoLocation() $request = new Request('GET', 'http://example.com'); $promise = $handler($request, []); $response = $promise->wait(); - $this->assertSame(304, $response->getStatusCode()); + self::assertSame(304, $response->getStatusCode()); } public function testRedirectsWithAbsoluteUri() @@ -54,8 +54,8 @@ public function testRedirectsWithAbsoluteUri() 'allow_redirects' => ['max' => 2] ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('http://test.com', (string)$mock->getLastRequest()->getUri()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('http://test.com', (string)$mock->getLastRequest()->getUri()); } public function testRedirectsWithRelativeUri() @@ -72,8 +72,8 @@ public function testRedirectsWithRelativeUri() 'allow_redirects' => ['max' => 2] ]); $response = $promise->wait(); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame('http://example.com/foo', (string)$mock->getLastRequest()->getUri()); + self::assertSame(200, $response->getStatusCode()); + self::assertSame('http://example.com/foo', (string)$mock->getLastRequest()->getUri()); } /** @@ -126,7 +126,7 @@ public function testAddsRefererHeader() 'allow_redirects' => ['max' => 2, 'referer' => true] ]); $promise->wait(); - $this->assertSame( + self::assertSame( 'http://example.com?a=b', $mock->getLastRequest()->getHeaderLine('Referer') ); @@ -146,7 +146,7 @@ public function testAddsRefererHeaderButClearsUserInfo() 'allow_redirects' => ['max' => 2, 'referer' => true] ]); $promise->wait(); - $this->assertSame( + self::assertSame( 'http://example.com?a=b', $mock->getLastRequest()->getHeaderLine('Referer') ); @@ -169,7 +169,7 @@ public function testAddsGuzzleRedirectHeader() 'allow_redirects' => ['track_redirects' => true] ]); $response = $promise->wait(true); - $this->assertSame( + self::assertSame( [ 'http://example.com', 'http://example.com/foo', @@ -197,7 +197,7 @@ public function testAddsGuzzleRedirectStatusHeader() 'allow_redirects' => ['track_redirects' => true] ]); $response = $promise->wait(true); - $this->assertSame( + self::assertSame( [ '301', '302', @@ -222,7 +222,7 @@ public function testDoesNotAddRefererWhenGoingFromHttpsToHttp() 'allow_redirects' => ['max' => 2, 'referer' => true] ]); $promise->wait(); - $this->assertFalse($mock->getLastRequest()->hasHeader('Referer')); + self::assertFalse($mock->getLastRequest()->hasHeader('Referer')); } public function testInvokesOnRedirectForRedirects() @@ -240,15 +240,15 @@ public function testInvokesOnRedirectForRedirects() 'allow_redirects' => [ 'max' => 2, 'on_redirect' => function ($request, $response, $uri) use (&$call) { - $this->assertSame(302, $response->getStatusCode()); - $this->assertSame('GET', $request->getMethod()); - $this->assertSame('http://test.com', (string) $uri); + self::assertSame(302, $response->getStatusCode()); + self::assertSame('GET', $request->getMethod()); + self::assertSame('http://test.com', (string) $uri); $call = true; } ] ]); $promise->wait(); - $this->assertTrue($call); + self::assertTrue($call); } public function testRemoveAuthorizationHeaderOnRedirect() @@ -256,7 +256,7 @@ public function testRemoveAuthorizationHeaderOnRedirect() $mock = new MockHandler([ new Response(302, ['Location' => 'http://test.com']), function (RequestInterface $request) { - $this->assertFalse($request->hasHeader('Authorization')); + self::assertFalse($request->hasHeader('Authorization')); return new Response(200); } ]); @@ -270,7 +270,7 @@ public function testNotRemoveAuthorizationHeaderOnRedirect() $mock = new MockHandler([ new Response(302, ['Location' => 'http://example.com/2']), function (RequestInterface $request) { - $this->assertTrue($request->hasHeader('Authorization')); + self::assertTrue($request->hasHeader('Authorization')); return new Response(200); } ]); diff --git a/tests/RetryMiddlewareTest.php b/tests/RetryMiddlewareTest.php index be3e277cd..7297aeb9f 100644 --- a/tests/RetryMiddlewareTest.php +++ b/tests/RetryMiddlewareTest.php @@ -22,8 +22,8 @@ public function testRetriesWhenDeciderReturnsTrue() }; $delay = function ($retries, $response) use (&$delayCalls) { $delayCalls++; - $this->assertSame($retries, $delayCalls); - $this->assertInstanceOf(Response::class, $response); + self::assertSame($retries, $delayCalls); + self::assertInstanceOf(Response::class, $response); return 1; }; $m = Middleware::retry($decider, $delay); @@ -32,9 +32,9 @@ public function testRetriesWhenDeciderReturnsTrue() $c = new Client(['handler' => $f]); $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); $p->wait(); - $this->assertCount(3, $calls); - $this->assertSame(2, $delayCalls); - $this->assertSame(202, $p->wait()->getStatusCode()); + self::assertCount(3, $calls); + self::assertSame(2, $delayCalls); + self::assertSame(202, $p->wait()->getStatusCode()); } public function testDoesNotRetryWhenDeciderReturnsFalse() @@ -46,7 +46,7 @@ public function testDoesNotRetryWhenDeciderReturnsFalse() $h = new MockHandler([new Response(200)]); $c = new Client(['handler' => $m($h)]); $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); - $this->assertSame(200, $p->wait()->getStatusCode()); + self::assertSame(200, $p->wait()->getStatusCode()); } public function testCanRetryExceptions() @@ -60,22 +60,22 @@ public function testCanRetryExceptions() $h = new MockHandler([new \Exception(), new Response(201)]); $c = new Client(['handler' => $m($h)]); $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); - $this->assertSame(201, $p->wait()->getStatusCode()); - $this->assertCount(2, $calls); - $this->assertSame(0, $calls[0][0]); - $this->assertNull($calls[0][2]); - $this->assertInstanceOf('Exception', $calls[0][3]); - $this->assertSame(1, $calls[1][0]); - $this->assertInstanceOf(Response::class, $calls[1][2]); - $this->assertNull($calls[1][3]); + self::assertSame(201, $p->wait()->getStatusCode()); + self::assertCount(2, $calls); + self::assertSame(0, $calls[0][0]); + self::assertNull($calls[0][2]); + self::assertInstanceOf('Exception', $calls[0][3]); + self::assertSame(1, $calls[1][0]); + self::assertInstanceOf(Response::class, $calls[1][2]); + self::assertNull($calls[1][3]); } public function testBackoffCalculateDelay() { - $this->assertSame(0, RetryMiddleware::exponentialDelay(0)); - $this->assertSame(1, RetryMiddleware::exponentialDelay(1)); - $this->assertSame(2, RetryMiddleware::exponentialDelay(2)); - $this->assertSame(4, RetryMiddleware::exponentialDelay(3)); - $this->assertSame(8, RetryMiddleware::exponentialDelay(4)); + self::assertSame(0, RetryMiddleware::exponentialDelay(0)); + self::assertSame(1, RetryMiddleware::exponentialDelay(1)); + self::assertSame(2, RetryMiddleware::exponentialDelay(2)); + self::assertSame(4, RetryMiddleware::exponentialDelay(3)); + self::assertSame(8, RetryMiddleware::exponentialDelay(4)); } } diff --git a/tests/TransferStatsTest.php b/tests/TransferStatsTest.php index 76506fb27..f8bbe5316 100644 --- a/tests/TransferStatsTest.php +++ b/tests/TransferStatsTest.php @@ -18,13 +18,13 @@ public function testHasData() null, ['foo' => 'bar'] ); - $this->assertSame($request, $stats->getRequest()); - $this->assertSame($response, $stats->getResponse()); - $this->assertTrue($stats->hasResponse()); - $this->assertSame(['foo' => 'bar'], $stats->getHandlerStats()); - $this->assertSame('bar', $stats->getHandlerStat('foo')); - $this->assertSame($request->getUri(), $stats->getEffectiveUri()); - $this->assertEquals(10.5, $stats->getTransferTime()); - $this->assertNull($stats->getHandlerErrorData()); + self::assertSame($request, $stats->getRequest()); + self::assertSame($response, $stats->getResponse()); + self::assertTrue($stats->hasResponse()); + self::assertSame(['foo' => 'bar'], $stats->getHandlerStats()); + self::assertSame('bar', $stats->getHandlerStat('foo')); + self::assertSame($request->getUri(), $stats->getEffectiveUri()); + self::assertEquals(10.5, $stats->getTransferTime()); + self::assertNull($stats->getHandlerErrorData()); } } diff --git a/tests/UriTemplateTest.php b/tests/UriTemplateTest.php index 854dbddc1..c06856e91 100644 --- a/tests/UriTemplateTest.php +++ b/tests/UriTemplateTest.php @@ -121,7 +121,7 @@ public function templateProvider() public function testExpandsUriTemplates($template, $expansion, $params) { $uri = new UriTemplate(); - $this->assertSame($expansion, $uri->expand($template, $params)); + self::assertSame($expansion, $uri->expand($template, $params)); } public function expressionProvider() @@ -171,7 +171,7 @@ public function testParsesExpressions($exp, $data) $method->setAccessible(true); $exp = substr($exp, 1, -1); - $this->assertSame($data, $method->invokeArgs($template, [$exp])); + self::assertSame($data, $method->invokeArgs($template, [$exp])); } /** @@ -197,6 +197,6 @@ public function testAllowsNestedArrayExpansion() ] ]); - $this->assertSame('http://example.com/foo/bar/one,two?query=test&more%5B0%5D=fun&more%5B1%5D=ice%20cream&baz%5Bbar%5D=fizz&baz%5Btest%5D=buzz&bam=boo', $result); + self::assertSame('http://example.com/foo/bar/one,two?query=test&more%5B0%5D=fun&more%5B1%5D=ice%20cream&baz%5Bbar%5D=fizz&baz%5Btest%5D=buzz&bam=boo', $result); } } diff --git a/tests/functionsTest.php b/tests/functionsTest.php index bf5c8d8b8..ba93f864d 100644 --- a/tests/functionsTest.php +++ b/tests/functionsTest.php @@ -8,7 +8,7 @@ class FunctionsTest extends TestCase { public function testExpandsTemplate() { - $this->assertSame( + self::assertSame( 'foo/123', GuzzleHttp\uri_template('foo/{bar}', ['bar' => '123']) ); @@ -21,7 +21,7 @@ public function noBodyProvider() public function testProvidesDefaultUserAgent() { $ua = GuzzleHttp\default_user_agent(); - $this->assertRegExp('#^GuzzleHttp/.+ curl/.+ PHP/.+$#', $ua); + self::assertRegExp('#^GuzzleHttp/.+ curl/.+ PHP/.+$#', $ua); } public function typeProvider() @@ -41,13 +41,13 @@ public function typeProvider() */ public function testDescribesType($input, $output) { - $this->assertSame($output, GuzzleHttp\describe_type($input)); + self::assertSame($output, GuzzleHttp\describe_type($input)); } public function testParsesHeadersFromLines() { $lines = ['Foo: bar', 'Foo: baz', 'Abc: 123', 'Def: a, b']; - $this->assertSame([ + self::assertSame([ 'Foo' => ['bar', 'baz'], 'Abc' => ['123'], 'Def' => ['a, b'], @@ -57,19 +57,19 @@ public function testParsesHeadersFromLines() public function testParsesHeadersFromLinesWithMultipleLines() { $lines = ['Foo: bar', 'Foo: baz', 'Foo: 123']; - $this->assertSame([ + self::assertSame([ 'Foo' => ['bar', 'baz', '123'], ], GuzzleHttp\headers_from_lines($lines)); } public function testReturnsDebugResource() { - $this->assertInternalType('resource', GuzzleHttp\debug_resource()); + self::assertInternalType('resource', GuzzleHttp\debug_resource()); } public function testProvidesDefaultCaBundler() { - $this->assertFileExists(GuzzleHttp\default_ca_bundle()); + self::assertFileExists(GuzzleHttp\default_ca_bundle()); } public function noProxyProvider() @@ -89,7 +89,7 @@ public function noProxyProvider() */ public function testChecksNoProxyList($host, $list, $result) { - $this->assertSame( + self::assertSame( $result, \GuzzleHttp\is_host_in_noproxy($host, $list) ); @@ -105,7 +105,7 @@ public function testEnsuresNoProxyCheckHostIsSet() public function testEncodesJson() { - $this->assertSame('true', \GuzzleHttp\json_encode(true)); + self::assertSame('true', \GuzzleHttp\json_encode(true)); } /** @@ -118,7 +118,7 @@ public function testEncodesJsonAndThrowsOnError() public function testDecodesJson() { - $this->assertTrue(\GuzzleHttp\json_decode('true')); + self::assertTrue(\GuzzleHttp\json_decode('true')); } /** @@ -131,7 +131,7 @@ public function testDecodesJsonAndThrowsOnError() public function testCurrentTime() { - $this->assertGreaterThan(0, GuzzleHttp\_current_time()); + self::assertGreaterThan(0, GuzzleHttp\_current_time()); } } From edcdb5d10288830bdbc0ce2718bcbdeb419a6b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Delprat?= Date: Tue, 12 Nov 2019 15:30:46 +0900 Subject: [PATCH 103/141] Update RequestException.php https://www.englishforums.com/English/AUsernameOrAnUsername/pxgzm/post.htm --- src/Exception/RequestException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exception/RequestException.php b/src/Exception/RequestException.php index ca93c1340..12dd081eb 100644 --- a/src/Exception/RequestException.php +++ b/src/Exception/RequestException.php @@ -128,7 +128,7 @@ public static function getResponseBodySummary(ResponseInterface $response) } /** - * Obfuscates URI if there is an username and a password present + * Obfuscates URI if there is a username and a password present * * @param UriInterface $uri * From c189018b02dd53e439810817c91adae47d46d8dc Mon Sep 17 00:00:00 2001 From: Sam Reed Date: Sun, 1 Dec 2019 02:18:59 +0000 Subject: [PATCH 104/141] Update .gitattributes --- .gitattributes | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.gitattributes b/.gitattributes index 3d7f7e351..160a6002c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,12 @@ -.editorconfig export-ignore -.gitattributes export-ignore -/.github/ export-ignore -.gitignore export-ignore -/.travis.yml export-ignore -/build/ export-ignore -/docs/ export-ignore -/Makefile export-ignore -/phpunit.xml.dist export-ignore -/tests/ export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +/.github/ export-ignore +.gitignore export-ignore +/.travis.yml export-ignore +/build/ export-ignore +/docs/ export-ignore +/Makefile export-ignore +/phpstan-baseline.neon export-ignore +/phpstan.neon.dist export-ignore +/phpunit.xml.dist export-ignore +/tests/ export-ignore From 8d1a5f282d6cc24cea24695204e3890cca3f2821 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Sat, 7 Dec 2019 09:41:32 +0100 Subject: [PATCH 105/141] Updated phpstan config for version 0.12.0 (#2419) --- phpstan-baseline.neon | 1309 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1248 insertions(+), 61 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 0a82f4bea..0ce83f754 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,12 +1,30 @@ - - parameters: ignoreErrors: + - + message: "#^Property GuzzleHttp\\\\Client\\:\\:\\$config type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:__construct\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:__call\\(\\) has parameter \\$args with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + - message: "#^Method GuzzleHttp\\\\Client\\:\\:__call\\(\\) should return GuzzleHttp\\\\Promise\\\\PromiseInterface but returns GuzzleHttp\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface\\.$#" count: 1 path: src/Client.php + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:sendAsync\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + - message: "#^Return typehint of method GuzzleHttp\\\\Client\\:\\:sendAsync\\(\\) has invalid type GuzzleHttp\\\\PromiseInterface\\.$#" count: 1 @@ -17,6 +35,11 @@ parameters: count: 1 path: src/Client.php + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:send\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + - message: "#^PHPDoc tag @throws with type GuzzleHttp\\\\GuzzleException is not subtype of Throwable$#" count: 2 @@ -27,6 +50,11 @@ parameters: count: 2 path: src/Client.php + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + - message: "#^Return typehint of method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) has invalid type GuzzleHttp\\\\PromiseInterface\\.$#" count: 1 @@ -37,11 +65,46 @@ parameters: count: 1 path: src/Client.php + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:request\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:buildUri\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:configureDefaults\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + - message: "#^Parameter \\#1 \\$str of function strtolower expects string, int\\|string given\\.$#" count: 1 path: src/Client.php + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:prepareDefaults\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:prepareDefaults\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:transfer\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + + - + message: "#^Method GuzzleHttp\\\\Client\\:\\:applyOptions\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Client.php + - message: "#^Parameter \\#2 \\$prefix of function http_build_query expects string, null given\\.$#" count: 1 @@ -52,6 +115,51 @@ parameters: count: 1 path: src/Client.php + - + message: "#^Method GuzzleHttp\\\\ClientInterface\\:\\:send\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/ClientInterface.php + + - + message: "#^Method GuzzleHttp\\\\ClientInterface\\:\\:sendAsync\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/ClientInterface.php + + - + message: "#^Method GuzzleHttp\\\\ClientInterface\\:\\:request\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/ClientInterface.php + + - + message: "#^Method GuzzleHttp\\\\ClientInterface\\:\\:requestAsync\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/ClientInterface.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:__construct\\(\\) has parameter \\$cookieArray with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:fromArray\\(\\) has parameter \\$cookies with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:fromArray\\(\\) return type has no value type specified in iterable type GuzzleHttp\\\\Cookie\\\\CookieJar\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:getCookieValue\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:getCookieValue\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + - message: "#^Result of \\|\\| is always false\\.$#" count: 1 @@ -62,169 +170,1248 @@ parameters: count: 2 path: src/Cookie/CookieJar.php + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Call to an undefined method Traversable\\\\:\\:getArrayCopy\\(\\)\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:clear\\(\\) return type has no value type specified in iterable type GuzzleHttp\\\\Cookie\\\\CookieJarInterface\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:clear\\(\\) should return GuzzleHttp\\\\Cookie\\\\CookieJarInterface but return statement is missing\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + - message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:clear\\(\\) should return GuzzleHttp\\\\Cookie\\\\CookieJarInterface but empty return statement found\\.$#" count: 1 path: src/Cookie/CookieJar.php + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:clearSessionCookies\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:count\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:getIterator\\(\\) return type has no value type specified in iterable type Traversable\\\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:extractCookies\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + - message: "#^Parameter \\#3 \\$length of function substr expects int, int\\|false given\\.$#" count: 1 path: src/Cookie/CookieJar.php + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:removeCookieIfEmpty\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJar.php + + - + message: "#^Interface GuzzleHttp\\\\Cookie\\\\CookieJarInterface extends generic interface IteratorAggregate but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Cookie/CookieJarInterface.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJarInterface\\:\\:extractCookies\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJarInterface.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJarInterface\\:\\:clear\\(\\) return type has no value type specified in iterable type GuzzleHttp\\\\Cookie\\\\CookieJarInterface\\.$#" + count: 1 + path: src/Cookie/CookieJarInterface.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJarInterface\\:\\:clearSessionCookies\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/CookieJarInterface.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJarInterface\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/CookieJarInterface.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\FileCookieJar\\:\\:save\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/FileCookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\FileCookieJar\\:\\:load\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/FileCookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\SessionCookieJar\\:\\:save\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/SessionCookieJar.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\SessionCookieJar\\:\\:load\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Cookie/SessionCookieJar.php + + - + message: "#^Property GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:\\$defaults type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/SetCookie.php + + - + message: "#^Property GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:\\$data type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/SetCookie.php + + - + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:__construct\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Cookie/SetCookie.php + - message: "#^Property GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:\\$data \\(array\\) does not accept array\\|null\\.$#" count: 1 path: src/Cookie/SetCookie.php - - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" + message: "#^Parameter \\#1 \\$timestamp of method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setExpires\\(\\) expects int, mixed given\\.$#" count: 1 path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$str of function ltrim expects string, string\\|null given\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:toArray\\(\\) has no return typehint specified\\.$#" count: 1 path: src/Cookie/SetCookie.php - - message: "#^Negated boolean expression is always false\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setName\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/CurlFactory.php + path: src/Cookie/SetCookie.php - - message: "#^If condition is always true\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setValue\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/CurlFactory.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$str1 of function strcasecmp expects string, int\\|string given\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setDomain\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/CurlFactory.php + path: src/Cookie/SetCookie.php - - message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$_mh \\(resource\\) does not accept resource\\|false\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setPath\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/CurlMultiHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$mh of function curl_multi_setopt expects resource, resource\\|false given\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setMaxAge\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/CurlMultiHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$status of class GuzzleHttp\\\\Psr7\\\\Response constructor expects int, string given\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setExpires\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/EasyHandle.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#2 \\$parameters of function call_user_func_array expects array\\, array given\\.$#" + message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 1 - path: src/Handler/MockHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Binary operation \"\\*\" between float\\|int\\|string and 1000 results in an error\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setSecure\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/MockHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$status of class GuzzleHttp\\\\Psr7\\\\Response constructor expects int, string given\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setDiscard\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/StreamHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Argument of an invalid type array\\\\>\\|null supplied for foreach, only iterables are supported\\.$#" + message: "#^Method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setHttpOnly\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/Handler/StreamHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#3 \\$use_include_path of function fopen expects bool, null given\\.$#" + message: "#^Parameter \\#1 \\$str of function ltrim expects string, string\\|null given\\.$#" count: 1 - path: src/Handler/StreamHandler.php + path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$stream of function stream_set_timeout expects resource, resource\\|false given\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\BadResponseException\\:\\:__construct\\(\\) has parameter \\$handlerContext with no value type specified in iterable type array\\.$#" count: 1 - path: src/Handler/StreamHandler.php + path: src/Exception/BadResponseException.php - - message: "#^Parameter \\#3 \\$microseconds of function stream_set_timeout expects int, float\\|int given\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\BadResponseException\\:\\:__construct\\(\\) has parameter \\$message with no typehint specified\\.$#" count: 1 - path: src/Handler/StreamHandler.php + path: src/Exception/BadResponseException.php - - message: "#^Parameter \\#1 \\$obj of function spl_object_hash expects object, callable given\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\ConnectException\\:\\:__construct\\(\\) has parameter \\$handlerContext with no value type specified in iterable type array\\.$#" count: 1 - path: src/HandlerStack.php + path: src/Exception/ConnectException.php - - message: "#^Method GuzzleHttp\\\\MessageFormatter\\:\\:format\\(\\) should return string but returns string\\|null\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\ConnectException\\:\\:__construct\\(\\) has parameter \\$message with no typehint specified\\.$#" count: 1 - path: src/MessageFormatter.php + path: src/Exception/ConnectException.php - - message: "#^Result of && is always false\\.$#" + message: "#^Property GuzzleHttp\\\\Exception\\\\RequestException\\:\\:\\$handlerContext type has no value type specified in iterable type array\\.$#" count: 1 - path: src/Middleware.php + path: src/Exception/RequestException.php - - message: "#^Return typehint of method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) has invalid type GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\RequestException\\:\\:__construct\\(\\) has parameter \\$handlerContext with no value type specified in iterable type array\\.$#" count: 1 - path: src/Pool.php + path: src/Exception/RequestException.php - - message: "#^Method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) should return GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\RequestException\\:\\:__construct\\(\\) has parameter \\$message with no typehint specified\\.$#" count: 1 - path: src/Pool.php + path: src/Exception/RequestException.php - - message: "#^Call to method wait\\(\\) on an unknown class GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\RequestException\\:\\:create\\(\\) has parameter \\$ctx with no value type specified in iterable type array\\.$#" count: 1 - path: src/Pool.php + path: src/Exception/RequestException.php - - message: "#^Parameter \\#1 \\$str of function substr expects string, int given\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\RequestException\\:\\:getHandlerContext\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 - path: src/RedirectMiddleware.php + path: src/Exception/RequestException.php - - message: "#^Parameter \\#1 \\$promise of method GuzzleHttp\\\\RedirectMiddleware\\:\\:withTracking\\(\\) expects GuzzleHttp\\\\Promise\\\\PromiseInterface, GuzzleHttp\\\\Promise\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface given\\.$#" + message: "#^Property GuzzleHttp\\\\Exception\\\\SeekException\\:\\:\\$stream has no typehint specified\\.$#" count: 1 - path: src/RedirectMiddleware.php + path: src/Exception/SeekException.php - - message: "#^Parameter \\#2 \\$value of method Psr\\\\Http\\\\Message\\\\MessageInterface\\:\\:withHeader\\(\\) expects array\\\\|string, array given\\.$#" - count: 2 - path: src/RedirectMiddleware.php + message: "#^Method GuzzleHttp\\\\Exception\\\\SeekException\\:\\:__construct\\(\\) has parameter \\$msg with no typehint specified\\.$#" + count: 1 + path: src/Exception/SeekException.php - - message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:doRetry\\(\\) should return GuzzleHttp\\\\RetryMiddleware but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + message: "#^Method GuzzleHttp\\\\Exception\\\\SeekException\\:\\:__construct\\(\\) has parameter \\$pos with no typehint specified\\.$#" count: 1 - path: src/RetryMiddleware.php + path: src/Exception/SeekException.php - - message: "#^Function uri_template not found\\.$#" + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:\\$handles type has no value type specified in iterable type array\\.$#" count: 1 - path: src/functions.php + path: src/Handler/CurlFactory.php - - message: "#^Parameter \\#1 \\$str of function rtrim expects string, string\\|false given\\.$#" + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:create\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 - path: src/functions.php + path: src/Handler/CurlFactory.php - - message: "#^Function GuzzleHttp\\\\debug_resource\\(\\) should return resource but returns resource\\|false\\.$#" + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:release\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/functions.php + path: src/Handler/CurlFactory.php - - message: "#^Parameter \\#1 \\$str of function substr expects string, string\\|null given\\.$#" + message: "#^Negated boolean expression is always false\\.$#" count: 1 - path: src/functions.php + path: src/Handler/CurlFactory.php - - message: "#^Function GuzzleHttp\\\\json_encode\\(\\) should return string but returns string\\|false\\.$#" + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:invokeStats\\(\\) has no return typehint specified\\.$#" count: 1 - path: src/functions.php + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:finishError\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:createRejection\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:createRejection\\(\\) has parameter \\$ctx with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^If condition is always true\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:getDefaultConf\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyMethod\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyMethod\\(\\) has parameter \\$conf with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyBody\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyBody\\(\\) has parameter \\$conf with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyBody\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyHeaders\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyHeaders\\(\\) has parameter \\$conf with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:removeHeader\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:removeHeader\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Parameter \\#1 \\$str1 of function strcasecmp expects string, int\\|string given\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyHandlerOptions\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:applyHandlerOptions\\(\\) has parameter \\$conf with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:retryFailedRewind\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:retryFailedRewind\\(\\) has parameter \\$ctx with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:createHeaderFn\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactoryInterface\\:\\:create\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlFactoryInterface.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactoryInterface\\:\\:release\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlFactoryInterface.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlHandler\\:\\:__construct\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlHandler\\:\\:__invoke\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlHandler\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$selectTimeout has no typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$active has no typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$handles has no typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$delays has no typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$options has no typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__construct\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__get\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__get\\(\\) has parameter \\$name with no typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:\\$_mh \\(resource\\) does not accept resource\\|false\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Parameter \\#1 \\$mh of function curl_multi_setopt expects resource, resource\\|false given\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__invoke\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:tick\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:execute\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:addRequest\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:addRequest\\(\\) has parameter \\$entry with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:processMessages\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\CurlMultiHandler\\:\\:timeToNext\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/CurlMultiHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\EasyHandle\\:\\:\\$headers type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\EasyHandle\\:\\:\\$options type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\EasyHandle\\:\\:createResponse\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Parameter \\#1 \\$status of class GuzzleHttp\\\\Psr7\\\\Response constructor expects int, string given\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\EasyHandle\\:\\:__get\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\EasyHandle\\:\\:__get\\(\\) has parameter \\$name with no typehint specified\\.$#" + count: 1 + path: src/Handler/EasyHandle.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:\\$queue has no typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:\\$lastRequest has no typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:\\$lastOptions has no typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:\\$onFulfilled has no typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:\\$onRejected has no typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:createWithMiddleware\\(\\) has parameter \\$queue with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:__construct\\(\\) has parameter \\$queue with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Parameter \\#2 \\$parameters of function call_user_func_array expects array\\, array given\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:__invoke\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Binary operation \"\\*\" between float\\|int\\|string and 1000 results in an error\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:append\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:getLastOptions\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:reset\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:invokeStats\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:invokeStats\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\MockHandler\\:\\:invokeStats\\(\\) has parameter \\$reason with no typehint specified\\.$#" + count: 1 + path: src/Handler/MockHandler.php + + - + message: "#^Property GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:\\$lastHeaders has no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:invokeStats\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:invokeStats\\(\\) has parameter \\$error with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:invokeStats\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:invokeStats\\(\\) has parameter \\$startTime with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createResponse\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createResponse\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createResponse\\(\\) has parameter \\$startTime with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createResponse\\(\\) has parameter \\$stream with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#1 \\$status of class GuzzleHttp\\\\Psr7\\\\Response constructor expects int, string given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createSink\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createSink\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:checkDecode\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:checkDecode\\(\\) has parameter \\$headers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:checkDecode\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:checkDecode\\(\\) has parameter \\$stream with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Argument of an invalid type array\\\\>\\|null supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createStream\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:createStream\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#3 \\$use_include_path of function fopen expects bool, null given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Parameter \\#1 \\$stream of function stream_set_timeout expects resource, resource\\|false given\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:resolveHost\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:resolveHost\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Cannot access offset 0 on array\\|false\\.$#" + count: 2 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:getDefaultContext\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_proxy\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_proxy\\(\\) has parameter \\$options with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_proxy\\(\\) has parameter \\$params with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_proxy\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_timeout\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_timeout\\(\\) has parameter \\$options with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_timeout\\(\\) has parameter \\$params with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_timeout\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_verify\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_verify\\(\\) has parameter \\$options with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_verify\\(\\) has parameter \\$params with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_verify\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_cert\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_cert\\(\\) has parameter \\$options with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_cert\\(\\) has parameter \\$params with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_cert\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_progress\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_progress\\(\\) has parameter \\$options with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_progress\\(\\) has parameter \\$params with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_progress\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_debug\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_debug\\(\\) has parameter \\$options with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_debug\\(\\) has parameter \\$params with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:add_debug\\(\\) has parameter \\$value with no typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:addNotification\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:addNotification\\(\\) has parameter \\$params with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:callArray\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Method GuzzleHttp\\\\Handler\\\\StreamHandler\\:\\:callArray\\(\\) has parameter \\$functions with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Handler/StreamHandler.php + + - + message: "#^Property GuzzleHttp\\\\HandlerStack\\:\\:\\$stack type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:setHandler\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:unshift\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:push\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:before\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:after\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:remove\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:splice\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\HandlerStack\\:\\:debugCallable\\(\\) has parameter \\$fn with no value type specified in iterable type array\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Parameter \\#1 \\$obj of function spl_object_hash expects object, callable given\\.$#" + count: 1 + path: src/HandlerStack.php + + - + message: "#^Method GuzzleHttp\\\\MessageFormatter\\:\\:format\\(\\) should return string but returns string\\|null\\.$#" + count: 1 + path: src/MessageFormatter.php + + - + message: "#^Method GuzzleHttp\\\\Middleware\\:\\:history\\(\\) has parameter \\$container with generic interface ArrayAccess but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Middleware.php + + - + message: "#^Method GuzzleHttp\\\\Middleware\\:\\:history\\(\\) has parameter \\$container with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Middleware.php + + - + message: "#^Result of && is always false\\.$#" + count: 1 + path: src/Middleware.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:__construct\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:__construct\\(\\) has parameter \\$requests with no value type specified in iterable type array\\|Iterator\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Return typehint of method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) has invalid type GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) should return GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:batch\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:batch\\(\\) has parameter \\$requests with no value type specified in iterable type array\\|Iterator\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:batch\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Call to method wait\\(\\) on an unknown class GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:cmpCallback\\(\\) has parameter \\$name with no typehint specified\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:cmpCallback\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\Pool\\:\\:cmpCallback\\(\\) has parameter \\$results with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Pool.php + + - + message: "#^Method GuzzleHttp\\\\PrepareBodyMiddleware\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/PrepareBodyMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\PrepareBodyMiddleware\\:\\:addExpectHeader\\(\\) has parameter \\$modify with no value type specified in iterable type array\\.$#" + count: 1 + path: src/PrepareBodyMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\PrepareBodyMiddleware\\:\\:addExpectHeader\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/PrepareBodyMiddleware.php + + - + message: "#^Property GuzzleHttp\\\\RedirectMiddleware\\:\\:\\$defaultSettings has no typehint specified\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:checkRedirect\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Parameter \\#1 \\$str of function substr expects string, int given\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Parameter \\#1 \\$promise of method GuzzleHttp\\\\RedirectMiddleware\\:\\:withTracking\\(\\) expects GuzzleHttp\\\\Promise\\\\PromiseInterface, GuzzleHttp\\\\Promise\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface given\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:withTracking\\(\\) has parameter \\$statusCode with no typehint specified\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:withTracking\\(\\) has parameter \\$uri with no typehint specified\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Parameter \\#2 \\$value of method Psr\\\\Http\\\\Message\\\\MessageInterface\\:\\:withHeader\\(\\) expects array\\\\|string, array given\\.$#" + count: 2 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:guardMax\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:modifyRequest\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RedirectMiddleware\\:\\:redirectUri\\(\\) has parameter \\$protocols with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RedirectMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:__invoke\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RetryMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:onFulfilled\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RetryMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:onRejected\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RetryMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:doRetry\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" + count: 1 + path: src/RetryMiddleware.php + + - + message: "#^Method GuzzleHttp\\\\RetryMiddleware\\:\\:doRetry\\(\\) should return GuzzleHttp\\\\RetryMiddleware but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" + count: 1 + path: src/RetryMiddleware.php + + - + message: "#^Property GuzzleHttp\\\\TransferStats\\:\\:\\$request has no typehint specified\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Property GuzzleHttp\\\\TransferStats\\:\\:\\$response has no typehint specified\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Property GuzzleHttp\\\\TransferStats\\:\\:\\$transferTime has no typehint specified\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Property GuzzleHttp\\\\TransferStats\\:\\:\\$handlerStats has no typehint specified\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Property GuzzleHttp\\\\TransferStats\\:\\:\\$handlerErrorData has no typehint specified\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Method GuzzleHttp\\\\TransferStats\\:\\:__construct\\(\\) has parameter \\$handlerStats with no value type specified in iterable type array\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Method GuzzleHttp\\\\TransferStats\\:\\:getHandlerStats\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/TransferStats.php + + - + message: "#^Property GuzzleHttp\\\\UriTemplate\\:\\:\\$variables type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Property GuzzleHttp\\\\UriTemplate\\:\\:\\$operatorHash type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Property GuzzleHttp\\\\UriTemplate\\:\\:\\$delims type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Property GuzzleHttp\\\\UriTemplate\\:\\:\\$delimsPct type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Method GuzzleHttp\\\\UriTemplate\\:\\:expand\\(\\) has no return typehint specified\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Method GuzzleHttp\\\\UriTemplate\\:\\:expand\\(\\) has parameter \\$template with no typehint specified\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Method GuzzleHttp\\\\UriTemplate\\:\\:expand\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Method GuzzleHttp\\\\UriTemplate\\:\\:parseExpression\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Method GuzzleHttp\\\\UriTemplate\\:\\:expandMatch\\(\\) has parameter \\$matches with no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Method GuzzleHttp\\\\UriTemplate\\:\\:isAssoc\\(\\) has parameter \\$array with no value type specified in iterable type array\\.$#" + count: 1 + path: src/UriTemplate.php + + - + message: "#^Function GuzzleHttp\\\\uri_template\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function uri_template not found\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Parameter \\#1 \\$str of function rtrim expects string, string\\|false given\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\headers_from_lines\\(\\) has parameter \\$lines with no value type specified in iterable type iterable\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\headers_from_lines\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\debug_resource\\(\\) should return resource but returns resource\\|false\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\normalize_header_keys\\(\\) has parameter \\$headers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\normalize_header_keys\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\is_host_in_noproxy\\(\\) has parameter \\$noProxyArray with no value type specified in iterable type array\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Cannot access offset 0 on array\\\\|false\\.$#" + count: 1 + path: src/functions.php + + - + message: "#^Function GuzzleHttp\\\\json_encode\\(\\) should return string but returns string\\|false\\.$#" + count: 1 + path: src/functions.php From 1293c1b6c988f87f4c8a8bd8626a58b1b5e4bd0a Mon Sep 17 00:00:00 2001 From: Diego Luces Date: Sat, 7 Dec 2019 00:54:01 -0800 Subject: [PATCH 106/141] Fix RetryMiddleware default exponential delay (#2132) * Fix RetryMiddleware::exponentialDelay by making it return milliseconds RetryMiddleware::exponentialDelay was being used as-is to set the delay option in the retry middleware. However, the option requires milliseconds and this method was returning seconds. * Fix RetryMiddleware::exponentialDelay by making it return milliseconds RetryMiddleware::exponentialDelay was being used as-is to set the delay option in the retry middleware. However, the option requires milliseconds and this method was returning seconds. * Fix exponentialDelay int casting * Added comment --- src/RetryMiddleware.php | 4 ++-- tests/RetryMiddlewareTest.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php index c8d72c200..5acc8c5c3 100644 --- a/src/RetryMiddleware.php +++ b/src/RetryMiddleware.php @@ -47,11 +47,11 @@ public function __construct( * * @param int $retries * - * @return int + * @return int milliseconds. */ public static function exponentialDelay($retries) { - return (int) pow(2, $retries - 1); + return (int) pow(2, $retries - 1) * 1000; } /** diff --git a/tests/RetryMiddlewareTest.php b/tests/RetryMiddlewareTest.php index 7297aeb9f..ed23c32ae 100644 --- a/tests/RetryMiddlewareTest.php +++ b/tests/RetryMiddlewareTest.php @@ -73,9 +73,9 @@ public function testCanRetryExceptions() public function testBackoffCalculateDelay() { self::assertSame(0, RetryMiddleware::exponentialDelay(0)); - self::assertSame(1, RetryMiddleware::exponentialDelay(1)); - self::assertSame(2, RetryMiddleware::exponentialDelay(2)); - self::assertSame(4, RetryMiddleware::exponentialDelay(3)); - self::assertSame(8, RetryMiddleware::exponentialDelay(4)); + self::assertSame(1000, RetryMiddleware::exponentialDelay(1)); + self::assertSame(2000, RetryMiddleware::exponentialDelay(2)); + self::assertSame(4000, RetryMiddleware::exponentialDelay(3)); + self::assertSame(8000, RetryMiddleware::exponentialDelay(4)); } } From 9d4716949a431e55752c7aa37d29566affcd4037 Mon Sep 17 00:00:00 2001 From: Alexey Shokov Date: Sat, 7 Dec 2019 04:28:27 -0500 Subject: [PATCH 107/141] Internationalized domain name (IDN) support (#2286) * Internationalized domain name (IDN) support * Documentation fix * Tests for base_uri * PHPStan and CI fixes * cs --- composer.json | 3 +- docs/request-options.rst | 25 ++++++++++++ phpstan-baseline.neon | 5 --- phpstan.neon.dist | 1 + src/Client.php | 38 +++++++++++++++++- src/RequestOptions.php | 8 ++++ tests/ClientTest.php | 80 +++++++++++++++++++++++++++++++++++++ tests/bootstrap-phpstan.php | 9 +++++ tests/bootstrap.php | 5 +++ 9 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 tests/bootstrap-phpstan.php diff --git a/composer.json b/composer.json index 28f84b003..bbf0ff20b 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,8 @@ "psr/log": "^1.1" }, "suggest": { - "psr/log": "Required for using the Log middleware" + "psr/log": "Required for using the Log middleware", + "ext-intl": "Required for Internationalized Domain Name (IDN) support" }, "config": { "sort-packages": true diff --git a/docs/request-options.rst b/docs/request-options.rst index 14be1dac7..2a477aee9 100644 --- a/docs/request-options.rst +++ b/docs/request-options.rst @@ -553,6 +553,31 @@ http_errors default when creating a handler with ``GuzzleHttp\default_handler``. +idn_conversion +--- + +:Summary: Internationalized Domain Name (IDN) support (enabled by default if + ``intl`` extension is available). +:Types: + - bool + - int +:Default: ``true`` if ``intl`` extension is available, ``false`` otherwise +:Constant: ``GuzzleHttp\RequestOptions::IDN_CONVERSION`` + +.. code-block:: php + + $client->request('GET', 'https://яндекс.рф'); + // яндекс.рф is translated to xn--d1acpjx3f.xn--p1ai before passing it to the handler + + $res = $client->request('GET', 'https://яндекс.рф', ['idn_conversion' => false]); + // The domain part (яндекс.рф) stays unmodified + +Enables/disables IDN support, can also be used for precise control by combining +IDNA_* constants (except IDNA_ERROR_*), see ``$options`` parameter in +`idn_to_ascii() `_ +documentation for more details. + + json ---- diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 0ce83f754..13a72f649 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -110,11 +110,6 @@ parameters: count: 1 path: src/Client.php - - - message: "#^PHPDoc tag @throws with type GuzzleHttp\\\\InvalidArgumentException is not subtype of Throwable$#" - count: 1 - path: src/Client.php - - message: "#^Method GuzzleHttp\\\\ClientInterface\\:\\:send\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 2d83c9846..012c5da5f 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,3 +5,4 @@ parameters: level: max paths: - src + bootstrap: tests/bootstrap-phpstan.php \ No newline at end of file diff --git a/src/Client.php b/src/Client.php index 57a0a75fc..db4062f94 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,6 +2,7 @@ namespace GuzzleHttp; use GuzzleHttp\Cookie\CookieJar; +use GuzzleHttp\Exception\InvalidArgumentException; use GuzzleHttp\Promise; use GuzzleHttp\Psr7; use Psr\Http\Message\RequestInterface; @@ -214,6 +215,38 @@ private function buildUri($uri, array $config) $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); } + if ($uri->getHost() && isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { + $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; + + $asciiHost = idn_to_ascii($uri->getHost(), $idnOptions, INTL_IDNA_VARIANT_UTS46, $info); + if ($asciiHost === false) { + $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; + + $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { + return substr($name, 0, 11) === 'IDNA_ERROR_'; + }); + + $errors = []; + foreach ($errorConstants as $errorConstant) { + if ($errorBitSet & constant($errorConstant)) { + $errors[] = $errorConstant; + } + } + + $errorMessage = 'IDN conversion failed'; + if ($errors) { + $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; + } + + throw new InvalidArgumentException($errorMessage); + } else { + if ($uri->getHost() !== $asciiHost) { + // Replace URI only if the ASCII version is different + $uri = $uri->withHost($asciiHost); + } + } + } + return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; } @@ -233,12 +266,15 @@ private function configureDefaults(array $config) 'cookies' => false ]; + // idn_to_ascii() is a part of ext-intl and might be not available + $defaults['idn_conversion'] = function_exists('idn_to_ascii'); + // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. // We can only trust the HTTP_PROXY environment variable in a CLI // process due to the fact that PHP has no reliable mechanism to // get environment variables that start with "HTTP_". - if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) { + if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) { $defaults['proxy']['http'] = getenv('HTTP_PROXY'); } diff --git a/src/RequestOptions.php b/src/RequestOptions.php index 5c0fd19d3..355f658f0 100644 --- a/src/RequestOptions.php +++ b/src/RequestOptions.php @@ -132,6 +132,14 @@ final class RequestOptions */ const HTTP_ERRORS = 'http_errors'; + /** + * idn: (bool|int, default=true) A combination of IDNA_* constants for + * idn_to_ascii() PHP's function (see "options" parameter). Set to false to + * disable IDN support completely, or to true to use the default + * configuration (IDNA_DEFAULT constant). + */ + const IDN_CONVERSION = 'idn_conversion'; + /** * json: (mixed) Adds JSON data to a request. The provided value is JSON * encoded and a Content-Type header of application/json will be added to diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 05c0d3a7d..771c5e6cb 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -711,4 +711,84 @@ public function testResponseContent() self::assertSame($responseBody, $response->getBody()->getContents()); } + + public function testIdnSupportDefaultValue() + { + $mockHandler = new MockHandler([new Response()]); + $client = new Client(['handler' => $mockHandler]); + + $config = $client->getConfig(); + + if (extension_loaded('intl')) { + self::assertTrue($config['idn_conversion']); + } else { + self::assertFalse($config['idn_conversion']); + } + } + + public function testIdnIsTranslatedToAsciiWhenConversionIsEnabled() + { + if (!extension_loaded('intl')) { + self::markTestSkipped('intl PHP extension is not loaded'); + } + $mockHandler = new MockHandler([new Response()]); + $client = new Client(['handler' => $mockHandler]); + + $client->request('GET', 'https://яндекс.рф/images', ['idn_conversion' => true]); + + $request = $mockHandler->getLastRequest(); + + self::assertSame('https://xn--d1acpjx3f.xn--p1ai/images', (string) $request->getUri()); + self::assertSame('xn--d1acpjx3f.xn--p1ai', (string) $request->getHeaderLine('Host')); + } + + public function testIdnStaysTheSameWhenConversionIsDisabled() + { + $mockHandler = new MockHandler([new Response()]); + $client = new Client(['handler' => $mockHandler]); + + $client->request('GET', 'https://яндекс.рф/images', ['idn_conversion' => false]); + + $request = $mockHandler->getLastRequest(); + + self::assertSame('https://яндекс.рф/images', (string) $request->getUri()); + self::assertSame('яндекс.рф', (string) $request->getHeaderLine('Host')); + } + + /** + * @expectedException \GuzzleHttp\Exception\InvalidArgumentException + * @expectedExceptionMessage IDN conversion failed (errors: IDNA_ERROR_LEADING_HYPHEN) + */ + public function testExceptionOnInvalidIdn() + { + if (!extension_loaded('intl')) { + self::markTestSkipped('intl PHP extension is not loaded'); + } + $mockHandler = new MockHandler([new Response()]); + $client = new Client(['handler' => $mockHandler]); + + $client->request('GET', 'https://-яндекс.рф/images', ['idn_conversion' => true]); + } + + /** + * @depends testCanUseRelativeUriWithSend + * @depends testIdnSupportDefaultValue + */ + public function testIdnBaseUri() + { + if (!extension_loaded('intl')) { + self::markTestSkipped('intl PHP extension is not loaded'); + } + + $mock = new MockHandler([new Response()]); + $client = new Client([ + 'handler' => $mock, + 'base_uri' => 'http://яндекс.рф', + ]); + self::assertSame('http://яндекс.рф', (string) $client->getConfig('base_uri')); + $request = new Request('GET', '/baz'); + $client->send($request); + self::assertSame('http://xn--d1acpjx3f.xn--p1ai/baz', (string) $mock->getLastRequest()->getUri()); + self::assertSame('xn--d1acpjx3f.xn--p1ai', (string) $mock->getLastRequest()->getHeaderLine('Host')); + } } diff --git a/tests/bootstrap-phpstan.php b/tests/bootstrap-phpstan.php new file mode 100644 index 000000000..e91b7419c --- /dev/null +++ b/tests/bootstrap-phpstan.php @@ -0,0 +1,9 @@ + Date: Sat, 7 Dec 2019 19:20:45 +0100 Subject: [PATCH 108/141] Prepare version 6.5 (#2420) * Prepare version 6.5 * Updated date --- CHANGELOG.md | 9 +++++++++ src/ClientInterface.php | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65557498b..342e0b6c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 6.5.0 - 2019-11-07 + +* Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143) +* Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287) +* Fix: Gracefully handle passing `null` to the `header` option. [#2132](https://github.com/guzzle/guzzle/pull/2132) +* Fix: `RetryMiddleware` did not do exponential delay between retires due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132) +* Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348) +* Deprecated `ClientInterface::VERSION` + ## 6.4.1 - 2019-10-23 * No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 24f566bb5..0829b3607 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -15,7 +15,7 @@ interface ClientInterface /** * @deprecated Will be removed in Guzzle 7.0.0 */ - const VERSION = '6.4.1'; + const VERSION = '6.5.0'; /** * Send an HTTP request. From f83124f46fb721ad722b2385423fcee24ad016ff Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sat, 7 Dec 2019 20:28:19 +0000 Subject: [PATCH 109/141] Fixed month in change log (#2422) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 342e0b6c0..90d731439 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## 6.5.0 - 2019-11-07 +## 6.5.0 - 2019-12-07 * Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143) * Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287) From 19964371e8da95dfe021a226c8c4ddcc5c775052 Mon Sep 17 00:00:00 2001 From: Mponos George Date: Wed, 11 Dec 2019 19:52:13 +0200 Subject: [PATCH 110/141] Fix issue 2423 and issue 2448 --- src/Client.php | 31 ++----------------------- src/RedirectMiddleware.php | 10 +++++++-- src/functions.php | 46 ++++++++++++++++++++++++++++++++++++++ tests/ClientTest.php | 34 ++++++++++++++++++++++++++++ tests/functionsTest.php | 11 +++++++++ 5 files changed, 101 insertions(+), 31 deletions(-) diff --git a/src/Client.php b/src/Client.php index db4062f94..fa9fc7a3c 100644 --- a/src/Client.php +++ b/src/Client.php @@ -215,36 +215,9 @@ private function buildUri($uri, array $config) $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); } - if ($uri->getHost() && isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { + if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; - - $asciiHost = idn_to_ascii($uri->getHost(), $idnOptions, INTL_IDNA_VARIANT_UTS46, $info); - if ($asciiHost === false) { - $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; - - $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { - return substr($name, 0, 11) === 'IDNA_ERROR_'; - }); - - $errors = []; - foreach ($errorConstants as $errorConstant) { - if ($errorBitSet & constant($errorConstant)) { - $errors[] = $errorConstant; - } - } - - $errorMessage = 'IDN conversion failed'; - if ($errors) { - $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; - } - - throw new InvalidArgumentException($errorMessage); - } else { - if ($uri->getHost() !== $asciiHost) { - // Replace URI only if the ASCII version is different - $uri = $uri->withHost($asciiHost); - } - } + $uri = _idn_uri_convert($uri, $idnOptions); } return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index 5a0edd572..2f3012618 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -13,7 +13,7 @@ * Request redirect middleware. * * Apply this middleware like other middleware using - * {@see GuzzleHttp\Middleware::redirect()}. + * {@see \GuzzleHttp\Middleware::redirect()}. */ class RedirectMiddleware { @@ -190,7 +190,13 @@ public function modifyRequest( $modify['body'] = ''; } - $modify['uri'] = $this->redirectUri($request, $response, $protocols); + $uri = $this->redirectUri($request, $response, $protocols); + if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { + $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion']; + $uri = _idn_uri_convert($uri, $idnOptions); + } + + $modify['uri'] = $uri; Psr7\rewind_body($request); // Add the Referer header if it is told to do so and only diff --git a/src/functions.php b/src/functions.php index aff69d557..97f9a33ff 100644 --- a/src/functions.php +++ b/src/functions.php @@ -1,10 +1,12 @@ getHost()) { + $variant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; + $asciiHost = idn_to_ascii($uri->getHost(), $options, $variant, $info); + if ($asciiHost === false) { + $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; + + $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { + return substr($name, 0, 11) === 'IDNA_ERROR_'; + }); + + $errors = []; + foreach ($errorConstants as $errorConstant) { + if ($errorBitSet & constant($errorConstant)) { + $errors[] = $errorConstant; + } + } + + $errorMessage = 'IDN conversion failed'; + if ($errors) { + $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; + } + + throw new InvalidArgumentException($errorMessage); + } else { + if ($uri->getHost() !== $asciiHost) { + // Replace URI only if the ASCII version is different + $uri = $uri->withHost($asciiHost); + } + } + } + + return $uri; +} diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 771c5e6cb..bc4ae33b1 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -5,11 +5,13 @@ use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; +use GuzzleHttp\Middleware; use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Uri; +use GuzzleHttp\RequestOptions; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; @@ -791,4 +793,36 @@ public function testIdnBaseUri() self::assertSame('http://xn--d1acpjx3f.xn--p1ai/baz', (string) $mock->getLastRequest()->getUri()); self::assertSame('xn--d1acpjx3f.xn--p1ai', (string) $mock->getLastRequest()->getHeaderLine('Host')); } + + public function testIdnWithRedirect() + { + if (!extension_loaded('intl')) { + self::markTestSkipped('intl PHP extension is not loaded'); + } + $mockHandler = new MockHandler([ + new Response(302, ['Location' => 'http://www.tést.com/whatever']), + new Response() + ]); + $handler = HandlerStack::create($mockHandler); + $requests = []; + $handler->push(Middleware::history($requests)); + $client = new Client(['handler' => $handler]); + + $client->request('GET', 'https://яндекс.рф/images', [ + RequestOptions::ALLOW_REDIRECTS => [ + 'referer' => true, + 'track_redirects' => true + ], + 'idn_conversion' => true + ]); + + $request = $mockHandler->getLastRequest(); + + self::assertSame('http://www.xn--tst-bma.com/whatever', (string) $request->getUri()); + self::assertSame('www.xn--tst-bma.com', (string) $request->getHeaderLine('Host')); + + $request = $requests[0]['request']; + self::assertSame('https://xn--d1acpjx3f.xn--p1ai/images', (string) $request->getUri()); + self::assertSame('xn--d1acpjx3f.xn--p1ai', (string) $request->getHeaderLine('Host')); + } } diff --git a/tests/functionsTest.php b/tests/functionsTest.php index ba93f864d..e07b558e8 100644 --- a/tests/functionsTest.php +++ b/tests/functionsTest.php @@ -133,6 +133,17 @@ public function testCurrentTime() { self::assertGreaterThan(0, GuzzleHttp\_current_time()); } + + public function testIdnConvert() + { + if (!extension_loaded('intl')) { + self::markTestSkipped('intl PHP extension is not loaded'); + } + + $uri = GuzzleHttp\Psr7\uri_for('https://яндекс.рф/images'); + $uri = GuzzleHttp\_idn_uri_convert($uri); + self::assertSame('xn--d1acpjx3f.xn--p1ai', $uri->getHost()); + } } final class StrClass From f2807491d46b25125310c9f216c3e710a504c98c Mon Sep 17 00:00:00 2001 From: Mponos George Date: Wed, 11 Dec 2019 20:32:35 +0200 Subject: [PATCH 111/141] Fix idn according to suggestions from review --- src/functions.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/functions.php b/src/functions.php index 97f9a33ff..4332996b0 100644 --- a/src/functions.php +++ b/src/functions.php @@ -358,8 +358,9 @@ function _current_time() function _idn_uri_convert(UriInterface $uri, $options = 0) { if ($uri->getHost()) { - $variant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; - $asciiHost = idn_to_ascii($uri->getHost(), $options, $variant, $info); + $asciiHost = defined('INTL_IDNA_VARIANT_UTS46') + ? idn_to_ascii($uri->getHost(), $options, INTL_IDNA_VARIANT_UTS46, $info) + : idn_to_ascii($uri->getHost(), $options); if ($asciiHost === false) { $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; From c63379edaad8af790be9e3bbd3d40d4eaae4e30c Mon Sep 17 00:00:00 2001 From: Alexey Shokov Date: Thu, 12 Dec 2019 11:41:39 +0400 Subject: [PATCH 112/141] Better defaults for PHP installations with old ICU lib --- docs/request-options.rst | 2 +- src/Client.php | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/request-options.rst b/docs/request-options.rst index 2a477aee9..4e5117b60 100644 --- a/docs/request-options.rst +++ b/docs/request-options.rst @@ -561,7 +561,7 @@ idn_conversion :Types: - bool - int -:Default: ``true`` if ``intl`` extension is available, ``false`` otherwise +:Default: ``true`` if ``intl`` extension is available (and ICU library is 4.6+ for PHP 7.2+), ``false`` otherwise :Constant: ``GuzzleHttp\RequestOptions::IDN_CONVERSION`` .. code-block:: php diff --git a/src/Client.php b/src/Client.php index db4062f94..a9c851cf5 100644 --- a/src/Client.php +++ b/src/Client.php @@ -218,7 +218,8 @@ private function buildUri($uri, array $config) if ($uri->getHost() && isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; - $asciiHost = idn_to_ascii($uri->getHost(), $idnOptions, INTL_IDNA_VARIANT_UTS46, $info); + $idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; + $asciiHost = idn_to_ascii($uri->getHost(), $idnOptions, $idnaVariant, $info); if ($asciiHost === false) { $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; @@ -267,7 +268,14 @@ private function configureDefaults(array $config) ]; // idn_to_ascii() is a part of ext-intl and might be not available - $defaults['idn_conversion'] = function_exists('idn_to_ascii'); + $defaults['idn_conversion'] = function_exists('idn_to_ascii') + // Old ICU versions don't have this constant, so we are basically stuck (see https://github.com/guzzle/guzzle/pull/2424 + // and https://github.com/guzzle/guzzle/issues/2448 for details) + && ( + defined('INTL_IDNA_VARIANT_UTS46') + || + version_compare(PHP_VERSION, '7.2.0') < 0 + ); // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. From 6a8a624477bb92c80f47ad5ca72a687b1b855ac4 Mon Sep 17 00:00:00 2001 From: Alexey Shokov Date: Thu, 12 Dec 2019 21:05:07 +0400 Subject: [PATCH 113/141] Faster PHP version comparison Co-Authored-By: Brandon Kelly --- src/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index a9c851cf5..687358ed9 100644 --- a/src/Client.php +++ b/src/Client.php @@ -274,7 +274,7 @@ private function configureDefaults(array $config) && ( defined('INTL_IDNA_VARIANT_UTS46') || - version_compare(PHP_VERSION, '7.2.0') < 0 + PHP_VERSION_ID < 70200 ); // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. From d56612f41dce5145e88174e5cd146f6b881c8e1f Mon Sep 17 00:00:00 2001 From: Mponos George Date: Sun, 15 Dec 2019 10:08:06 +0200 Subject: [PATCH 114/141] Revert a check that is not needed --- src/functions.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/functions.php b/src/functions.php index 4332996b0..cc68dc78f 100644 --- a/src/functions.php +++ b/src/functions.php @@ -358,9 +358,7 @@ function _current_time() function _idn_uri_convert(UriInterface $uri, $options = 0) { if ($uri->getHost()) { - $asciiHost = defined('INTL_IDNA_VARIANT_UTS46') - ? idn_to_ascii($uri->getHost(), $options, INTL_IDNA_VARIANT_UTS46, $info) - : idn_to_ascii($uri->getHost(), $options); + $asciiHost = idn_to_ascii($uri->getHost(), $options, INTL_IDNA_VARIANT_UTS46, $info); if ($asciiHost === false) { $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; From 4703d969ea3f9c17a691a66012a591797a9a8944 Mon Sep 17 00:00:00 2001 From: Jaik Dean Date: Mon, 16 Dec 2019 13:39:11 +0000 Subject: [PATCH 115/141] Fix return type for GuzzleHttp\Pool::promise() --- phpstan-baseline.neon | 15 --------------- src/Pool.php | 3 ++- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 13a72f649..f4bd742f2 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1125,16 +1125,6 @@ parameters: count: 1 path: src/Pool.php - - - message: "#^Return typehint of method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) has invalid type GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" - count: 1 - path: src/Pool.php - - - - message: "#^Method GuzzleHttp\\\\Pool\\:\\:promise\\(\\) should return GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" - count: 1 - path: src/Pool.php - - message: "#^Method GuzzleHttp\\\\Pool\\:\\:batch\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 @@ -1155,11 +1145,6 @@ parameters: count: 1 path: src/Pool.php - - - message: "#^Call to method wait\\(\\) on an unknown class GuzzleHttp\\\\GuzzleHttp\\\\Promise\\\\Promise\\.$#" - count: 1 - path: src/Pool.php - - message: "#^Method GuzzleHttp\\\\Pool\\:\\:cmpCallback\\(\\) has parameter \\$name with no typehint specified\\.$#" count: 1 diff --git a/src/Pool.php b/src/Pool.php index ec7df6c0e..b921b6264 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -71,7 +71,8 @@ public function __construct( /** * Get promise - * @return GuzzleHttp\Promise\Promise + * + * @return \GuzzleHttp\Promise\PromiseInterface */ public function promise() { From b751abd9468196ae8504dfec66100bef273a25e9 Mon Sep 17 00:00:00 2001 From: Jaik Dean Date: Mon, 16 Dec 2019 14:45:18 +0000 Subject: [PATCH 116/141] Add use statements for PromiseInterface returns --- src/Client.php | 4 ++-- src/Pool.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Client.php b/src/Client.php index db4062f94..09ecf24d9 100644 --- a/src/Client.php +++ b/src/Client.php @@ -102,7 +102,7 @@ public function __call($method, $args) * @param array $options Request options to apply to the given * request and to the transfer. See \GuzzleHttp\RequestOptions. * - * @return PromiseInterface + * @return Promise\PromiseInterface */ public function sendAsync(RequestInterface $request, array $options = []) { @@ -142,7 +142,7 @@ public function send(RequestInterface $request, array $options = []) * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. * - * @return PromiseInterface + * @return Promise\PromiseInterface */ public function requestAsync($method, $uri = '', array $options = []) { diff --git a/src/Pool.php b/src/Pool.php index b921b6264..5838db4f4 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -2,6 +2,7 @@ namespace GuzzleHttp; use GuzzleHttp\Promise\EachPromise; +use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Promise\PromisorInterface; use Psr\Http\Message\RequestInterface; @@ -72,7 +73,7 @@ public function __construct( /** * Get promise * - * @return \GuzzleHttp\Promise\PromiseInterface + * @return PromiseInterface */ public function promise() { From 62881ec7dcf7f0845b25debd4dd31ba98fdc1da9 Mon Sep 17 00:00:00 2001 From: Jaik Dean Date: Mon, 16 Dec 2019 14:49:41 +0000 Subject: [PATCH 117/141] Update phpstan baseline --- phpstan-baseline.neon | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f4bd742f2..37dbf1bb3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -16,7 +16,7 @@ parameters: path: src/Client.php - - message: "#^Method GuzzleHttp\\\\Client\\:\\:__call\\(\\) should return GuzzleHttp\\\\Promise\\\\PromiseInterface but returns GuzzleHttp\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface\\.$#" + message: "#^Method GuzzleHttp\\\\Client\\:\\:__call\\(\\) should return GuzzleHttp\\\\Promise\\\\PromiseInterface but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\|Psr\\\\Http\\\\Message\\\\ResponseInterface\\.$#" count: 1 path: src/Client.php @@ -25,16 +25,6 @@ parameters: count: 1 path: src/Client.php - - - message: "#^Return typehint of method GuzzleHttp\\\\Client\\:\\:sendAsync\\(\\) has invalid type GuzzleHttp\\\\PromiseInterface\\.$#" - count: 1 - path: src/Client.php - - - - message: "#^Method GuzzleHttp\\\\Client\\:\\:sendAsync\\(\\) should return GuzzleHttp\\\\PromiseInterface but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" - count: 1 - path: src/Client.php - - message: "#^Method GuzzleHttp\\\\Client\\:\\:send\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 @@ -45,26 +35,11 @@ parameters: count: 2 path: src/Client.php - - - message: "#^Call to method wait\\(\\) on an unknown class GuzzleHttp\\\\PromiseInterface\\.$#" - count: 2 - path: src/Client.php - - message: "#^Method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 path: src/Client.php - - - message: "#^Return typehint of method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) has invalid type GuzzleHttp\\\\PromiseInterface\\.$#" - count: 1 - path: src/Client.php - - - - message: "#^Method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) should return GuzzleHttp\\\\PromiseInterface but returns GuzzleHttp\\\\Promise\\\\PromiseInterface\\.$#" - count: 1 - path: src/Client.php - - message: "#^Method GuzzleHttp\\\\Client\\:\\:request\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 From b372406562bd7c2dba7dd828ba9987e8d7536fd4 Mon Sep 17 00:00:00 2001 From: Jonny Nott Date: Tue, 17 Dec 2019 08:34:44 +0000 Subject: [PATCH 118/141] fix dash underline for idn_conversion ...so it actually shows up as a section in the docfile --- docs/request-options.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/request-options.rst b/docs/request-options.rst index 2a477aee9..654f7524f 100644 --- a/docs/request-options.rst +++ b/docs/request-options.rst @@ -554,7 +554,7 @@ http_errors idn_conversion ---- +-------------- :Summary: Internationalized Domain Name (IDN) support (enabled by default if ``intl`` extension is available). From 4bd2d3383bcc860ed3abaaaf6f09b54e84af8657 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Fri, 20 Dec 2019 00:17:39 +0000 Subject: [PATCH 119/141] Use PHP 7.4 stable on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 79d9e32ef..14100e3c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ php: - 7.1 - 7.2 - 7.3 - - 7.4snapshot + - 7.4 - nightly before_script: From 0274c05370a7bc9bb3a33838858253418bd7d14b Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Sat, 21 Dec 2019 09:51:15 +0100 Subject: [PATCH 120/141] Prepare CHANGELOG for 6.5.1 (#2481) --- CHANGELOG.md | 5 +++++ src/ClientInterface.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d731439..67738daef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 6.5.1 - 2019-12-21 + +* Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454) +* IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424) + ## 6.5.0 - 2019-12-07 * Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 0829b3607..0c8d42a1e 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -15,7 +15,7 @@ interface ClientInterface /** * @deprecated Will be removed in Guzzle 7.0.0 */ - const VERSION = '6.5.0'; + const VERSION = '6.5.1'; /** * Send an HTTP request. From 8781cac0e4b6e820f3cbc6c09ab728a727a4ac1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rk=20S=C3=A1gi-Kaz=C3=A1r?= Date: Mon, 23 Dec 2019 08:58:26 +0100 Subject: [PATCH 121/141] Fix Roave BC check (#2490) * Fix Roave BC checks * Remove rule from baseline --- .github/workflows/{bc.yml => checks.yml} | 19 ++++++++++++++----- .github/workflows/static.yml | 18 +++++++++++++++--- phpstan-baseline.neon | 5 ----- 3 files changed, 29 insertions(+), 13 deletions(-) rename .github/workflows/{bc.yml => checks.yml} (51%) diff --git a/.github/workflows/bc.yml b/.github/workflows/checks.yml similarity index 51% rename from .github/workflows/bc.yml rename to .github/workflows/checks.yml index a2dbf0ecd..fdac56ce3 100644 --- a/.github/workflows/bc.yml +++ b/.github/workflows/checks.yml @@ -1,11 +1,20 @@ -on: [push, pull_request] -name: Roave +name: Checks + +on: + push: + branches: + - master + pull_request: + jobs: - roave_bc_check: - name: BC Check + roave-bc-check: + name: Roave BC Check runs-on: ubuntu-latest + steps: - - uses: actions/checkout@master + - name: Checkout code + uses: actions/checkout@v1 + - name: Roave BC Check uses: docker://nyholm/roave-bc-check-ga with: diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 14900316a..9d1546807 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -1,11 +1,20 @@ -on: [push, pull_request] name: Static analysis + +on: + push: + branches: + - master + pull_request: + jobs: phpstan: name: PHPStan runs-on: ubuntu-latest + steps: - - uses: actions/checkout@master + - name: Checkout code + uses: actions/checkout@v1 + - name: PHPStan uses: docker://oskarstark/phpstan-ga with: @@ -14,8 +23,11 @@ jobs: php-cs-fixer: name: PHP-CS-Fixer runs-on: ubuntu-latest + steps: - - uses: actions/checkout@master + - name: Checkout code + uses: actions/checkout@v1 + - name: PHP-CS-Fixer uses: docker://oskarstark/php-cs-fixer-ga with: diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 37dbf1bb3..dc5180f7f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -255,11 +255,6 @@ parameters: count: 1 path: src/Cookie/SetCookie.php - - - message: "#^Property GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:\\$data \\(array\\) does not accept array\\|null\\.$#" - count: 1 - path: src/Cookie/SetCookie.php - - message: "#^Parameter \\#1 \\$timestamp of method GuzzleHttp\\\\Cookie\\\\SetCookie\\:\\:setExpires\\(\\) expects int, mixed given\\.$#" count: 1 From af1ace0cedb6ad440441dc903a0493014e856277 Mon Sep 17 00:00:00 2001 From: Alexey Shokov Date: Mon, 23 Dec 2019 12:05:53 +0400 Subject: [PATCH 122/141] idn_to_ascii() fix for old PHP versions (#2489) --- src/functions.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/functions.php b/src/functions.php index 1924d6d33..5e806f632 100644 --- a/src/functions.php +++ b/src/functions.php @@ -359,7 +359,9 @@ function _idn_uri_convert(UriInterface $uri, $options = 0) { if ($uri->getHost()) { $idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; - $asciiHost = idn_to_ascii($uri->getHost(), $options, $idnaVariant, $info); + $asciiHost = $idnaVariant === 0 + ? idn_to_ascii($uri->getHost(), $options) + : idn_to_ascii($uri->getHost(), $options, $idnaVariant, $info); if ($asciiHost === false) { $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; From c62b7e54e4227732bad5d90ced7989168f8a185c Mon Sep 17 00:00:00 2001 From: Mponos George Date: Mon, 23 Dec 2019 10:27:48 +0200 Subject: [PATCH 123/141] Wrote changelog for version 6.5.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67738daef..a2b61e712 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 6.5.2 - 2019-12-23 + +* idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489) + ## 6.5.1 - 2019-12-21 * Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454) From a7680be7f3baba747db9d3bb75bfc94f2528d538 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 29 Dec 2019 19:13:05 +0000 Subject: [PATCH 124/141] Fixed deprecation warning in node test server (#2517) --- tests/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/server.js b/tests/server.js index 6bc858e30..8e2ab249d 100644 --- a/tests/server.js +++ b/tests/server.js @@ -178,7 +178,7 @@ var GuzzleServer = function(port, log) { that.responses = JSON.parse(request.body); for (var i = 0; i < that.responses.length; i++) { if (that.responses[i].body) { - that.responses[i].body = new Buffer(that.responses[i].body, 'base64'); + that.responses[i].body = new Buffer.from(that.responses[i].body, 'base64'); } } if (that.log) { From 27c816866d521cd03321d84ccef236b537d0a4e8 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 29 Dec 2019 19:17:51 +0000 Subject: [PATCH 125/141] Travis improvements --- .travis.yml | 56 +++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14100e3c7..96955d9d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,37 +1,43 @@ language: php -sudo: false - -php: - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 - - 7.4 - - nightly - -before_script: - - curl --version - - composer install --no-interaction --prefer-source --dev - - ~/.nvm/nvm.sh install v0.6.14 - - ~/.nvm/nvm.sh run v0.6.14 - - if [[ "$TRAVIS_PHP_VERSION" != "7.0" || "$TRAVIS_PHP_VERSION" != "7.1" ]]; then echo "xdebug.overload_var_dump = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini || true; fi - -script: make test - matrix: - allow_failures: - - php: hhvm - dist: trusty - - php: nightly include: - php: 5.5 dist: trusty - - php: hhvm + - php: 5.6 + dist: xenial + - php: 7.0 + dist: xenial + - php: 7.1 + dist: bionic + - php: 7.2 + dist: bionic + - php: 7.3 + dist: bionic + - php: 7.4 + dist: bionic + - php: nightly + dist: bionic + env: COMPOSER_ARGS="--ignore-platform-reqs" + - php: hhvm-3.24 dist: trusty + allow_failures: + - php: hhvm-3.24 + - php: nightly fast_finish: true +install: + - if [[ "$TRAVIS_PHP_VERSION" != "hhvm-3.24" || "$TRAVIS_PHP_VERSION" != "nightly" ]]; then echo "xdebug.overload_var_dump = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini || true; fi + - composer install --prefer-dist $COMPOSER_ARGS + - ~/.nvm/nvm.sh install v10.18.0 + - ~/.nvm/nvm.sh run v10.18.0 + +before_script: + - curl --version + +script: + - make test + before_deploy: - make package From 9189d4690adf3d0d86e1c034356604b4088a090e Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 15 Apr 2020 18:44:58 +0100 Subject: [PATCH 126/141] Don't use internal functions (#2548) --- src/Client.php | 2 +- src/Handler/CurlMultiHandler.php | 7 +-- src/Handler/StreamHandler.php | 5 +- src/RedirectMiddleware.php | 2 +- src/Utils.php | 67 ++++++++++++++++++++++++++ src/functions.php | 62 +----------------------- tests/Handler/CurlHandlerTest.php | 5 +- tests/Handler/CurlMultiHandlerTest.php | 5 +- tests/Handler/StreamHandlerTest.php | 5 +- tests/InternalUtilsTest.php | 25 ++++++++++ tests/functionsTest.php | 16 ------ 11 files changed, 111 insertions(+), 90 deletions(-) create mode 100644 src/Utils.php create mode 100644 tests/InternalUtilsTest.php diff --git a/src/Client.php b/src/Client.php index f2bf20444..84b8a3b92 100644 --- a/src/Client.php +++ b/src/Client.php @@ -217,7 +217,7 @@ private function buildUri($uri, array $config) if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; - $uri = _idn_uri_convert($uri, $idnOptions); + $uri = Utils::idnUriConvert($uri, $idnOptions); } return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; diff --git a/src/Handler/CurlMultiHandler.php b/src/Handler/CurlMultiHandler.php index b73e5c72d..8eaa34f35 100644 --- a/src/Handler/CurlMultiHandler.php +++ b/src/Handler/CurlMultiHandler.php @@ -4,6 +4,7 @@ use GuzzleHttp\Exception\InvalidArgumentException; use GuzzleHttp\Promise as P; use GuzzleHttp\Promise\Promise; +use GuzzleHttp\Utils; use Psr\Http\Message\RequestInterface; /** @@ -102,7 +103,7 @@ public function tick() { // Add any delayed handles if needed. if ($this->delays) { - $currentTime = \GuzzleHttp\_current_time(); + $currentTime = Utils::currentTime(); foreach ($this->delays as $id => $delay) { if ($currentTime >= $delay) { unset($this->delays[$id]); @@ -154,7 +155,7 @@ private function addRequest(array $entry) if (empty($easy->options['delay'])) { curl_multi_add_handle($this->_mh, $easy->handle); } else { - $this->delays[$id] = \GuzzleHttp\_current_time() + ($easy->options['delay'] / 1000); + $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000); } } @@ -206,7 +207,7 @@ private function processMessages() private function timeToNext() { - $currentTime = \GuzzleHttp\_current_time(); + $currentTime = Utils::currentTime(); $nextTime = PHP_INT_MAX; foreach ($this->delays as $time) { if ($time < $nextTime) { diff --git a/src/Handler/StreamHandler.php b/src/Handler/StreamHandler.php index a8eba3786..a15734a44 100644 --- a/src/Handler/StreamHandler.php +++ b/src/Handler/StreamHandler.php @@ -7,6 +7,7 @@ use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Psr7; use GuzzleHttp\TransferStats; +use GuzzleHttp\Utils; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; @@ -33,7 +34,7 @@ public function __invoke(RequestInterface $request, array $options) usleep($options['delay'] * 1000); } - $startTime = isset($options['on_stats']) ? \GuzzleHttp\_current_time() : null; + $startTime = isset($options['on_stats']) ? Utils::currentTime() : null; try { // Does not support the expect header. @@ -82,7 +83,7 @@ private function invokeStats( $stats = new TransferStats( $request, $response, - \GuzzleHttp\_current_time() - $startTime, + Utils::currentTime() - $startTime, $error, [] ); diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index 2f3012618..e4644b7ac 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -193,7 +193,7 @@ public function modifyRequest( $uri = $this->redirectUri($request, $response, $protocols); if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion']; - $uri = _idn_uri_convert($uri, $idnOptions); + $uri = Utils::idnUriConvert($uri, $idnOptions); } $modify['uri'] = $uri; diff --git a/src/Utils.php b/src/Utils.php new file mode 100644 index 000000000..c8fc1aec6 --- /dev/null +++ b/src/Utils.php @@ -0,0 +1,67 @@ +getHost()) { + $idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; + $asciiHost = $idnaVariant === 0 + ? idn_to_ascii($uri->getHost(), $options) + : idn_to_ascii($uri->getHost(), $options, $idnaVariant, $info); + if ($asciiHost === false) { + $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; + + $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { + return substr($name, 0, 11) === 'IDNA_ERROR_'; + }); + + $errors = []; + foreach ($errorConstants as $errorConstant) { + if ($errorBitSet & constant($errorConstant)) { + $errors[] = $errorConstant; + } + } + + $errorMessage = 'IDN conversion failed'; + if ($errors) { + $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; + } + + throw new InvalidArgumentException($errorMessage); + } else { + if ($uri->getHost() !== $asciiHost) { + // Replace URI only if the ASCII version is different + $uri = $uri->withHost($asciiHost); + } + } + } + + return $uri; + } +} diff --git a/src/functions.php b/src/functions.php index 5e806f632..c2afd8c7b 100644 --- a/src/functions.php +++ b/src/functions.php @@ -1,12 +1,10 @@ getHost()) { - $idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; - $asciiHost = $idnaVariant === 0 - ? idn_to_ascii($uri->getHost(), $options) - : idn_to_ascii($uri->getHost(), $options, $idnaVariant, $info); - if ($asciiHost === false) { - $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; - - $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { - return substr($name, 0, 11) === 'IDNA_ERROR_'; - }); - - $errors = []; - foreach ($errorConstants as $errorConstant) { - if ($errorBitSet & constant($errorConstant)) { - $errors[] = $errorConstant; - } - } - - $errorMessage = 'IDN conversion failed'; - if ($errors) { - $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; - } - - throw new InvalidArgumentException($errorMessage); - } else { - if ($uri->getHost() !== $asciiHost) { - // Replace URI only if the ASCII version is different - $uri = $uri->withHost($asciiHost); - } - } - } - - return $uri; -} diff --git a/tests/Handler/CurlHandlerTest.php b/tests/Handler/CurlHandlerTest.php index 8bbb81734..189a0a966 100644 --- a/tests/Handler/CurlHandlerTest.php +++ b/tests/Handler/CurlHandlerTest.php @@ -7,6 +7,7 @@ use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Tests\Server; +use GuzzleHttp\Utils; use PHPUnit\Framework\TestCase; /** @@ -47,9 +48,9 @@ public function testDoesSleep() Server::enqueue([$response]); $a = new CurlHandler(); $request = new Request('GET', Server::$url); - $s = \GuzzleHttp\_current_time(); + $s = Utils::currentTime(); $a($request, ['delay' => 0.1])->wait(); - self::assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); + self::assertGreaterThan(0.0001, Utils::currentTime() - $s); } public function testCreatesCurlErrorsWithContext() diff --git a/tests/Handler/CurlMultiHandlerTest.php b/tests/Handler/CurlMultiHandlerTest.php index 9db4f5622..8e2d499ac 100644 --- a/tests/Handler/CurlMultiHandlerTest.php +++ b/tests/Handler/CurlMultiHandlerTest.php @@ -5,6 +5,7 @@ use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Tests\Server; +use GuzzleHttp\Utils; use PHPUnit\Framework\TestCase; class CurlMultiHandlerTest extends TestCase @@ -91,10 +92,10 @@ public function testDelaysConcurrently() Server::flush(); Server::enqueue([new Response()]); $a = new CurlMultiHandler(); - $expected = \GuzzleHttp\_current_time() + (100 / 1000); + $expected = Utils::currentTime() + (100 / 1000); $response = $a(new Request('GET', Server::$url), ['delay' => 100]); $response->wait(); - self::assertGreaterThanOrEqual($expected, \GuzzleHttp\_current_time()); + self::assertGreaterThanOrEqual($expected, Utils::currentTime()); } public function testUsesTimeoutEnvironmentVariables() diff --git a/tests/Handler/StreamHandlerTest.php b/tests/Handler/StreamHandlerTest.php index 5571dd844..674a4ad7f 100644 --- a/tests/Handler/StreamHandlerTest.php +++ b/tests/Handler/StreamHandlerTest.php @@ -10,6 +10,7 @@ use GuzzleHttp\RequestOptions; use GuzzleHttp\Tests\Server; use GuzzleHttp\TransferStats; +use GuzzleHttp\Utils; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; @@ -508,9 +509,9 @@ public function testDoesSleep() Server::enqueue([$response]); $a = new StreamHandler(); $request = new Request('GET', Server::$url); - $s = \GuzzleHttp\_current_time(); + $s = Utils::currentTime(); $a($request, ['delay' => 0.1])->wait(); - self::assertGreaterThan(0.0001, \GuzzleHttp\_current_time() - $s); + self::assertGreaterThan(0.0001, Utils::currentTime() - $s); } /** diff --git a/tests/InternalUtilsTest.php b/tests/InternalUtilsTest.php new file mode 100644 index 000000000..133bee5ea --- /dev/null +++ b/tests/InternalUtilsTest.php @@ -0,0 +1,25 @@ +getHost()); + } +} diff --git a/tests/functionsTest.php b/tests/functionsTest.php index e07b558e8..33473ea62 100644 --- a/tests/functionsTest.php +++ b/tests/functionsTest.php @@ -128,22 +128,6 @@ public function testDecodesJsonAndThrowsOnError() { \GuzzleHttp\json_decode('{{]]'); } - - public function testCurrentTime() - { - self::assertGreaterThan(0, GuzzleHttp\_current_time()); - } - - public function testIdnConvert() - { - if (!extension_loaded('intl')) { - self::markTestSkipped('intl PHP extension is not loaded'); - } - - $uri = GuzzleHttp\Psr7\uri_for('https://яндекс.рф/images'); - $uri = GuzzleHttp\_idn_uri_convert($uri); - self::assertSame('xn--d1acpjx3f.xn--p1ai', $uri->getHost()); - } } final class StrClass From 3325c9d98ad876127d6244d6e09e3cd7076d6492 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 15 Apr 2020 19:04:46 +0100 Subject: [PATCH 127/141] [6.5] Install symfony's intl-idn polyfill (#2550) * Install symfony's intl-idn polyfill * idn conversion always available * remove "skipped because of intl" * PHPStan CI fix Co-authored-by: Nyholm --- .github/workflows/static.yml | 2 ++ composer.json | 4 ++-- phpstan.neon.dist | 1 - src/Client.php | 13 ++----------- tests/ClientTest.php | 19 +------------------ tests/InternalUtilsTest.php | 4 ---- tests/bootstrap-phpstan.php | 9 --------- 7 files changed, 7 insertions(+), 45 deletions(-) delete mode 100644 tests/bootstrap-phpstan.php diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 9d1546807..0558d935f 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -17,6 +17,8 @@ jobs: - name: PHPStan uses: docker://oskarstark/phpstan-ga + env: + REQUIRE_DEV: true with: args: analyze --no-progress diff --git a/composer.json b/composer.json index bbf0ff20b..02ab73c0f 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "require": { "php": ">=5.5", "ext-json": "*", + "symfony/polyfill-intl-idn": "^1.11", "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1" }, @@ -32,8 +33,7 @@ "psr/log": "^1.1" }, "suggest": { - "psr/log": "Required for using the Log middleware", - "ext-intl": "Required for Internationalized Domain Name (IDN) support" + "psr/log": "Required for using the Log middleware" }, "config": { "sort-packages": true diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 012c5da5f..2d83c9846 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,4 +5,3 @@ parameters: level: max paths: - src - bootstrap: tests/bootstrap-phpstan.php \ No newline at end of file diff --git a/src/Client.php b/src/Client.php index 84b8a3b92..cd9a63574 100644 --- a/src/Client.php +++ b/src/Client.php @@ -236,19 +236,10 @@ private function configureDefaults(array $config) 'http_errors' => true, 'decode_content' => true, 'verify' => true, - 'cookies' => false + 'cookies' => false, + 'idn_conversion' => true, ]; - // idn_to_ascii() is a part of ext-intl and might be not available - $defaults['idn_conversion'] = function_exists('idn_to_ascii') - // Old ICU versions don't have this constant, so we are basically stuck (see https://github.com/guzzle/guzzle/pull/2424 - // and https://github.com/guzzle/guzzle/issues/2448 for details) - && ( - defined('INTL_IDNA_VARIANT_UTS46') - || - PHP_VERSION_ID < 70200 - ); - // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. // We can only trust the HTTP_PROXY environment variable in a CLI diff --git a/tests/ClientTest.php b/tests/ClientTest.php index bc4ae33b1..cf4fcccde 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -721,18 +721,11 @@ public function testIdnSupportDefaultValue() $config = $client->getConfig(); - if (extension_loaded('intl')) { - self::assertTrue($config['idn_conversion']); - } else { - self::assertFalse($config['idn_conversion']); - } + self::assertTrue($config['idn_conversion']); } public function testIdnIsTranslatedToAsciiWhenConversionIsEnabled() { - if (!extension_loaded('intl')) { - self::markTestSkipped('intl PHP extension is not loaded'); - } $mockHandler = new MockHandler([new Response()]); $client = new Client(['handler' => $mockHandler]); @@ -763,9 +756,6 @@ public function testIdnStaysTheSameWhenConversionIsDisabled() */ public function testExceptionOnInvalidIdn() { - if (!extension_loaded('intl')) { - self::markTestSkipped('intl PHP extension is not loaded'); - } $mockHandler = new MockHandler([new Response()]); $client = new Client(['handler' => $mockHandler]); @@ -778,10 +768,6 @@ public function testExceptionOnInvalidIdn() */ public function testIdnBaseUri() { - if (!extension_loaded('intl')) { - self::markTestSkipped('intl PHP extension is not loaded'); - } - $mock = new MockHandler([new Response()]); $client = new Client([ 'handler' => $mock, @@ -796,9 +782,6 @@ public function testIdnBaseUri() public function testIdnWithRedirect() { - if (!extension_loaded('intl')) { - self::markTestSkipped('intl PHP extension is not loaded'); - } $mockHandler = new MockHandler([ new Response(302, ['Location' => 'http://www.tést.com/whatever']), new Response() diff --git a/tests/InternalUtilsTest.php b/tests/InternalUtilsTest.php index 133bee5ea..b465ff046 100644 --- a/tests/InternalUtilsTest.php +++ b/tests/InternalUtilsTest.php @@ -14,10 +14,6 @@ public function testCurrentTime() public function testIdnConvert() { - if (!extension_loaded('intl')) { - self::markTestSkipped('intl PHP extension is not loaded'); - } - $uri = Psr7\uri_for('https://яндекс.рф/images'); $uri = Utils::idnUriConvert($uri); self::assertSame('xn--d1acpjx3f.xn--p1ai', $uri->getHost()); diff --git a/tests/bootstrap-phpstan.php b/tests/bootstrap-phpstan.php deleted file mode 100644 index e91b7419c..000000000 --- a/tests/bootstrap-phpstan.php +++ /dev/null @@ -1,9 +0,0 @@ - Date: Sat, 18 Apr 2020 12:38:46 +0200 Subject: [PATCH 128/141] Prepare release of 6.5.3 (#2613) * Prepare release of 6.5.3 * Typo * Updated date * Updated constant --- CHANGELOG.md | 5 +++++ src/ClientInterface.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2b61e712..a5cb9c1a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 6.5.3 - 2020-04-18 + +* Use Symfony intl-idn polyfill [#2550](https://github.com/guzzle/guzzle/pull/2550) +* Remove use of internal functions [#2548](https://github.com/guzzle/guzzle/pull/2548) + ## 6.5.2 - 2019-12-23 * idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 0c8d42a1e..76872dd3a 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -15,7 +15,7 @@ interface ClientInterface /** * @deprecated Will be removed in Guzzle 7.0.0 */ - const VERSION = '6.5.1'; + const VERSION = '6.5.3'; /** * Send an HTTP request. From 351a213ba2ea52b7b7d26339fad552f0edba5742 Mon Sep 17 00:00:00 2001 From: Guilliam Xavier Date: Sun, 17 May 2020 11:36:12 +0200 Subject: [PATCH 129/141] Fix "Fixed deprecation warning in node test server" (#2638) * Fix "Fixed deprecation warning in node test server * Ignore PHPStan error after review --- phpstan-baseline.neon | 5 +++++ tests/server.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index dc5180f7f..506d060d1 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -495,6 +495,11 @@ parameters: count: 1 path: src/Handler/CurlFactory.php + - + message: "#^Parameter \\#1 \\$filename of function is_dir expects string, string\\|false given\\.$#" + count: 1 + path: src/Handler/CurlFactory.php + - message: "#^Method GuzzleHttp\\\\Handler\\\\CurlFactory\\:\\:retryFailedRewind\\(\\) has no return typehint specified\\.$#" count: 1 diff --git a/tests/server.js b/tests/server.js index 8e2ab249d..f6c336a5a 100644 --- a/tests/server.js +++ b/tests/server.js @@ -178,7 +178,7 @@ var GuzzleServer = function(port, log) { that.responses = JSON.parse(request.body); for (var i = 0; i < that.responses.length; i++) { if (that.responses[i].body) { - that.responses[i].body = new Buffer.from(that.responses[i].body, 'base64'); + that.responses[i].body = Buffer.from(that.responses[i].body, 'base64'); } } if (that.log) { From 5262ecfd7683f760e08a934db6e76e748e3c2f00 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Mon, 18 May 2020 06:46:00 -0400 Subject: [PATCH 130/141] Document the impact of fixing time units for RetryMiddleware (#2570) Related to #2132 A fraction of use cases will expect low timeouts or no timeouts. Make it clearer that those applications should override the defaults of the middleware if upgrading to 6.5.0 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5cb9c1a8..9de171789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,10 @@ * Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143) * Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287) * Fix: Gracefully handle passing `null` to the `header` option. [#2132](https://github.com/guzzle/guzzle/pull/2132) -* Fix: `RetryMiddleware` did not do exponential delay between retires due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132) +* Fix: `RetryMiddleware` did not do exponential delay between retries due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132) + Previously, `RetryMiddleware` would sleep for 1 millisecond, then 2 milliseconds, then 4 milliseconds. + **After this change, `RetryMiddleware` will sleep for 1 second, then 2 seconds, then 4 seconds.** + `Middleware::retry()` accepts a second callback parameter to override the default timeouts if needed. * Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348) * Deprecated `ClientInterface::VERSION` From c8162bee934111d42b1db4869c09fb58926074c7 Mon Sep 17 00:00:00 2001 From: Guilliam Xavier Date: Tue, 19 May 2020 14:55:02 +0200 Subject: [PATCH 131/141] Fix use and phpDoc for `@throws` GuzzleException/InvalidArgumentException (#2621) --- phpstan-baseline.neon | 5 ----- src/Client.php | 4 ++-- src/Handler/CurlMultiHandler.php | 1 - 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 506d060d1..8ced5b066 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -30,11 +30,6 @@ parameters: count: 1 path: src/Client.php - - - message: "#^PHPDoc tag @throws with type GuzzleHttp\\\\GuzzleException is not subtype of Throwable$#" - count: 2 - path: src/Client.php - - message: "#^Method GuzzleHttp\\\\Client\\:\\:requestAsync\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 diff --git a/src/Client.php b/src/Client.php index cd9a63574..2caac7584 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,7 +2,7 @@ namespace GuzzleHttp; use GuzzleHttp\Cookie\CookieJar; -use GuzzleHttp\Exception\InvalidArgumentException; +use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Promise; use GuzzleHttp\Psr7; use Psr\Http\Message\RequestInterface; @@ -489,7 +489,7 @@ private function applyOptions(RequestInterface $request, array &$options) /** * Throw Exception with pre-set message. * @return void - * @throws InvalidArgumentException Invalid body. + * @throws \InvalidArgumentException Invalid body. */ private function invalidBody() { diff --git a/src/Handler/CurlMultiHandler.php b/src/Handler/CurlMultiHandler.php index 8eaa34f35..564c95f48 100644 --- a/src/Handler/CurlMultiHandler.php +++ b/src/Handler/CurlMultiHandler.php @@ -1,7 +1,6 @@ Date: Sat, 23 May 2020 19:57:25 +0100 Subject: [PATCH 132/141] [6.5] Fix various intl icu issues (#2626) * Fix issues when compiled against old intl icu * Fixes * Bumped minimum polyfill-intl-idn version * Skip conversion for ASCII domains * Lock version to symfony/polyfill-intl-idn:1.17.0 Co-authored-by: Nyholm --- composer.json | 2 +- phpstan-baseline.neon | 5 +++++ src/Utils.php | 30 ++++++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 02ab73c0f..b7bff79a8 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "require": { "php": ">=5.5", "ext-json": "*", - "symfony/polyfill-intl-idn": "^1.11", + "symfony/polyfill-intl-idn": "1.17.0", "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1" }, diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 8ced5b066..747e2f637 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1310,6 +1310,11 @@ parameters: count: 1 path: src/UriTemplate.php + - + message: "#^Method GuzzleHttp\\\\Utils\\:\\:idnToAsci\\(\\) has parameter \\$info with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Utils.php + - message: "#^Function GuzzleHttp\\\\uri_template\\(\\) has parameter \\$variables with no value type specified in iterable type array\\.$#" count: 1 diff --git a/src/Utils.php b/src/Utils.php index c8fc1aec6..dd90c2265 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -3,6 +3,7 @@ use GuzzleHttp\Exception\InvalidArgumentException; use Psr\Http\Message\UriInterface; +use Symfony\Polyfill\Intl\Idn\Idn; final class Utils { @@ -30,10 +31,7 @@ public static function currentTime() public static function idnUriConvert(UriInterface $uri, $options = 0) { if ($uri->getHost()) { - $idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0; - $asciiHost = $idnaVariant === 0 - ? idn_to_ascii($uri->getHost(), $options) - : idn_to_ascii($uri->getHost(), $options, $idnaVariant, $info); + $asciiHost = self::idnToAsci($uri->getHost(), $options, $info); if ($asciiHost === false) { $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; @@ -64,4 +62,28 @@ public static function idnUriConvert(UriInterface $uri, $options = 0) return $uri; } + + /** + * @param string $domain + * @param int $options + * @param array $info + * + * @return string|false + */ + private static function idnToAsci($domain, $options, &$info = []) + { + if (\preg_match('%^[ -~]+$%', $domain) === 1) { + return $domain; + } + + if (\extension_loaded('intl') && defined('INTL_IDNA_VARIANT_UTS46')) { + return \idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $info); + } + + /* + * The Idn class is marked as @internal. We've locked the version to + * symfony/polyfill-intl-idn to avoid issues in the future. + */ + return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info); + } } From 0d137e94480b275aadd1f2536a76d91cf580711c Mon Sep 17 00:00:00 2001 From: Guilliam Xavier Date: Sat, 23 May 2020 20:58:46 +0200 Subject: [PATCH 133/141] [6.5] Remove obsolete statement in `handler` option docs (#2567) * Remove obsolete statement in handler option phpDoc * Remove obsolete statement in handler option doc --- docs/quickstart.rst | 3 +-- src/Client.php | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 1c6988c3a..7a3f35fbd 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -67,8 +67,7 @@ The client constructor accepts an associative array of options: function is called with a ``Psr7\Http\Message\RequestInterface`` and array of transfer options, and must return a ``GuzzleHttp\Promise\PromiseInterface`` that is fulfilled with a - ``Psr7\Http\Message\ResponseInterface`` on success. ``handler`` is a - constructor only option that cannot be overridden in per/request options. + ``Psr7\Http\Message\ResponseInterface`` on success. ``...`` (mixed) All other options passed to the constructor are used as default diff --git a/src/Client.php b/src/Client.php index 2caac7584..315a022cf 100644 --- a/src/Client.php +++ b/src/Client.php @@ -47,9 +47,8 @@ class Client implements ClientInterface * wire. The function is called with a Psr7\Http\Message\RequestInterface * and array of transfer options, and must return a * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a - * Psr7\Http\Message\ResponseInterface on success. "handler" is a - * constructor only option that cannot be overridden in per/request - * options. If no handler is provided, a default handler will be created + * Psr7\Http\Message\ResponseInterface on success. + * If no handler is provided, a default handler will be created * that enables all of the request options below by attaching all of the * default middleware to the handler. * - base_uri: (string|UriInterface) Base URI of the client that is merged From a4a1b6930528a8f7ee03518e6442ec7a44155d9d Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Mon, 25 May 2020 21:35:05 +0200 Subject: [PATCH 134/141] Adding changelog for 6.5.4 (#2651) * Adding changelog for 6.5.4 * Bump version --- CHANGELOG.md | 4 ++++ src/ClientInterface.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9de171789..f5b183a0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 6.5.4 - 2020-05-25 + +* Fix various intl icu issues [#2626](https://github.com/guzzle/guzzle/pull/2626) + ## 6.5.3 - 2020-04-18 * Use Symfony intl-idn polyfill [#2550](https://github.com/guzzle/guzzle/pull/2550) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 76872dd3a..54c759b96 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -15,7 +15,7 @@ interface ClientInterface /** * @deprecated Will be removed in Guzzle 7.0.0 */ - const VERSION = '6.5.3'; + const VERSION = '6.5.4'; /** * Send an HTTP request. From 23730ab1005ca1e760dcdfbd7d853e6c3f1035d6 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Sat, 6 Jun 2020 14:11:37 +0200 Subject: [PATCH 135/141] Unpin version for symfony/polyfill-intl-idn (#2678) * Unpin version for symfony/polyfill-intl-idn * minor * typo * Added changelgo --- CHANGELOG.md | 4 ++++ composer.json | 2 +- src/Utils.php | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b183a0c..683c55946 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 6.5.5 - UNRELEASED + +* Unpin version constraint for `symfony/polyfill-intl-idn` [#2678](https://github.com/guzzle/guzzle/pull/2678) + ## 6.5.4 - 2020-05-25 * Fix various intl icu issues [#2626](https://github.com/guzzle/guzzle/pull/2626) diff --git a/composer.json b/composer.json index b7bff79a8..c01864f01 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "require": { "php": ">=5.5", "ext-json": "*", - "symfony/polyfill-intl-idn": "1.17.0", + "symfony/polyfill-intl-idn": "^1.17.0", "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1" }, diff --git a/src/Utils.php b/src/Utils.php index dd90c2265..c698acbf0 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -81,9 +81,12 @@ private static function idnToAsci($domain, $options, &$info = []) } /* - * The Idn class is marked as @internal. We've locked the version to - * symfony/polyfill-intl-idn to avoid issues in the future. + * The Idn class is marked as @internal. Verify that class and method exists. */ - return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info); + if (method_exists(Idn::class, 'idn_to_ascii')) { + return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info); + } + + throw new \RuntimeException('ext-intl or symfony/polyfill-intl-idn not loaded or too old'); } } From ba7930ff4209374c2817738e408eeeedcf42fa7b Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Tue, 16 Jun 2020 10:06:57 +0100 Subject: [PATCH 136/141] Updated static analysis tooling (#2694) --- .github/workflows/checks.yml | 2 +- .github/workflows/static.yml | 10 +++++----- Makefile | 19 +++++++++++++++++++ phpstan-baseline.neon | 20 -------------------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index fdac56ce3..4a248d146 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Roave BC Check uses: docker://nyholm/roave-bc-check-ga diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 0558d935f..8948130b6 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -10,13 +10,13 @@ jobs: phpstan: name: PHPStan runs-on: ubuntu-latest - + steps: - name: Checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: PHPStan - uses: docker://oskarstark/phpstan-ga + uses: OskarStark/phpstan-ga@0.12.28 env: REQUIRE_DEV: true with: @@ -28,9 +28,9 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: PHP-CS-Fixer - uses: docker://oskarstark/php-cs-fixer-ga + uses: OskarStark/php-cs-fixer-ga@2.16.3.1 with: args: --dry-run --diff-format udiff diff --git a/Makefile b/Makefile index a58682615..387a46d2e 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,11 @@ help: @echo " docs-show to view the Sphinx docs" @echo " tag to modify the version, update changelog, and chag tag" @echo " package to build the phar and zip files" + @echo " static to run phpstan and php-cs-fixer on the codebase" + @echo " static-phpstan to run phpstan on the codebase" + @echo " static-phpstan-update-baseline to regenerate the phpstan baseline file" + @echo " static-codestyle-fix to run php-cs-fixer on the codebase, writing the changes" + @echo " static-codestyle-check to run php-cs-fixer on the codebase" start-server: stop-server node tests/server.js &> /dev/null & @@ -56,4 +61,18 @@ tag: package: php build/packager.php +static: static-phpstan static-codestyle-check + +static-phpstan: + docker run --rm -it -e REQUIRE_DEV=true -v ${PWD}:/app -w /app oskarstark/phpstan-ga:0.12.28 analyze $(PHPSTAN_PARAMS) + +static-phpstan-update-baseline: + $(MAKE) static-phpstan PHPSTAN_PARAMS="--generate-baseline" + +static-codestyle-fix: + docker run --rm -it -v ${PWD}:/app -w /app oskarstark/php-cs-fixer-ga:2.16.3.1 --diff-format udiff $(CS_PARAMS) + +static-codestyle-check: + $(MAKE) static-codestyle-fix CS_PARAMS="--dry-run" + .PHONY: docs burgomaster coverage-show view-coverage diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 747e2f637..6f81f2857 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -165,11 +165,6 @@ parameters: count: 1 path: src/Cookie/CookieJar.php - - - message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:count\\(\\) has no return typehint specified\\.$#" - count: 1 - path: src/Cookie/CookieJar.php - - message: "#^Method GuzzleHttp\\\\Cookie\\\\CookieJar\\:\\:getIterator\\(\\) return type has no value type specified in iterable type Traversable\\\\.$#" count: 1 @@ -320,21 +315,11 @@ parameters: count: 1 path: src/Exception/BadResponseException.php - - - message: "#^Method GuzzleHttp\\\\Exception\\\\BadResponseException\\:\\:__construct\\(\\) has parameter \\$message with no typehint specified\\.$#" - count: 1 - path: src/Exception/BadResponseException.php - - message: "#^Method GuzzleHttp\\\\Exception\\\\ConnectException\\:\\:__construct\\(\\) has parameter \\$handlerContext with no value type specified in iterable type array\\.$#" count: 1 path: src/Exception/ConnectException.php - - - message: "#^Method GuzzleHttp\\\\Exception\\\\ConnectException\\:\\:__construct\\(\\) has parameter \\$message with no typehint specified\\.$#" - count: 1 - path: src/Exception/ConnectException.php - - message: "#^Property GuzzleHttp\\\\Exception\\\\RequestException\\:\\:\\$handlerContext type has no value type specified in iterable type array\\.$#" count: 1 @@ -345,11 +330,6 @@ parameters: count: 1 path: src/Exception/RequestException.php - - - message: "#^Method GuzzleHttp\\\\Exception\\\\RequestException\\:\\:__construct\\(\\) has parameter \\$message with no typehint specified\\.$#" - count: 1 - path: src/Exception/RequestException.php - - message: "#^Method GuzzleHttp\\\\Exception\\\\RequestException\\:\\:create\\(\\) has parameter \\$ctx with no value type specified in iterable type array\\.$#" count: 1 From 9d4290de1cfd701f38099ef7e183b64b4b7b0c5e Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Tue, 16 Jun 2020 23:01:06 +0200 Subject: [PATCH 137/141] Prepare 6.5.5 (#2692) --- CHANGELOG.md | 2 +- src/ClientInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 683c55946..464cf1c50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## 6.5.5 - UNRELEASED +## 6.5.5 - 2020-06-16 * Unpin version constraint for `symfony/polyfill-intl-idn` [#2678](https://github.com/guzzle/guzzle/pull/2678) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 54c759b96..638b75dca 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -15,7 +15,7 @@ interface ClientInterface /** * @deprecated Will be removed in Guzzle 7.0.0 */ - const VERSION = '6.5.4'; + const VERSION = '6.5.5'; /** * Send an HTTP request. From e8ed4dbf49b260ff129ff0e0400718c3269971bf Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Thu, 2 Jul 2020 07:52:04 +0100 Subject: [PATCH 138/141] Fixed tests (#2720) --- tests/ClientTest.php | 2 +- tests/Exception/RequestExceptionTest.php | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index cf4fcccde..65f09bd1e 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -752,7 +752,7 @@ public function testIdnStaysTheSameWhenConversionIsDisabled() /** * @expectedException \GuzzleHttp\Exception\InvalidArgumentException - * @expectedExceptionMessage IDN conversion failed (errors: IDNA_ERROR_LEADING_HYPHEN) + * @expectedExceptionMessage IDN conversion failed */ public function testExceptionOnInvalidIdn() { diff --git a/tests/Exception/RequestExceptionTest.php b/tests/Exception/RequestExceptionTest.php index d52a0be80..64d50d671 100644 --- a/tests/Exception/RequestExceptionTest.php +++ b/tests/Exception/RequestExceptionTest.php @@ -126,21 +126,6 @@ public function testExceptionMessageIgnoresEmptyBody() self::assertStringEndsWith('response', $e->getMessage()); } - public function testCreatesExceptionWithoutPrintableBody() - { - $response = new Response( - 500, - ['Content-Type' => 'image/gif'], - $content = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7') // 1x1 gif - ); - $e = RequestException::create(new Request('GET', '/'), $response); - self::assertNotContains( - $content, - $e->getMessage() - ); - self::assertInstanceOf('GuzzleHttp\Exception\RequestException', $e); - } - public function testHasStatusCodeAsExceptionCode() { $e = RequestException::create(new Request('GET', '/'), new Response(442)); From f092dd734083473658de3ee4bef093ed77d2689c Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 25 May 2022 14:19:12 +0100 Subject: [PATCH 139/141] [6.x] Fix cross-domain cookie leakage (#3017) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tim Düsterhus <209270+TimWolla@users.noreply.github.com> --- .gitattributes | 7 ++-- .github/workflows/ci.yml | 70 ++++++++++++++++++++++++++++++++++ .github/workflows/static.yml | 36 ----------------- .travis.yml | 56 --------------------------- CHANGELOG.md | 4 ++ LICENSE | 10 ++++- README.md | 23 ++++++----- composer.json | 30 +++++++++++++++ src/Cookie/CookieJar.php | 5 +++ src/Cookie/SetCookie.php | 11 +++++- tests/Cookie/CookieJarTest.php | 37 ++++++++++++++++-- 11 files changed, 176 insertions(+), 113 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/static.yml delete mode 100644 .travis.yml diff --git a/.gitattributes b/.gitattributes index 160a6002c..ba1c92ba3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,7 @@ -.editorconfig export-ignore -.gitattributes export-ignore +.editorconfig export-ignore +.gitattributes export-ignore /.github/ export-ignore -.gitignore export-ignore -/.travis.yml export-ignore +.gitignore export-ignore /build/ export-ignore /docs/ export-ignore /Makefile export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..88649df2e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,70 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + +jobs: + build-lowest: + name: Build lowest + runs-on: ubuntu-latest + + steps: + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '5.5' + coverage: none + extensions: mbstring, intl + + - name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: '14.x' + + - name: Setup Problem Matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download dependencies + run: composer update --no-interaction --no-progress --prefer-stable --prefer-lowest + + - name: Run tests + run: make test + + build: + name: Build + runs-on: ubuntu-latest + strategy: + max-parallel: 10 + matrix: + php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] + + steps: + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + extensions: mbstring, intl + + - name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: '14.x' + + - name: Setup Problem Matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download dependencies + run: composer update --no-interaction --no-progress + + - name: Run tests + run: make test diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml deleted file mode 100644 index 8948130b6..000000000 --- a/.github/workflows/static.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Static analysis - -on: - push: - branches: - - master - pull_request: - -jobs: - phpstan: - name: PHPStan - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: PHPStan - uses: OskarStark/phpstan-ga@0.12.28 - env: - REQUIRE_DEV: true - with: - args: analyze --no-progress - - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: PHP-CS-Fixer - uses: OskarStark/php-cs-fixer-ga@2.16.3.1 - with: - args: --dry-run --diff-format udiff diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 96955d9d0..000000000 --- a/.travis.yml +++ /dev/null @@ -1,56 +0,0 @@ -language: php - -matrix: - include: - - php: 5.5 - dist: trusty - - php: 5.6 - dist: xenial - - php: 7.0 - dist: xenial - - php: 7.1 - dist: bionic - - php: 7.2 - dist: bionic - - php: 7.3 - dist: bionic - - php: 7.4 - dist: bionic - - php: nightly - dist: bionic - env: COMPOSER_ARGS="--ignore-platform-reqs" - - php: hhvm-3.24 - dist: trusty - allow_failures: - - php: hhvm-3.24 - - php: nightly - fast_finish: true - -install: - - if [[ "$TRAVIS_PHP_VERSION" != "hhvm-3.24" || "$TRAVIS_PHP_VERSION" != "nightly" ]]; then echo "xdebug.overload_var_dump = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini || true; fi - - composer install --prefer-dist $COMPOSER_ARGS - - ~/.nvm/nvm.sh install v10.18.0 - - ~/.nvm/nvm.sh run v10.18.0 - -before_script: - - curl --version - -script: - - make test - -before_deploy: - - make package - -deploy: - provider: releases - skip_cleanup: true - api_key: - secure: mz9H1B4cPH7dW9hTzgHnbh75+HJ6fJZ9S/1nMWFaqgj5C0wDzTqkJ+BbwiCEiqXGh6VGZbM4EmO1/wnZ7B+Hk8zsB1PP+GKVkq8+7a/261o60W3OS4gQpZQ9R68dyEO1EyZBJvL1Lzc03rkt/0WnKiAjg7nsc1j4aLKhWMDQ6x8= - file: - - build/artifacts/guzzle.phar - - build/artifacts/guzzle.zip - on: - repo: guzzle/guzzle - tags: true - all_branches: true - php: 5.5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 464cf1c50..95d26df21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 6.5.6 - 2022-05-25 + +* Fix cross-domain cookie leakage + ## 6.5.5 - 2020-06-16 * Unpin version constraint for `symfony/polyfill-intl-idn` [#2678](https://github.com/guzzle/guzzle/pull/2678) diff --git a/LICENSE b/LICENSE index 50a177b03..fd2375d88 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,12 @@ -Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling +The MIT License (MIT) + +Copyright (c) 2011 Michael Dowling +Copyright (c) 2012 Jeremy Lindblom +Copyright (c) 2014 Graham Campbell +Copyright (c) 2015 Márk Sági-Kazár +Copyright (c) 2015 Tobias Schultze +Copyright (c) 2016 Tobias Nyholm +Copyright (c) 2016 George Mponos Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 5fdb6c5f4..00d2066e9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Guzzle, PHP HTTP client ======================= [![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases) -[![Build Status](https://img.shields.io/travis/guzzle/guzzle.svg?style=flat-square)](https://travis-ci.org/guzzle/guzzle) +[![Build Status](https://img.shields.io/github/workflow/status/guzzle/guzzle/CI?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI) [![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle) Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and @@ -74,17 +74,20 @@ composer update ## Version Guidance -| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version | -|---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------| -| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >= 5.3.3 | -| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >= 5.4 | -| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >= 5.4 | -| 6.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >= 5.5 | +| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version | +|---------|----------------|---------------------|--------------|---------------------|---------------------|-------|--------------| +| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 | +| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 | +| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 | +| 6.x | Security fixes | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 | +| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.2 | [guzzle-3-repo]: https://github.com/guzzle/guzzle3 [guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3 -[guzzle-6-repo]: https://github.com/guzzle/guzzle +[guzzle-6-repo]: https://github.com/guzzle/guzzle/tree/6.5 +[guzzle-7-repo]: https://github.com/guzzle/guzzle [guzzle-3-docs]: http://guzzle3.readthedocs.org -[guzzle-5-docs]: http://guzzle.readthedocs.org/en/5.3/ -[guzzle-6-docs]: http://guzzle.readthedocs.org/en/latest/ +[guzzle-5-docs]: http://docs.guzzlephp.org/en/5.3/ +[guzzle-6-docs]: http://docs.guzzlephp.org/en/6.5/ +[guzzle-7-docs]: http://docs.guzzlephp.org/en/latest/ diff --git a/composer.json b/composer.json index c01864f01..b9cb386a6 100644 --- a/composer.json +++ b/composer.json @@ -14,10 +14,40 @@ "homepage": "http://guzzlephp.org/", "license": "MIT", "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], "require": { diff --git a/src/Cookie/CookieJar.php b/src/Cookie/CookieJar.php index 38f98ad7c..394df3a7c 100644 --- a/src/Cookie/CookieJar.php +++ b/src/Cookie/CookieJar.php @@ -240,6 +240,11 @@ public function extractCookies( if (0 !== strpos($sc->getPath(), '/')) { $sc->setPath($this->getCookiePathFromRequest($request)); } + if (!$sc->matchesDomain($request->getUri()->getHost())) { + continue; + } + // Note: At this point `$sc->getDomain()` being a public suffix should + // be rejected, but we don't want to pull in the full PSL dependency. $this->setCookie($sc); } } diff --git a/src/Cookie/SetCookie.php b/src/Cookie/SetCookie.php index 3d776a70b..55f6901a7 100644 --- a/src/Cookie/SetCookie.php +++ b/src/Cookie/SetCookie.php @@ -333,12 +333,19 @@ public function matchesPath($requestPath) */ public function matchesDomain($domain) { + $cookieDomain = $this->getDomain(); + if (null === $cookieDomain) { + return true; + } + // Remove the leading '.' as per spec in RFC 6265. // http://tools.ietf.org/html/rfc6265#section-5.2.3 - $cookieDomain = ltrim($this->getDomain(), '.'); + $cookieDomain = ltrim(strtolower($cookieDomain), '.'); + + $domain = strtolower($domain); // Domain not set or exact match. - if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { + if ('' === $cookieDomain || $domain === $cookieDomain) { return true; } diff --git a/tests/Cookie/CookieJarTest.php b/tests/Cookie/CookieJarTest.php index 873999cf9..1e9c84c92 100644 --- a/tests/Cookie/CookieJarTest.php +++ b/tests/Cookie/CookieJarTest.php @@ -385,9 +385,6 @@ public function getCookiePathsDataProvider() ['/foo', '/'], ['/foo/bar', '/foo'], ['/foo/bar/', '/foo/bar'], - ['foo', '/'], - ['foo/bar', '/'], - ['foo/bar/', '/'], ]; } @@ -406,13 +403,45 @@ public function testCookiePathWithEmptySetCookiePath($uriPath, $cookiePath) "bar=foo; expires={$this->futureExpirationDate()}; domain=www.example.com; path=foobar;" ) ; - $request = (new Request('GET', $uriPath))->withHeader('Host', 'www.example.com'); + $request = (new Request('GET', "https://www.example.com{$uriPath}")); $this->jar->extractCookies($request, $response); self::assertSame($cookiePath, $this->jar->toArray()[0]['Path']); self::assertSame($cookiePath, $this->jar->toArray()[1]['Path']); } + public function getDomainMatchesProvider() + { + return [ + ['www.example.com', 'www.example.com', true], + ['www.example.com', 'www.EXAMPLE.com', true], + ['www.example.com', 'www.example.net', false], + ['www.example.com', 'ftp.example.com', false], + ['www.example.com', 'example.com', true], + ['www.example.com', 'EXAMPLE.com', true], + ['fra.de.example.com', 'EXAMPLE.com', true], + ['www.EXAMPLE.com', 'www.example.com', true], + ['www.EXAMPLE.com', 'www.example.COM', true], + ]; + } + + /** + * @dataProvider getDomainMatchesProvider + */ + public function testIgnoresCookiesForMismatchingDomains($requestHost, $domainAttribute, $matches) + { + $response = (new Response(200)) + ->withAddedHeader( + 'Set-Cookie', + "foo=bar; expires={$this->futureExpirationDate()}; domain={$domainAttribute}; path=/;" + ) + ; + $request = (new Request('GET', "https://{$requestHost}/")); + $this->jar->extractCookies($request, $response); + + self::assertCount($matches ? 1 : 0, $this->jar->toArray()); + } + private function futureExpirationDate() { return (new DateTimeImmutable)->add(new DateInterval('P1D'))->format(DateTime::COOKIE); From 724562fa861e21a4071c652c8a159934e4f05592 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Thu, 9 Jun 2022 22:36:50 +0100 Subject: [PATCH 140/141] Release 6.5.7 (#3022) --- CHANGELOG.md | 5 +++++ src/RedirectMiddleware.php | 38 +++++++++++++++++++++++++++----- tests/RedirectMiddlewareTest.php | 37 +++++++++++++++++-------------- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95d26df21..cd3db22d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 6.5.7 - 2022-06-09 + +* Fix failure to strip Authorization header on HTTP downgrade +* Fix failure to strip the Cookie header on change in host or HTTP downgrade + ## 6.5.6 - 2022-05-25 * Fix cross-domain cookie leakage diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index e4644b7ac..fd86c60a7 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -141,7 +141,7 @@ function (ResponseInterface $response) use ($uri, $statusCode) { } /** - * Check for too many redirects + * Check for too many redirects. * * @return void * @@ -190,7 +190,7 @@ public function modifyRequest( $modify['body'] = ''; } - $uri = $this->redirectUri($request, $response, $protocols); + $uri = self::redirectUri($request, $response, $protocols); if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion']; $uri = Utils::idnUriConvert($uri, $idnOptions); @@ -210,16 +210,42 @@ public function modifyRequest( $modify['remove_headers'][] = 'Referer'; } - // Remove Authorization header if host is different. - if ($request->getUri()->getHost() !== $modify['uri']->getHost()) { + // Remove Authorization and Cookie headers if required. + if (self::shouldStripSensitiveHeaders($request->getUri(), $modify['uri'])) { $modify['remove_headers'][] = 'Authorization'; + $modify['remove_headers'][] = 'Cookie'; } return Psr7\modify_request($request, $modify); } /** - * Set the appropriate URL on the request based on the location header + * Determine if we should strip sensitive headers from the request. + * + * We return true if either of the following conditions are true: + * + * 1. the host is different; + * 2. the scheme has changed, and now is non-https. + * + * @return bool + */ + private static function shouldStripSensitiveHeaders( + UriInterface $originalUri, + UriInterface $modifiedUri + ) { + if (strcasecmp($originalUri->getHost(), $modifiedUri->getHost()) !== 0) { + return true; + } + + if ($originalUri->getScheme() !== $modifiedUri->getScheme() && 'https' !== $modifiedUri->getScheme()) { + return true; + } + + return false; + } + + /** + * Set the appropriate URL on the request based on the location header. * * @param RequestInterface $request * @param ResponseInterface $response @@ -227,7 +253,7 @@ public function modifyRequest( * * @return UriInterface */ - private function redirectUri( + private static function redirectUri( RequestInterface $request, ResponseInterface $response, array $protocols diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index e74f713d2..fc830bacb 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -251,31 +251,36 @@ public function testInvokesOnRedirectForRedirects() self::assertTrue($call); } - public function testRemoveAuthorizationHeaderOnRedirect() + public function crossOriginRedirectProvider() { - $mock = new MockHandler([ - new Response(302, ['Location' => 'http://test.com']), - function (RequestInterface $request) { - self::assertFalse($request->hasHeader('Authorization')); - return new Response(200); - } - ]); - $handler = HandlerStack::create($mock); - $client = new Client(['handler' => $handler]); - $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass']]); + return [ + ['http://example.com?a=b', 'http://test.com/', false], + ['https://example.com?a=b', 'https://test.com/', false], + ['http://example.com?a=b', 'https://test.com/', false], + ['https://example.com?a=b', 'http://test.com/', false], + ['http://example.com?a=b', 'http://example.com/', true], + ['https://example.com?a=b', 'https://example.com/', true], + ['http://example.com?a=b', 'https://example.com/', true], + ['https://example.com?a=b', 'http://example.com/', false], + ]; } - public function testNotRemoveAuthorizationHeaderOnRedirect() + /** + * @dataProvider crossOriginRedirectProvider + */ + public function testHeadersTreatmentOnRedirect($originalUri, $targetUri, $shouldBePresent) { $mock = new MockHandler([ - new Response(302, ['Location' => 'http://example.com/2']), - function (RequestInterface $request) { - self::assertTrue($request->hasHeader('Authorization')); + new Response(302, ['Location' => $targetUri]), + function (RequestInterface $request) use ($shouldBePresent) { + self::assertSame($shouldBePresent, $request->hasHeader('Authorization')); + self::assertSame($shouldBePresent, $request->hasHeader('Cookie')); + return new Response(200); } ]); $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); - $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass']]); + $client->get($originalUri, ['auth' => ['testuser', 'testpass'], 'headers' => ['Cookie' => 'foo=bar']]); } } From a52f0440530b54fa079ce76e8c5d196a42cad981 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Mon, 20 Jun 2022 23:16:07 +0100 Subject: [PATCH 141/141] Release 6.5.8 (#3042) * Release 6.5.8 * Update README.md * Update RedirectMiddleware.php --- CHANGELOG.md | 5 + README.md | 22 ++-- composer.json | 9 +- src/RedirectMiddleware.php | 37 ++----- tests/RedirectMiddlewareTest.php | 177 ++++++++++++++++++++++++++++--- 5 files changed, 199 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd3db22d8..b053017a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 6.5.8 - 2022-06-20 + +* Fix change in port should be considered a change in origin +* Fix `CURLOPT_HTTPAUTH` option not cleared on change of origin + ## 6.5.7 - 2022-06-09 * Fix failure to strip Authorization header on HTTP downgrade diff --git a/README.md b/README.md index 00d2066e9..bc98e1a10 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -Guzzle, PHP HTTP client -======================= +![Guzzle](.github/logo.png?raw=true) + +# Guzzle, PHP HTTP client [![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases) [![Build Status](https://img.shields.io/github/workflow/status/guzzle/guzzle/CI?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI) @@ -38,15 +39,18 @@ $promise->wait(); ## Help and docs -- [Documentation](http://guzzlephp.org/) -- [Stack Overflow](http://stackoverflow.com/questions/tagged/guzzle) +We use GitHub issues only to discuss bugs and new features. For support please refer to: + +- [Documentation](https://docs.guzzlephp.org) +- [Stack Overflow](https://stackoverflow.com/questions/tagged/guzzle) +- [#guzzle](https://app.slack.com/client/T0D2S9JCT/CE6UAAKL4) channel on [PHP-HTTP Slack](https://slack.httplug.io/) - [Gitter](https://gitter.im/guzzle/guzzle) ## Installing Guzzle The recommended way to install Guzzle is through -[Composer](http://getcomposer.org). +[Composer](https://getcomposer.org/). ```bash # Install Composer @@ -87,7 +91,7 @@ composer update [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3 [guzzle-6-repo]: https://github.com/guzzle/guzzle/tree/6.5 [guzzle-7-repo]: https://github.com/guzzle/guzzle -[guzzle-3-docs]: http://guzzle3.readthedocs.org -[guzzle-5-docs]: http://docs.guzzlephp.org/en/5.3/ -[guzzle-6-docs]: http://docs.guzzlephp.org/en/6.5/ -[guzzle-7-docs]: http://docs.guzzlephp.org/en/latest/ +[guzzle-3-docs]: https://guzzle3.readthedocs.io/ +[guzzle-5-docs]: https://docs.guzzlephp.org/en/5.3/ +[guzzle-6-docs]: https://docs.guzzlephp.org/en/6.5/ +[guzzle-7-docs]: https://docs.guzzlephp.org/en/latest/ diff --git a/composer.json b/composer.json index b9cb386a6..a57d78f60 100644 --- a/composer.json +++ b/composer.json @@ -53,9 +53,9 @@ "require": { "php": ">=5.5", "ext-json": "*", - "symfony/polyfill-intl-idn": "^1.17.0", + "symfony/polyfill-intl-idn": "^1.17", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1" + "guzzlehttp/psr7": "^1.9" }, "require-dev": { "ext-curl": "*", @@ -66,7 +66,10 @@ "psr/log": "Required for using the Log middleware" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "bamarni/composer-bin-plugin": true + } }, "extra": { "branch-alias": { diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index fd86c60a7..008a29b8c 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -94,6 +94,14 @@ public function checkRedirect( $this->guardMax($request, $options); $nextRequest = $this->modifyRequest($request, $options, $response); + // If authorization is handled by curl, unset it if URI is cross-origin. + if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $nextRequest->getUri()) && defined('\CURLOPT_HTTPAUTH')) { + unset( + $options['curl'][\CURLOPT_HTTPAUTH], + $options['curl'][\CURLOPT_USERPWD] + ); + } + if (isset($options['allow_redirects']['on_redirect'])) { call_user_func( $options['allow_redirects']['on_redirect'], @@ -210,8 +218,8 @@ public function modifyRequest( $modify['remove_headers'][] = 'Referer'; } - // Remove Authorization and Cookie headers if required. - if (self::shouldStripSensitiveHeaders($request->getUri(), $modify['uri'])) { + // Remove Authorization and Cookie headers if URI is cross-origin. + if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $modify['uri'])) { $modify['remove_headers'][] = 'Authorization'; $modify['remove_headers'][] = 'Cookie'; } @@ -219,31 +227,6 @@ public function modifyRequest( return Psr7\modify_request($request, $modify); } - /** - * Determine if we should strip sensitive headers from the request. - * - * We return true if either of the following conditions are true: - * - * 1. the host is different; - * 2. the scheme has changed, and now is non-https. - * - * @return bool - */ - private static function shouldStripSensitiveHeaders( - UriInterface $originalUri, - UriInterface $modifiedUri - ) { - if (strcasecmp($originalUri->getHost(), $modifiedUri->getHost()) !== 0) { - return true; - } - - if ($originalUri->getScheme() !== $modifiedUri->getScheme() && 'https' !== $modifiedUri->getScheme()) { - return true; - } - - return false; - } - /** * Set the appropriate URL on the request based on the location header. * diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index fc830bacb..73f333a27 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -251,30 +251,183 @@ public function testInvokesOnRedirectForRedirects() self::assertTrue($call); } + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testRemoveCurlAuthorizationOptionsOnRedirectCrossHost($auth) + { + if (!defined('\CURLOPT_HTTPAUTH')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://test.com']), + static function (RequestInterface $request, $options) { + self::assertFalse( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options still contain CURLOPT_HTTPAUTH entry' + ); + self::assertFalse( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options still contain CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testRemoveCurlAuthorizationOptionsOnRedirectCrossPort($auth) + { + if (!defined('\CURLOPT_HTTPAUTH')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://example.com:81/']), + static function (RequestInterface $request, $options) { + self::assertFalse( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options still contain CURLOPT_HTTPAUTH entry' + ); + self::assertFalse( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options still contain CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testRemoveCurlAuthorizationOptionsOnRedirectCrossScheme($auth) + { + if (!defined('\CURLOPT_HTTPAUTH')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://example.com?a=b']), + static function (RequestInterface $request, $options) { + self::assertFalse( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options still contain CURLOPT_HTTPAUTH entry' + ); + self::assertFalse( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options still contain CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('https://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testRemoveCurlAuthorizationOptionsOnRedirectCrossSchemeSamePort($auth) + { + if (!defined('\CURLOPT_HTTPAUTH')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://example.com:80?a=b']), + static function (RequestInterface $request, $options) { + self::assertFalse( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options still contain CURLOPT_HTTPAUTH entry' + ); + self::assertFalse( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options still contain CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('https://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testNotRemoveCurlAuthorizationOptionsOnRedirect($auth) + { + if (!defined('\CURLOPT_HTTPAUTH') || !defined('\CURLOPT_USERPWD')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://example.com/2']), + static function (RequestInterface $request, $options) { + self::assertTrue( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options does not contain expected CURLOPT_HTTPAUTH entry' + ); + self::assertTrue( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options does not contain expected CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + public function crossOriginRedirectProvider() { return [ - ['http://example.com?a=b', 'http://test.com/', false], - ['https://example.com?a=b', 'https://test.com/', false], - ['http://example.com?a=b', 'https://test.com/', false], - ['https://example.com?a=b', 'http://test.com/', false], - ['http://example.com?a=b', 'http://example.com/', true], - ['https://example.com?a=b', 'https://example.com/', true], - ['http://example.com?a=b', 'https://example.com/', true], - ['https://example.com?a=b', 'http://example.com/', false], + ['http://example.com/123', 'http://example.com/', false], + ['http://example.com/123', 'http://example.com:80/', false], + ['http://example.com:80/123', 'http://example.com/', false], + ['http://example.com:80/123', 'http://example.com:80/', false], + ['http://example.com/123', 'https://example.com/', true], + ['http://example.com/123', 'http://www.example.com/', true], + ['http://example.com/123', 'http://example.com:81/', true], + ['http://example.com:80/123', 'http://example.com:81/', true], + ['https://example.com/123', 'https://example.com/', false], + ['https://example.com/123', 'https://example.com:443/', false], + ['https://example.com:443/123', 'https://example.com/', false], + ['https://example.com:443/123', 'https://example.com:443/', false], + ['https://example.com/123', 'http://example.com/', true], + ['https://example.com/123', 'https://www.example.com/', true], + ['https://example.com/123', 'https://example.com:444/', true], + ['https://example.com:443/123', 'https://example.com:444/', true], ]; } /** * @dataProvider crossOriginRedirectProvider */ - public function testHeadersTreatmentOnRedirect($originalUri, $targetUri, $shouldBePresent) + public function testHeadersTreatmentOnRedirect($originalUri, $targetUri, $isCrossOrigin) { $mock = new MockHandler([ new Response(302, ['Location' => $targetUri]), - function (RequestInterface $request) use ($shouldBePresent) { - self::assertSame($shouldBePresent, $request->hasHeader('Authorization')); - self::assertSame($shouldBePresent, $request->hasHeader('Cookie')); + function (RequestInterface $request) use ($isCrossOrigin) { + self::assertSame(!$isCrossOrigin, $request->hasHeader('Authorization')); + self::assertSame(!$isCrossOrigin, $request->hasHeader('Cookie')); return new Response(200); }