diff --git a/composer.json b/composer.json index 907743905..9b2e04f93 100644 --- a/composer.json +++ b/composer.json @@ -20,11 +20,11 @@ "deepdiver1975/tarstreamer": "v2.0.0", "doctrine/dbal": "2.12.0", "egulias/email-validator": "2.1.25", - "guzzlehttp/guzzle": "6.5.5", + "guzzlehttp/guzzle": "^7.2", "icewind/searchdav": "^2.0.0", "icewind/streams": "v0.7.2", "league/flysystem": "^1.0", - "microsoft/azure-storage-blob": "1.5.0", + "microsoft/azure-storage-blob": "^1.5", "nextcloud/lognormalizer": "^1.0", "nikic/php-parser": "^4.2", "patchwork/jsqueeze": "^2.0", @@ -32,7 +32,8 @@ "pear/archive_tar": "^1.4.9", "pear/pear-core-minimal": "^v1.10", "phpseclib/phpseclib": "2.0.25", - "php-opencloud/openstack": "3.0.7", + "php-http/guzzle7-adapter": "^0.1.1", + "php-opencloud/openstack": "^3.1", "pimple/pimple": "3.2.3", "psr/container": "^1.0", "punic/punic": "^1.6", @@ -46,7 +47,6 @@ "symfony/process": "4.4.18", "symfony/routing": "4.4.18", "symfony/translation": "4.4.18", - "php-http/guzzle6-adapter": "^2.0", "web-auth/webauthn-lib": "^3.1", "php-ds/php-ds": "^1.3", "opis/closure": "^3.6", diff --git a/composer.lock b/composer.lock index 9fb579e15..2fc702f07 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "debf706a7e288e46deee2d1645ffaffd", + "content-hash": "010eddd49ee5c61d7f8f44fdce19e66f", "packages": [ { "name": "aws/aws-sdk-php", @@ -944,37 +944,43 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.5", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.17.0" + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", "psr/log": "^1.1" }, "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.5-dev" + "dev-master": "7.1-dev" } }, "autoload": { @@ -994,6 +1000,11 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "Guzzle is a PHP HTTP client library", @@ -1004,14 +1015,34 @@ "framework", "http", "http client", + "psr-18", + "psr-7", "rest", "web service" ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/6.5" + "source": "https://github.com/guzzle/guzzle/tree/7.2.0" }, - "time": "2020-06-16T21:01:06+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2020-10-10T11:47:56+00:00" }, { "name": "guzzlehttp/promises", @@ -1143,6 +1174,73 @@ }, "time": "2020-09-30T07:37:11+00:00" }, + { + "name": "guzzlehttp/uri-template", + "version": "v0.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "db46525d6d8fee71033b73cc07160f3e5271a8ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/db46525d6d8fee71033b73cc07160f3e5271a8ce", + "reference": "db46525d6d8fee71033b73cc07160f3e5271a8ce", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos", + "role": "Developer" + } + ], + "description": "A polyfill class for uri_template of PHP", + "homepage": "https://github.com/guzzlehttp/uri-template", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/master" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2020-07-21T13:45:09+00:00" + }, { "name": "icewind/searchdav", "version": "v2.0.0", @@ -1229,16 +1327,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.2.9", + "version": "5.2.10", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "44c6787311242a979fa15c704327c20e7221a0e4" + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4", - "reference": "44c6787311242a979fa15c704327c20e7221a0e4", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", "shasum": "" }, "require": { @@ -1291,7 +1389,11 @@ "json", "schema" ], - "time": "2019-09-25T14:49:45+00:00" + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + }, + "time": "2020-05-27T16:41:55+00:00" }, { "name": "league/flysystem", @@ -1597,20 +1699,20 @@ }, { "name": "microsoft/azure-storage-blob", - "version": "1.5.0", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/Azure/azure-storage-blob-php.git", - "reference": "6a333cd28a3742c3e99e79042dc6510f9f917919" + "reference": "2475330963372d519387cb8135d6a9cfd42272da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/6a333cd28a3742c3e99e79042dc6510f9f917919", - "reference": "6a333cd28a3742c3e99e79042dc6510f9f917919", + "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/2475330963372d519387cb8135d6a9cfd42272da", + "reference": "2475330963372d519387cb8135d6a9cfd42272da", "shasum": "" }, "require": { - "microsoft/azure-storage-common": "~1.4", + "microsoft/azure-storage-common": "~1.5", "php": ">=5.6.0" }, "type": "library", @@ -1637,24 +1739,28 @@ "sdk", "storage" ], - "time": "2020-01-02T07:18:59+00:00" + "support": { + "issues": "https://github.com/Azure/azure-storage-blob-php/issues", + "source": "https://github.com/Azure/azure-storage-blob-php/tree/v1.5.2" + }, + "time": "2020-12-29T02:22:11+00:00" }, { "name": "microsoft/azure-storage-common", - "version": "1.4.1", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/Azure/azure-storage-common-php.git", - "reference": "be4df800761d0d0fa91a9460c7f42517197d57a0" + "reference": "e5738035891546075bd369954e8af121d65ebd6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/be4df800761d0d0fa91a9460c7f42517197d57a0", - "reference": "be4df800761d0d0fa91a9460c7f42517197d57a0", + "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/e5738035891546075bd369954e8af121d65ebd6d", + "reference": "e5738035891546075bd369954e8af121d65ebd6d", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "~6.0", + "guzzlehttp/guzzle": "~6.0|^7.0", "php": ">=5.6.0" }, "type": "library", @@ -1681,7 +1787,11 @@ "sdk", "storage" ], - "time": "2020-01-02T07:15:54+00:00" + "support": { + "issues": "https://github.com/Azure/azure-storage-common-php/issues", + "source": "https://github.com/Azure/azure-storage-common-php/tree/v1.5.1" + }, + "time": "2020-12-28T07:59:51+00:00" }, { "name": "mtdowling/jmespath.php", @@ -2350,22 +2460,22 @@ "time": "2020-10-14T04:23:31+00:00" }, { - "name": "php-http/guzzle6-adapter", - "version": "v2.0.1", + "name": "php-http/guzzle7-adapter", + "version": "0.1.1", "source": { "type": "git", - "url": "https://github.com/php-http/guzzle6-adapter.git", - "reference": "6074a4b1f4d5c21061b70bab3b8ad484282fe31f" + "url": "https://github.com/php-http/guzzle7-adapter.git", + "reference": "1967de656b9679a2a6a66d0e4e16fa99bbed1ad1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/guzzle6-adapter/zipball/6074a4b1f4d5c21061b70bab3b8ad484282fe31f", - "reference": "6074a4b1f4d5c21061b70bab3b8ad484282fe31f", + "url": "https://api.github.com/repos/php-http/guzzle7-adapter/zipball/1967de656b9679a2a6a66d0e4e16fa99bbed1ad1", + "reference": "1967de656b9679a2a6a66d0e4e16fa99bbed1ad1", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.0", - "php": "^7.1", + "guzzlehttp/guzzle": "^7.0", + "php": "^7.2 | ^8.0", "php-http/httplug": "^2.0", "psr/http-client": "^1.0" }, @@ -2375,19 +2485,18 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "ext-curl": "*", - "php-http/client-integration-tests": "^2.0", - "phpunit/phpunit": "^7.4" + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.0|^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "0.2.x-dev" } }, "autoload": { "psr-4": { - "Http\\Adapter\\Guzzle6\\": "src/" + "Http\\Adapter\\Guzzle7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2396,45 +2505,45 @@ ], "authors": [ { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - }, - { - "name": "David de Boer", - "email": "david@ddeboer.nl" + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" } ], - "description": "Guzzle 6 HTTP Adapter", + "description": "Guzzle 7 HTTP Adapter", "homepage": "http://httplug.io", "keywords": [ "Guzzle", "http" ], - "time": "2018-12-16T14:44:03+00:00" + "support": { + "issues": "https://github.com/php-http/guzzle7-adapter/issues", + "source": "https://github.com/php-http/guzzle7-adapter/tree/0.1.1" + }, + "time": "2020-10-21T17:30:51+00:00" }, { "name": "php-http/httplug", - "version": "2.1.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/php-http/httplug.git", - "reference": "72d2b129a48f0490d55b7f89be0d6aa0597ffb06" + "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/httplug/zipball/72d2b129a48f0490d55b7f89be0d6aa0597ffb06", - "reference": "72d2b129a48f0490d55b7f89be0d6aa0597ffb06", + "url": "https://api.github.com/repos/php-http/httplug/zipball/191a0a1b41ed026b717421931f8d3bd2514ffbf9", + "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9", "shasum": "" }, "require": { - "php": "^7.0", - "php-http/promise": "^1.0", + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", "psr/http-client": "^1.0", "psr/http-message": "^1.0" }, "require-dev": { "friends-of-phpspec/phpspec-code-coverage": "^4.1", - "phpspec/phpspec": "^4.3.4|^5.0|^6.0" + "phpspec/phpspec": "^5.1 || ^6.0" }, "type": "library", "extra": { @@ -2458,7 +2567,8 @@ }, { "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "HTTPlug, the HTTP client abstraction for PHP", @@ -2467,25 +2577,32 @@ "client", "http" ], - "time": "2019-12-27T10:07:11+00:00" + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/master" + }, + "time": "2020-07-13T15:43:23+00:00" }, { "name": "php-http/promise", - "version": "v1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-http/promise.git", - "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980" + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/dc494cdc9d7160b9a09bd5573272195242ce7980", - "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980", + "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", "shasum": "" }, + "require": { + "php": "^7.1 || ^8.0" + }, "require-dev": { - "henrikbjorn/phpspec-code-coverage": "^1.0", - "phpspec/phpspec": "^2.4" + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" }, "type": "library", "extra": { @@ -2503,13 +2620,13 @@ "MIT" ], "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - }, { "name": "Joel Wurtz", "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" } ], "description": "Promise used for asynchronous HTTP requests", @@ -2517,26 +2634,31 @@ "keywords": [ "promise" ], - "time": "2016-01-26T13:27:02+00:00" + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.1.0" + }, + "time": "2020-07-07T09:29:14+00:00" }, { "name": "php-opencloud/openstack", - "version": "v3.0.7", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/php-opencloud/openstack.git", - "reference": "5d73ff577731fc473448c489acfca9730aa39c88" + "reference": "7b0eeb63defe533fb802514af3c70855c45eaf1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-opencloud/openstack/zipball/5d73ff577731fc473448c489acfca9730aa39c88", - "reference": "5d73ff577731fc473448c489acfca9730aa39c88", + "url": "https://api.github.com/repos/php-opencloud/openstack/zipball/7b0eeb63defe533fb802514af3c70855c45eaf1e", + "reference": "7b0eeb63defe533fb802514af3c70855c45eaf1e", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.1", + "guzzlehttp/guzzle": "^7.0", + "guzzlehttp/uri-template": "0.2", "justinrainbow/json-schema": "^5.2", - "php": "~7.0" + "php": "^7.2.5" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.13", @@ -2580,7 +2702,11 @@ "php", "sdk" ], - "time": "2020-01-07T08:46:53+00:00" + "support": { + "issues": "https://github.com/php-opencloud/openstack/issues", + "source": "https://github.com/php-opencloud/openstack/tree/v3.1.0" + }, + "time": "2020-10-11T16:12:31+00:00" }, { "name": "phpseclib/phpseclib", @@ -3090,6 +3216,10 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { diff --git a/composer/InstalledVersions.php b/composer/InstalledVersions.php index d467023a9..88c923c59 100644 --- a/composer/InstalledVersions.php +++ b/composer/InstalledVersions.php @@ -29,7 +29,7 @@ class InstalledVersions 'aliases' => array ( ), - 'reference' => '7fd440b16ef3dc16447e4565246c00e981ab9298', + 'reference' => '225c51509edf9ab3557ce109c3762731e7863e10', 'name' => 'nextcloud/3rdparty', ), 'versions' => @@ -162,12 +162,12 @@ class InstalledVersions ), 'guzzlehttp/guzzle' => array ( - 'pretty_version' => '6.5.5', - 'version' => '6.5.5.0', + 'pretty_version' => '7.2.0', + 'version' => '7.2.0.0', 'aliases' => array ( ), - 'reference' => '9d4290de1cfd701f38099ef7e183b64b4b7b0c5e', + 'reference' => '0aa74dfb41ae110835923ef10a9d803a22d50e79', ), 'guzzlehttp/promises' => array ( @@ -187,6 +187,15 @@ class InstalledVersions ), 'reference' => '53330f47520498c0ae1f61f7e2c90f55690c06a3', ), + 'guzzlehttp/uri-template' => + array ( + 'pretty_version' => 'v0.2.0', + 'version' => '0.2.0.0', + 'aliases' => + array ( + ), + 'reference' => 'db46525d6d8fee71033b73cc07160f3e5271a8ce', + ), 'icewind/searchdav' => array ( 'pretty_version' => 'v2.0.0', @@ -207,12 +216,12 @@ class InstalledVersions ), 'justinrainbow/json-schema' => array ( - 'pretty_version' => '5.2.9', - 'version' => '5.2.9.0', + 'pretty_version' => '5.2.10', + 'version' => '5.2.10.0', 'aliases' => array ( ), - 'reference' => '44c6787311242a979fa15c704327c20e7221a0e4', + 'reference' => '2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b', ), 'league/flysystem' => array ( @@ -252,21 +261,21 @@ class InstalledVersions ), 'microsoft/azure-storage-blob' => array ( - 'pretty_version' => '1.5.0', - 'version' => '1.5.0.0', + 'pretty_version' => '1.5.2', + 'version' => '1.5.2.0', 'aliases' => array ( ), - 'reference' => '6a333cd28a3742c3e99e79042dc6510f9f917919', + 'reference' => '2475330963372d519387cb8135d6a9cfd42272da', ), 'microsoft/azure-storage-common' => array ( - 'pretty_version' => '1.4.1', - 'version' => '1.4.1.0', + 'pretty_version' => '1.5.1', + 'version' => '1.5.1.0', 'aliases' => array ( ), - 'reference' => 'be4df800761d0d0fa91a9460c7f42517197d57a0', + 'reference' => 'e5738035891546075bd369954e8af121d65ebd6d', ), 'mtdowling/jmespath.php' => array ( @@ -284,7 +293,7 @@ class InstalledVersions 'aliases' => array ( ), - 'reference' => '7fd440b16ef3dc16447e4565246c00e981ab9298', + 'reference' => '225c51509edf9ab3557ce109c3762731e7863e10', ), 'nextcloud/lognormalizer' => array ( @@ -399,41 +408,41 @@ class InstalledVersions 0 => '1.0', ), ), - 'php-http/guzzle6-adapter' => + 'php-http/guzzle7-adapter' => array ( - 'pretty_version' => 'v2.0.1', - 'version' => '2.0.1.0', + 'pretty_version' => '0.1.1', + 'version' => '0.1.1.0', 'aliases' => array ( ), - 'reference' => '6074a4b1f4d5c21061b70bab3b8ad484282fe31f', + 'reference' => '1967de656b9679a2a6a66d0e4e16fa99bbed1ad1', ), 'php-http/httplug' => array ( - 'pretty_version' => '2.1.0', - 'version' => '2.1.0.0', + 'pretty_version' => '2.2.0', + 'version' => '2.2.0.0', 'aliases' => array ( ), - 'reference' => '72d2b129a48f0490d55b7f89be0d6aa0597ffb06', + 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9', ), 'php-http/promise' => array ( - 'pretty_version' => 'v1.0.0', - 'version' => '1.0.0.0', + 'pretty_version' => '1.1.0', + 'version' => '1.1.0.0', 'aliases' => array ( ), - 'reference' => 'dc494cdc9d7160b9a09bd5573272195242ce7980', + 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88', ), 'php-opencloud/openstack' => array ( - 'pretty_version' => 'v3.0.7', - 'version' => '3.0.7.0', + 'pretty_version' => 'v3.1.0', + 'version' => '3.1.0.0', 'aliases' => array ( ), - 'reference' => '5d73ff577731fc473448c489acfca9730aa39c88', + 'reference' => '7b0eeb63defe533fb802514af3c70855c45eaf1e', ), 'phpseclib/phpseclib' => array ( diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index bf341fcdf..c9f659aec 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -1223,8 +1223,11 @@ 'FG\\X509\\SAN\\IPAddress' => $vendorDir . '/fgrosse/phpasn1/lib/X509/SAN/IPAddress.php', 'FG\\X509\\SAN\\SubjectAlternativeNames' => $vendorDir . '/fgrosse/phpasn1/lib/X509/SAN/SubjectAlternativeNames.php', 'Giggsey\\Locale\\Locale' => $vendorDir . '/giggsey/locale/src/Locale.php', + 'GuzzleHttp\\BodySummarizer' => $vendorDir . '/guzzlehttp/guzzle/src/BodySummarizer.php', + 'GuzzleHttp\\BodySummarizerInterface' => $vendorDir . '/guzzlehttp/guzzle/src/BodySummarizerInterface.php', 'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php', 'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php', + 'GuzzleHttp\\ClientTrait' => $vendorDir . '/guzzlehttp/guzzle/src/ClientTrait.php', 'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', 'GuzzleHttp\\Cookie\\CookieJarInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php', 'GuzzleHttp\\Cookie\\FileCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php', @@ -1236,7 +1239,6 @@ 'GuzzleHttp\\Exception\\GuzzleException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/GuzzleException.php', 'GuzzleHttp\\Exception\\InvalidArgumentException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php', 'GuzzleHttp\\Exception\\RequestException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/RequestException.php', - 'GuzzleHttp\\Exception\\SeekException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/SeekException.php', 'GuzzleHttp\\Exception\\ServerException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ServerException.php', 'GuzzleHttp\\Exception\\TooManyRedirectsException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php', 'GuzzleHttp\\Exception\\TransferException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TransferException.php', @@ -1250,6 +1252,7 @@ 'GuzzleHttp\\Handler\\Proxy' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/Proxy.php', 'GuzzleHttp\\Handler\\StreamHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/StreamHandler.php', 'GuzzleHttp\\MessageFormatter' => $vendorDir . '/guzzlehttp/guzzle/src/MessageFormatter.php', + 'GuzzleHttp\\MessageFormatterInterface' => $vendorDir . '/guzzlehttp/guzzle/src/MessageFormatterInterface.php', 'GuzzleHttp\\Middleware' => $vendorDir . '/guzzlehttp/guzzle/src/Middleware.php', 'GuzzleHttp\\Pool' => $vendorDir . '/guzzlehttp/guzzle/src/Pool.php', 'GuzzleHttp\\PrepareBodyMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php', @@ -1301,11 +1304,11 @@ 'GuzzleHttp\\RequestOptions' => $vendorDir . '/guzzlehttp/guzzle/src/RequestOptions.php', 'GuzzleHttp\\RetryMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RetryMiddleware.php', 'GuzzleHttp\\TransferStats' => $vendorDir . '/guzzlehttp/guzzle/src/TransferStats.php', - 'GuzzleHttp\\UriTemplate' => $vendorDir . '/guzzlehttp/guzzle/src/UriTemplate.php', + 'GuzzleHttp\\UriTemplate\\UriTemplate' => $vendorDir . '/guzzlehttp/uri-template/src/UriTemplate.php', 'GuzzleHttp\\Utils' => $vendorDir . '/guzzlehttp/guzzle/src/Utils.php', - 'Http\\Adapter\\Guzzle6\\Client' => $vendorDir . '/php-http/guzzle6-adapter/src/Client.php', - 'Http\\Adapter\\Guzzle6\\Exception\\UnexpectedValueException' => $vendorDir . '/php-http/guzzle6-adapter/src/Exception/UnexpectedValueException.php', - 'Http\\Adapter\\Guzzle6\\Promise' => $vendorDir . '/php-http/guzzle6-adapter/src/Promise.php', + 'Http\\Adapter\\Guzzle7\\Client' => $vendorDir . '/php-http/guzzle7-adapter/src/Client.php', + 'Http\\Adapter\\Guzzle7\\Exception\\UnexpectedValueException' => $vendorDir . '/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php', + 'Http\\Adapter\\Guzzle7\\Promise' => $vendorDir . '/php-http/guzzle7-adapter/src/Promise.php', 'Http\\Client\\Exception' => $vendorDir . '/php-http/httplug/src/Exception.php', 'Http\\Client\\Exception\\HttpException' => $vendorDir . '/php-http/httplug/src/Exception/HttpException.php', 'Http\\Client\\Exception\\NetworkException' => $vendorDir . '/php-http/httplug/src/Exception/NetworkException.php', @@ -1555,6 +1558,7 @@ 'MicrosoftAzure\\Storage\\Blob\\Models\\SetBlobPropertiesOptions' => $vendorDir . '/microsoft/azure-storage-blob/src/Blob/Models/SetBlobPropertiesOptions.php', 'MicrosoftAzure\\Storage\\Blob\\Models\\SetBlobPropertiesResult' => $vendorDir . '/microsoft/azure-storage-blob/src/Blob/Models/SetBlobPropertiesResult.php', 'MicrosoftAzure\\Storage\\Blob\\Models\\SetBlobTierOptions' => $vendorDir . '/microsoft/azure-storage-blob/src/Blob/Models/SetBlobTierOptions.php', + 'MicrosoftAzure\\Storage\\Blob\\Models\\UndeleteBlobOptions' => $vendorDir . '/microsoft/azure-storage-blob/src/Blob/Models/UndeleteBlobOptions.php', 'MicrosoftAzure\\Storage\\Common\\CloudConfigurationManager' => $vendorDir . '/microsoft/azure-storage-common/src/Common/CloudConfigurationManager.php', 'MicrosoftAzure\\Storage\\Common\\Exceptions\\InvalidArgumentTypeException' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Exceptions/InvalidArgumentTypeException.php', 'MicrosoftAzure\\Storage\\Common\\Exceptions\\ServiceException' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Exceptions/ServiceException.php', @@ -1562,6 +1566,7 @@ 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\IAuthScheme' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/IAuthScheme.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\SharedAccessSignatureAuthScheme' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedAccessSignatureAuthScheme.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\SharedKeyAuthScheme' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedKeyAuthScheme.php', + 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\TokenAuthScheme' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/TokenAuthScheme.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\ConnectionStringParser' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/ConnectionStringParser.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\ConnectionStringSource' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/ConnectionStringSource.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\Http\\HttpCallContext' => $vendorDir . '/microsoft/azure-storage-common/src/Common/Internal/Http/HttpCallContext.php', diff --git a/composer/autoload_files.php b/composer/autoload_files.php index 111fb5f3b..20783adb3 100644 --- a/composer/autoload_files.php +++ b/composer/autoload_files.php @@ -10,19 +10,19 @@ '383eaff206634a77a1be54e64e6459c7' => $vendorDir . '/sabre/uri/lib/functions.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', - 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a4ecaeafb8cfb009ad0e052c90355e98' => $vendorDir . '/beberlei/assert/lib/Assert/functions.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', '2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php', 'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php', 'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php', '3569eecfeed3bcf0bad3c998a494ecb8' => $vendorDir . '/sabre/xml/lib/Deserializer/functions.php', '93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', + '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', + 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', 'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', 'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php', diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php index ed1f1b684..6f076c366 100644 --- a/composer/autoload_psr4.php +++ b/composer/autoload_psr4.php @@ -62,7 +62,8 @@ 'ID3Parser\\' => array($vendorDir . '/christophwurst/id3parser/src'), 'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'), 'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'), - 'Http\\Adapter\\Guzzle6\\' => array($vendorDir . '/php-http/guzzle6-adapter/src'), + 'Http\\Adapter\\Guzzle7\\' => array($vendorDir . '/php-http/guzzle7-adapter/src'), + 'GuzzleHttp\\UriTemplate\\' => array($vendorDir . '/guzzlehttp/uri-template/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), diff --git a/composer/autoload_static.php b/composer/autoload_static.php index c3975a306..d0b982fa8 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -11,19 +11,19 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 '383eaff206634a77a1be54e64e6459c7' => __DIR__ . '/..' . '/sabre/uri/lib/functions.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', - 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', - 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a4ecaeafb8cfb009ad0e052c90355e98' => __DIR__ . '/..' . '/beberlei/assert/lib/Assert/functions.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', '2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php', 'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php', 'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php', '3569eecfeed3bcf0bad3c998a494ecb8' => __DIR__ . '/..' . '/sabre/xml/lib/Deserializer/functions.php', '93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', + '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', + 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', 'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', 'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php', @@ -139,10 +139,11 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 array ( 'Http\\Promise\\' => 13, 'Http\\Client\\' => 12, - 'Http\\Adapter\\Guzzle6\\' => 21, + 'Http\\Adapter\\Guzzle7\\' => 21, ), 'G' => array ( + 'GuzzleHttp\\UriTemplate\\' => 23, 'GuzzleHttp\\Psr7\\' => 16, 'GuzzleHttp\\Promise\\' => 19, 'GuzzleHttp\\' => 11, @@ -409,9 +410,13 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 array ( 0 => __DIR__ . '/..' . '/php-http/httplug/src', ), - 'Http\\Adapter\\Guzzle6\\' => + 'Http\\Adapter\\Guzzle7\\' => + array ( + 0 => __DIR__ . '/..' . '/php-http/guzzle7-adapter/src', + ), + 'GuzzleHttp\\UriTemplate\\' => array ( - 0 => __DIR__ . '/..' . '/php-http/guzzle6-adapter/src', + 0 => __DIR__ . '/..' . '/guzzlehttp/uri-template/src', ), 'GuzzleHttp\\Psr7\\' => array ( @@ -1725,8 +1730,11 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'FG\\X509\\SAN\\IPAddress' => __DIR__ . '/..' . '/fgrosse/phpasn1/lib/X509/SAN/IPAddress.php', 'FG\\X509\\SAN\\SubjectAlternativeNames' => __DIR__ . '/..' . '/fgrosse/phpasn1/lib/X509/SAN/SubjectAlternativeNames.php', 'Giggsey\\Locale\\Locale' => __DIR__ . '/..' . '/giggsey/locale/src/Locale.php', + 'GuzzleHttp\\BodySummarizer' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/BodySummarizer.php', + 'GuzzleHttp\\BodySummarizerInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/BodySummarizerInterface.php', 'GuzzleHttp\\Client' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Client.php', 'GuzzleHttp\\ClientInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/ClientInterface.php', + 'GuzzleHttp\\ClientTrait' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/ClientTrait.php', 'GuzzleHttp\\Cookie\\CookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', 'GuzzleHttp\\Cookie\\CookieJarInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php', 'GuzzleHttp\\Cookie\\FileCookieJar' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php', @@ -1738,7 +1746,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'GuzzleHttp\\Exception\\GuzzleException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/GuzzleException.php', 'GuzzleHttp\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php', 'GuzzleHttp\\Exception\\RequestException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/RequestException.php', - 'GuzzleHttp\\Exception\\SeekException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/SeekException.php', 'GuzzleHttp\\Exception\\ServerException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/ServerException.php', 'GuzzleHttp\\Exception\\TooManyRedirectsException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php', 'GuzzleHttp\\Exception\\TransferException' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Exception/TransferException.php', @@ -1752,6 +1759,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'GuzzleHttp\\Handler\\Proxy' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Handler/Proxy.php', 'GuzzleHttp\\Handler\\StreamHandler' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Handler/StreamHandler.php', 'GuzzleHttp\\MessageFormatter' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/MessageFormatter.php', + 'GuzzleHttp\\MessageFormatterInterface' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/MessageFormatterInterface.php', 'GuzzleHttp\\Middleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Middleware.php', 'GuzzleHttp\\Pool' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Pool.php', 'GuzzleHttp\\PrepareBodyMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php', @@ -1803,11 +1811,11 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'GuzzleHttp\\RequestOptions' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RequestOptions.php', 'GuzzleHttp\\RetryMiddleware' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/RetryMiddleware.php', 'GuzzleHttp\\TransferStats' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/TransferStats.php', - 'GuzzleHttp\\UriTemplate' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/UriTemplate.php', + 'GuzzleHttp\\UriTemplate\\UriTemplate' => __DIR__ . '/..' . '/guzzlehttp/uri-template/src/UriTemplate.php', 'GuzzleHttp\\Utils' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/Utils.php', - 'Http\\Adapter\\Guzzle6\\Client' => __DIR__ . '/..' . '/php-http/guzzle6-adapter/src/Client.php', - 'Http\\Adapter\\Guzzle6\\Exception\\UnexpectedValueException' => __DIR__ . '/..' . '/php-http/guzzle6-adapter/src/Exception/UnexpectedValueException.php', - 'Http\\Adapter\\Guzzle6\\Promise' => __DIR__ . '/..' . '/php-http/guzzle6-adapter/src/Promise.php', + 'Http\\Adapter\\Guzzle7\\Client' => __DIR__ . '/..' . '/php-http/guzzle7-adapter/src/Client.php', + 'Http\\Adapter\\Guzzle7\\Exception\\UnexpectedValueException' => __DIR__ . '/..' . '/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php', + 'Http\\Adapter\\Guzzle7\\Promise' => __DIR__ . '/..' . '/php-http/guzzle7-adapter/src/Promise.php', 'Http\\Client\\Exception' => __DIR__ . '/..' . '/php-http/httplug/src/Exception.php', 'Http\\Client\\Exception\\HttpException' => __DIR__ . '/..' . '/php-http/httplug/src/Exception/HttpException.php', 'Http\\Client\\Exception\\NetworkException' => __DIR__ . '/..' . '/php-http/httplug/src/Exception/NetworkException.php', @@ -2057,6 +2065,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'MicrosoftAzure\\Storage\\Blob\\Models\\SetBlobPropertiesOptions' => __DIR__ . '/..' . '/microsoft/azure-storage-blob/src/Blob/Models/SetBlobPropertiesOptions.php', 'MicrosoftAzure\\Storage\\Blob\\Models\\SetBlobPropertiesResult' => __DIR__ . '/..' . '/microsoft/azure-storage-blob/src/Blob/Models/SetBlobPropertiesResult.php', 'MicrosoftAzure\\Storage\\Blob\\Models\\SetBlobTierOptions' => __DIR__ . '/..' . '/microsoft/azure-storage-blob/src/Blob/Models/SetBlobTierOptions.php', + 'MicrosoftAzure\\Storage\\Blob\\Models\\UndeleteBlobOptions' => __DIR__ . '/..' . '/microsoft/azure-storage-blob/src/Blob/Models/UndeleteBlobOptions.php', 'MicrosoftAzure\\Storage\\Common\\CloudConfigurationManager' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/CloudConfigurationManager.php', 'MicrosoftAzure\\Storage\\Common\\Exceptions\\InvalidArgumentTypeException' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Exceptions/InvalidArgumentTypeException.php', 'MicrosoftAzure\\Storage\\Common\\Exceptions\\ServiceException' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Exceptions/ServiceException.php', @@ -2064,6 +2073,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\IAuthScheme' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/IAuthScheme.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\SharedAccessSignatureAuthScheme' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedAccessSignatureAuthScheme.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\SharedKeyAuthScheme' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedKeyAuthScheme.php', + 'MicrosoftAzure\\Storage\\Common\\Internal\\Authentication\\TokenAuthScheme' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/Authentication/TokenAuthScheme.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\ConnectionStringParser' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/ConnectionStringParser.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\ConnectionStringSource' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/ConnectionStringSource.php', 'MicrosoftAzure\\Storage\\Common\\Internal\\Http\\HttpCallContext' => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common/Internal/Http/HttpCallContext.php', diff --git a/composer/installed.json b/composer/installed.json index c8cc48f84..f4d68989e 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -980,39 +980,45 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.5", - "version_normalized": "6.5.5.0", + "version": "7.2.0", + "version_normalized": "7.2.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.17.0" + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", "psr/log": "^1.1" }, "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, - "time": "2020-06-16T21:01:06+00:00", + "time": "2020-10-10T11:47:56+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "6.5-dev" + "dev-master": "7.1-dev" } }, "installation-source": "dist", @@ -1033,6 +1039,11 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "Guzzle is a PHP HTTP client library", @@ -1043,13 +1054,33 @@ "framework", "http", "http client", + "psr-18", + "psr-7", "rest", "web service" ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/6.5" + "source": "https://github.com/guzzle/guzzle/tree/7.2.0" }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], "install-path": "../guzzlehttp/guzzle" }, { @@ -1188,6 +1219,76 @@ }, "install-path": "../guzzlehttp/psr7" }, + { + "name": "guzzlehttp/uri-template", + "version": "v0.2.0", + "version_normalized": "0.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "db46525d6d8fee71033b73cc07160f3e5271a8ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/db46525d6d8fee71033b73cc07160f3e5271a8ce", + "reference": "db46525d6d8fee71033b73cc07160f3e5271a8ce", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3", + "uri-template/tests": "1.0.0" + }, + "time": "2020-07-21T13:45:09+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos", + "role": "Developer" + } + ], + "description": "A polyfill class for uri_template of PHP", + "homepage": "https://github.com/guzzlehttp/uri-template", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/master" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "install-path": "../guzzlehttp/uri-template" + }, { "name": "icewind/searchdav", "version": "v2.0.0", @@ -1280,17 +1381,17 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.2.9", - "version_normalized": "5.2.9.0", + "version": "5.2.10", + "version_normalized": "5.2.10.0", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "44c6787311242a979fa15c704327c20e7221a0e4" + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4", - "reference": "44c6787311242a979fa15c704327c20e7221a0e4", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", "shasum": "" }, "require": { @@ -1301,7 +1402,7 @@ "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, - "time": "2019-09-25T14:49:45+00:00", + "time": "2020-05-27T16:41:55+00:00", "bin": [ "bin/validate-json" ], @@ -1345,6 +1446,10 @@ "json", "schema" ], + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + }, "install-path": "../justinrainbow/json-schema" }, { @@ -1663,24 +1768,24 @@ }, { "name": "microsoft/azure-storage-blob", - "version": "1.5.0", - "version_normalized": "1.5.0.0", + "version": "1.5.2", + "version_normalized": "1.5.2.0", "source": { "type": "git", "url": "https://github.com/Azure/azure-storage-blob-php.git", - "reference": "6a333cd28a3742c3e99e79042dc6510f9f917919" + "reference": "2475330963372d519387cb8135d6a9cfd42272da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/6a333cd28a3742c3e99e79042dc6510f9f917919", - "reference": "6a333cd28a3742c3e99e79042dc6510f9f917919", + "url": "https://api.github.com/repos/Azure/azure-storage-blob-php/zipball/2475330963372d519387cb8135d6a9cfd42272da", + "reference": "2475330963372d519387cb8135d6a9cfd42272da", "shasum": "" }, "require": { - "microsoft/azure-storage-common": "~1.4", + "microsoft/azure-storage-common": "~1.5", "php": ">=5.6.0" }, - "time": "2020-01-02T07:18:59+00:00", + "time": "2020-12-29T02:22:11+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1706,28 +1811,32 @@ "sdk", "storage" ], + "support": { + "issues": "https://github.com/Azure/azure-storage-blob-php/issues", + "source": "https://github.com/Azure/azure-storage-blob-php/tree/v1.5.2" + }, "install-path": "../microsoft/azure-storage-blob" }, { "name": "microsoft/azure-storage-common", - "version": "1.4.1", - "version_normalized": "1.4.1.0", + "version": "1.5.1", + "version_normalized": "1.5.1.0", "source": { "type": "git", "url": "https://github.com/Azure/azure-storage-common-php.git", - "reference": "be4df800761d0d0fa91a9460c7f42517197d57a0" + "reference": "e5738035891546075bd369954e8af121d65ebd6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/be4df800761d0d0fa91a9460c7f42517197d57a0", - "reference": "be4df800761d0d0fa91a9460c7f42517197d57a0", + "url": "https://api.github.com/repos/Azure/azure-storage-common-php/zipball/e5738035891546075bd369954e8af121d65ebd6d", + "reference": "e5738035891546075bd369954e8af121d65ebd6d", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "~6.0", + "guzzlehttp/guzzle": "~6.0|^7.0", "php": ">=5.6.0" }, - "time": "2020-01-02T07:15:54+00:00", + "time": "2020-12-28T07:59:51+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1753,6 +1862,10 @@ "sdk", "storage" ], + "support": { + "issues": "https://github.com/Azure/azure-storage-common-php/issues", + "source": "https://github.com/Azure/azure-storage-common-php/tree/v1.5.1" + }, "install-path": "../microsoft/azure-storage-common" }, { @@ -2441,23 +2554,23 @@ "install-path": "../php-ds/php-ds" }, { - "name": "php-http/guzzle6-adapter", - "version": "v2.0.1", - "version_normalized": "2.0.1.0", + "name": "php-http/guzzle7-adapter", + "version": "0.1.1", + "version_normalized": "0.1.1.0", "source": { "type": "git", - "url": "https://github.com/php-http/guzzle6-adapter.git", - "reference": "6074a4b1f4d5c21061b70bab3b8ad484282fe31f" + "url": "https://github.com/php-http/guzzle7-adapter.git", + "reference": "1967de656b9679a2a6a66d0e4e16fa99bbed1ad1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/guzzle6-adapter/zipball/6074a4b1f4d5c21061b70bab3b8ad484282fe31f", - "reference": "6074a4b1f4d5c21061b70bab3b8ad484282fe31f", + "url": "https://api.github.com/repos/php-http/guzzle7-adapter/zipball/1967de656b9679a2a6a66d0e4e16fa99bbed1ad1", + "reference": "1967de656b9679a2a6a66d0e4e16fa99bbed1ad1", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.0", - "php": "^7.1", + "guzzlehttp/guzzle": "^7.0", + "php": "^7.2 | ^8.0", "php-http/httplug": "^2.0", "psr/http-client": "^1.0" }, @@ -2467,21 +2580,20 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "ext-curl": "*", - "php-http/client-integration-tests": "^2.0", - "phpunit/phpunit": "^7.4" + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.0|^9.3" }, - "time": "2018-12-16T14:44:03+00:00", + "time": "2020-10-21T17:30:51+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "0.2.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Http\\Adapter\\Guzzle6\\": "src/" + "Http\\Adapter\\Guzzle7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2490,48 +2602,48 @@ ], "authors": [ { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - }, - { - "name": "David de Boer", - "email": "david@ddeboer.nl" + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" } ], - "description": "Guzzle 6 HTTP Adapter", + "description": "Guzzle 7 HTTP Adapter", "homepage": "http://httplug.io", "keywords": [ "Guzzle", "http" ], - "install-path": "../php-http/guzzle6-adapter" + "support": { + "issues": "https://github.com/php-http/guzzle7-adapter/issues", + "source": "https://github.com/php-http/guzzle7-adapter/tree/0.1.1" + }, + "install-path": "../php-http/guzzle7-adapter" }, { "name": "php-http/httplug", - "version": "2.1.0", - "version_normalized": "2.1.0.0", + "version": "2.2.0", + "version_normalized": "2.2.0.0", "source": { "type": "git", "url": "https://github.com/php-http/httplug.git", - "reference": "72d2b129a48f0490d55b7f89be0d6aa0597ffb06" + "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/httplug/zipball/72d2b129a48f0490d55b7f89be0d6aa0597ffb06", - "reference": "72d2b129a48f0490d55b7f89be0d6aa0597ffb06", + "url": "https://api.github.com/repos/php-http/httplug/zipball/191a0a1b41ed026b717421931f8d3bd2514ffbf9", + "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9", "shasum": "" }, "require": { - "php": "^7.0", - "php-http/promise": "^1.0", + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", "psr/http-client": "^1.0", "psr/http-message": "^1.0" }, "require-dev": { "friends-of-phpspec/phpspec-code-coverage": "^4.1", - "phpspec/phpspec": "^4.3.4|^5.0|^6.0" + "phpspec/phpspec": "^5.1 || ^6.0" }, - "time": "2019-12-27T10:07:11+00:00", + "time": "2020-07-13T15:43:23+00:00", "type": "library", "extra": { "branch-alias": { @@ -2555,7 +2667,8 @@ }, { "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "HTTPlug, the HTTP client abstraction for PHP", @@ -2564,28 +2677,35 @@ "client", "http" ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/master" + }, "install-path": "../php-http/httplug" }, { "name": "php-http/promise", - "version": "v1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/php-http/promise.git", - "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980" + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/dc494cdc9d7160b9a09bd5573272195242ce7980", - "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980", + "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", "shasum": "" }, + "require": { + "php": "^7.1 || ^8.0" + }, "require-dev": { - "henrikbjorn/phpspec-code-coverage": "^1.0", - "phpspec/phpspec": "^2.4" + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" }, - "time": "2016-01-26T13:27:02+00:00", + "time": "2020-07-07T09:29:14+00:00", "type": "library", "extra": { "branch-alias": { @@ -2603,13 +2723,13 @@ "MIT" ], "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - }, { "name": "Joel Wurtz", "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" } ], "description": "Promise used for asynchronous HTTP requests", @@ -2617,27 +2737,32 @@ "keywords": [ "promise" ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.1.0" + }, "install-path": "../php-http/promise" }, { "name": "php-opencloud/openstack", - "version": "v3.0.7", - "version_normalized": "3.0.7.0", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", "source": { "type": "git", "url": "https://github.com/php-opencloud/openstack.git", - "reference": "5d73ff577731fc473448c489acfca9730aa39c88" + "reference": "7b0eeb63defe533fb802514af3c70855c45eaf1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-opencloud/openstack/zipball/5d73ff577731fc473448c489acfca9730aa39c88", - "reference": "5d73ff577731fc473448c489acfca9730aa39c88", + "url": "https://api.github.com/repos/php-opencloud/openstack/zipball/7b0eeb63defe533fb802514af3c70855c45eaf1e", + "reference": "7b0eeb63defe533fb802514af3c70855c45eaf1e", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.1", + "guzzlehttp/guzzle": "^7.0", + "guzzlehttp/uri-template": "0.2", "justinrainbow/json-schema": "^5.2", - "php": "~7.0" + "php": "^7.2.5" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.13", @@ -2646,7 +2771,7 @@ "phpunit/phpunit": "^6.5", "psr/log": "^1.0" }, - "time": "2020-01-07T08:46:53+00:00", + "time": "2020-10-11T16:12:31+00:00", "type": "library", "extra": { "branch-alias": { @@ -2683,6 +2808,10 @@ "php", "sdk" ], + "support": { + "issues": "https://github.com/php-opencloud/openstack/issues", + "source": "https://github.com/php-opencloud/openstack/tree/v3.1.0" + }, "install-path": "../php-opencloud/openstack" }, { @@ -5596,6 +5725,6 @@ "install-path": "../web-auth/webauthn-lib" } ], - "dev": false, + "dev": true, "dev-package-names": [] } diff --git a/composer/installed.php b/composer/installed.php index 551f8ef9a..ee4ebb187 100644 --- a/composer/installed.php +++ b/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '7fd440b16ef3dc16447e4565246c00e981ab9298', + 'reference' => '225c51509edf9ab3557ce109c3762731e7863e10', 'name' => 'nextcloud/3rdparty', ), 'versions' => @@ -139,12 +139,12 @@ ), 'guzzlehttp/guzzle' => array ( - 'pretty_version' => '6.5.5', - 'version' => '6.5.5.0', + 'pretty_version' => '7.2.0', + 'version' => '7.2.0.0', 'aliases' => array ( ), - 'reference' => '9d4290de1cfd701f38099ef7e183b64b4b7b0c5e', + 'reference' => '0aa74dfb41ae110835923ef10a9d803a22d50e79', ), 'guzzlehttp/promises' => array ( @@ -164,6 +164,15 @@ ), 'reference' => '53330f47520498c0ae1f61f7e2c90f55690c06a3', ), + 'guzzlehttp/uri-template' => + array ( + 'pretty_version' => 'v0.2.0', + 'version' => '0.2.0.0', + 'aliases' => + array ( + ), + 'reference' => 'db46525d6d8fee71033b73cc07160f3e5271a8ce', + ), 'icewind/searchdav' => array ( 'pretty_version' => 'v2.0.0', @@ -184,12 +193,12 @@ ), 'justinrainbow/json-schema' => array ( - 'pretty_version' => '5.2.9', - 'version' => '5.2.9.0', + 'pretty_version' => '5.2.10', + 'version' => '5.2.10.0', 'aliases' => array ( ), - 'reference' => '44c6787311242a979fa15c704327c20e7221a0e4', + 'reference' => '2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b', ), 'league/flysystem' => array ( @@ -229,21 +238,21 @@ ), 'microsoft/azure-storage-blob' => array ( - 'pretty_version' => '1.5.0', - 'version' => '1.5.0.0', + 'pretty_version' => '1.5.2', + 'version' => '1.5.2.0', 'aliases' => array ( ), - 'reference' => '6a333cd28a3742c3e99e79042dc6510f9f917919', + 'reference' => '2475330963372d519387cb8135d6a9cfd42272da', ), 'microsoft/azure-storage-common' => array ( - 'pretty_version' => '1.4.1', - 'version' => '1.4.1.0', + 'pretty_version' => '1.5.1', + 'version' => '1.5.1.0', 'aliases' => array ( ), - 'reference' => 'be4df800761d0d0fa91a9460c7f42517197d57a0', + 'reference' => 'e5738035891546075bd369954e8af121d65ebd6d', ), 'mtdowling/jmespath.php' => array ( @@ -261,7 +270,7 @@ 'aliases' => array ( ), - 'reference' => '7fd440b16ef3dc16447e4565246c00e981ab9298', + 'reference' => '225c51509edf9ab3557ce109c3762731e7863e10', ), 'nextcloud/lognormalizer' => array ( @@ -376,41 +385,41 @@ 0 => '1.0', ), ), - 'php-http/guzzle6-adapter' => + 'php-http/guzzle7-adapter' => array ( - 'pretty_version' => 'v2.0.1', - 'version' => '2.0.1.0', + 'pretty_version' => '0.1.1', + 'version' => '0.1.1.0', 'aliases' => array ( ), - 'reference' => '6074a4b1f4d5c21061b70bab3b8ad484282fe31f', + 'reference' => '1967de656b9679a2a6a66d0e4e16fa99bbed1ad1', ), 'php-http/httplug' => array ( - 'pretty_version' => '2.1.0', - 'version' => '2.1.0.0', + 'pretty_version' => '2.2.0', + 'version' => '2.2.0.0', 'aliases' => array ( ), - 'reference' => '72d2b129a48f0490d55b7f89be0d6aa0597ffb06', + 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9', ), 'php-http/promise' => array ( - 'pretty_version' => 'v1.0.0', - 'version' => '1.0.0.0', + 'pretty_version' => '1.1.0', + 'version' => '1.1.0.0', 'aliases' => array ( ), - 'reference' => 'dc494cdc9d7160b9a09bd5573272195242ce7980', + 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88', ), 'php-opencloud/openstack' => array ( - 'pretty_version' => 'v3.0.7', - 'version' => '3.0.7.0', + 'pretty_version' => 'v3.1.0', + 'version' => '3.1.0.0', 'aliases' => array ( ), - 'reference' => '5d73ff577731fc473448c489acfca9730aa39c88', + 'reference' => '7b0eeb63defe533fb802514af3c70855c45eaf1e', ), 'phpseclib/phpseclib' => array ( diff --git a/guzzlehttp/guzzle/LICENSE b/guzzlehttp/guzzle/LICENSE index 50a177b03..d51aa6986 100644 --- a/guzzlehttp/guzzle/LICENSE +++ b/guzzlehttp/guzzle/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling +Copyright (c) 2011 Michael Dowling, https://github.com/mtdowling 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/guzzlehttp/guzzle/src/BodySummarizer.php b/guzzlehttp/guzzle/src/BodySummarizer.php new file mode 100644 index 000000000..6eca94ef9 --- /dev/null +++ b/guzzlehttp/guzzle/src/BodySummarizer.php @@ -0,0 +1,28 @@ +truncateAt = $truncateAt; + } + + /** + * Returns a summarized message body. + */ + public function summarize(MessageInterface $message): ?string + { + return $this->truncateAt === null + ? \GuzzleHttp\Psr7\Message::bodySummary($message) + : \GuzzleHttp\Psr7\Message::bodySummary($message, $this->truncateAt); + } +} diff --git a/guzzlehttp/guzzle/src/BodySummarizerInterface.php b/guzzlehttp/guzzle/src/BodySummarizerInterface.php new file mode 100644 index 000000000..3e02e036e --- /dev/null +++ b/guzzlehttp/guzzle/src/BodySummarizerInterface.php @@ -0,0 +1,13 @@ +configureDefaults($config); @@ -79,19 +74,21 @@ public function __construct(array $config = []) * @param string $method * @param array $args * - * @return Promise\PromiseInterface + * @return PromiseInterface|ResponseInterface + * + * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0. */ public function __call($method, $args) { - if (count($args) < 1) { - throw new \InvalidArgumentException('Magic request methods require a URI and optional options array'); + if (\count($args) < 1) { + throw new InvalidArgumentException('Magic request methods require a URI and optional options array'); } $uri = $args[0]; - $opts = isset($args[1]) ? $args[1] : []; + $opts = $args[1] ?? []; - return substr($method, -5) === 'Async' - ? $this->requestAsync(substr($method, 0, -5), $uri, $opts) + return \substr($method, -5) === 'Async' + ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts) : $this->request($method, $uri, $opts); } @@ -100,10 +97,8 @@ public function __call($method, $args) * * @param array $options Request options to apply to the given * request and to the transfer. See \GuzzleHttp\RequestOptions. - * - * @return Promise\PromiseInterface */ - public function sendAsync(RequestInterface $request, array $options = []) + public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface { // Merge the base URI into the request URI if needed. $options = $this->prepareDefaults($options); @@ -120,15 +115,28 @@ public function sendAsync(RequestInterface $request, array $options = []) * @param array $options Request options to apply to the given * request and to the transfer. See \GuzzleHttp\RequestOptions. * - * @return ResponseInterface * @throws GuzzleException */ - public function send(RequestInterface $request, array $options = []) + public function send(RequestInterface $request, array $options = []): ResponseInterface { $options[RequestOptions::SYNCHRONOUS] = true; return $this->sendAsync($request, $options)->wait(); } + /** + * The HttpClient PSR (PSR-18) specify this method. + * + * @inheritDoc + */ + public function sendRequest(RequestInterface $request): ResponseInterface + { + $options[RequestOptions::SYNCHRONOUS] = true; + $options[RequestOptions::ALLOW_REDIRECTS] = false; + $options[RequestOptions::HTTP_ERRORS] = false; + + return $this->sendAsync($request, $options)->wait(); + } + /** * Create and send an asynchronous HTTP request. * @@ -140,20 +148,18 @@ 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. See \GuzzleHttp\RequestOptions. - * - * @return Promise\PromiseInterface */ - public function requestAsync($method, $uri = '', array $options = []) + public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface { $options = $this->prepareDefaults($options); // Remove request modifying parameter because it can be done up-front. - $headers = isset($options['headers']) ? $options['headers'] : []; - $body = isset($options['body']) ? $options['body'] : null; - $version = isset($options['version']) ? $options['version'] : '1.1'; + $headers = $options['headers'] ?? []; + $body = $options['body'] ?? null; + $version = $options['version'] ?? '1.1'; // Merge the URI into the base URI. - $uri = $this->buildUri($uri, $options); - if (is_array($body)) { - $this->invalidBody(); + $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options); + if (\is_array($body)) { + throw $this->invalidBody(); } $request = new Psr7\Request($method, $uri, $headers, $body, $version); // Remove the option so that they are not doubly-applied. @@ -173,10 +179,9 @@ public function requestAsync($method, $uri = '', array $options = []) * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. * - * @return ResponseInterface * @throws GuzzleException */ - public function request($method, $uri = '', array $options = []) + public function request(string $method, $uri = '', array $options = []): ResponseInterface { $options[RequestOptions::SYNCHRONOUS] = true; return $this->requestAsync($method, $uri, $options)->wait(); @@ -192,30 +197,24 @@ public function request($method, $uri = '', array $options = []) * @param string|null $option The config option to retrieve. * * @return mixed + * + * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0. */ - public function getConfig($option = null) + public function getConfig(?string $option = null) { return $option === null ? $this->config : (isset($this->config[$option]) ? $this->config[$option] : null); } - /** - * @param string|null $uri - * - * @return UriInterface - */ - private function buildUri($uri, array $config) + private function buildUri(UriInterface $uri, array $config): UriInterface { - // for BC we accept null which would otherwise fail in uri_for - $uri = Psr7\uri_for($uri === null ? '' : $uri); - if (isset($config['base_uri'])) { - $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); + $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri); } if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { - $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; + $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion']; $uri = Utils::idnUriConvert($uri, $idnOptions); } @@ -224,11 +223,8 @@ private function buildUri($uri, array $config) /** * Configures the default options for a client. - * - * @param array $config - * @return void */ - private function configureDefaults(array $config) + private function configureDefaults(array $config): void { $defaults = [ 'allow_redirects' => RedirectMiddleware::$defaultSettings, @@ -236,7 +232,7 @@ private function configureDefaults(array $config) 'decode_content' => true, 'verify' => true, 'cookies' => false, - 'idn_conversion' => true, + 'idn_conversion' => false, ]; // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. @@ -244,17 +240,17 @@ private function configureDefaults(array $config) // 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')) { - $defaults['proxy']['http'] = getenv('HTTP_PROXY'); + if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) { + $defaults['proxy']['http'] = $proxy; } - if ($proxy = getenv('HTTPS_PROXY')) { + if ($proxy = Utils::getenv('HTTPS_PROXY')) { $defaults['proxy']['https'] = $proxy; } - if ($noProxy = getenv('NO_PROXY')) { - $cleanedNoProxy = str_replace(' ', '', $noProxy); - $defaults['proxy']['no'] = explode(',', $cleanedNoProxy); + if ($noProxy = Utils::getenv('NO_PROXY')) { + $cleanedNoProxy = \str_replace(' ', '', $noProxy); + $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy); } $this->config = $config + $defaults; @@ -265,15 +261,15 @@ private function configureDefaults(array $config) // Add the default user-agent header. if (!isset($this->config['headers'])) { - $this->config['headers'] = ['User-Agent' => default_user_agent()]; + $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()]; } else { // Add the User-Agent header if one was not already set. - foreach (array_keys($this->config['headers']) as $name) { - if (strtolower($name) === 'user-agent') { + foreach (\array_keys($this->config['headers']) as $name) { + if (\strtolower($name) === 'user-agent') { return; } } - $this->config['headers']['User-Agent'] = default_user_agent(); + $this->config['headers']['User-Agent'] = Utils::defaultUserAgent(); } } @@ -281,10 +277,8 @@ private function configureDefaults(array $config) * Merges default options into the array. * * @param array $options Options to modify by reference - * - * @return array */ - private function prepareDefaults(array $options) + private function prepareDefaults(array $options): array { $defaults = $this->config; @@ -296,13 +290,13 @@ private function prepareDefaults(array $options) // Special handling for headers is required as they are added as // conditional headers and as headers passed to a request ctor. - if (array_key_exists('headers', $options)) { + if (\array_key_exists('headers', $options)) { // Allows default headers to be unset. if ($options['headers'] === null) { $defaults['_conditional'] = []; unset($options['headers']); - } elseif (!is_array($options['headers'])) { - throw new \InvalidArgumentException('headers must be an array'); + } elseif (!\is_array($options['headers'])) { + throw new InvalidArgumentException('headers must be an array'); } } @@ -326,43 +320,24 @@ private function prepareDefaults(array $options) * as-is without merging in default options. * * @param array $options See \GuzzleHttp\RequestOptions. - * - * @return Promise\PromiseInterface */ - private function transfer(RequestInterface $request, array $options) + private function transfer(RequestInterface $request, array $options): PromiseInterface { - // save_to -> sink - if (isset($options['save_to'])) { - $options['sink'] = $options['save_to']; - unset($options['save_to']); - } - - // exceptions -> http_errors - if (isset($options['exceptions'])) { - $options['http_errors'] = $options['exceptions']; - unset($options['exceptions']); - } - $request = $this->applyOptions($request, $options); /** @var HandlerStack $handler */ $handler = $options['handler']; try { - return Promise\promise_for($handler($request, $options)); + return P\Create::promiseFor($handler($request, $options)); } catch (\Exception $e) { - return Promise\rejection_for($e); + return P\Create::rejectionFor($e); } } /** * Applies the array of request options to a request. - * - * @param RequestInterface $request - * @param array $options - * - * @return RequestInterface */ - private function applyOptions(RequestInterface $request, array &$options) + private function applyOptions(RequestInterface $request, array &$options): RequestInterface { $modify = [ 'set_headers' => [], @@ -375,16 +350,16 @@ private function applyOptions(RequestInterface $request, array &$options) if (isset($options['form_params'])) { if (isset($options['multipart'])) { - throw new \InvalidArgumentException('You cannot use ' + throw new InvalidArgumentException('You cannot use ' . 'form_params and multipart at the same time. Use the ' . 'form_params option if you want to send application/' . 'x-www-form-urlencoded requests, and the multipart ' . 'option to send multipart/form-data requests.'); } - $options['body'] = http_build_query($options['form_params'], '', '&'); + $options['body'] = \http_build_query($options['form_params'], '', '&'); unset($options['form_params']); // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); + $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded'; } @@ -394,10 +369,10 @@ private function applyOptions(RequestInterface $request, array &$options) } if (isset($options['json'])) { - $options['body'] = \GuzzleHttp\json_encode($options['json']); + $options['body'] = Utils::jsonEncode($options['json']); unset($options['json']); // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); + $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); $options['_conditional']['Content-Type'] = 'application/json'; } @@ -405,47 +380,47 @@ private function applyOptions(RequestInterface $request, array &$options) && $options['decode_content'] !== true ) { // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']); + $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']); $modify['set_headers']['Accept-Encoding'] = $options['decode_content']; } if (isset($options['body'])) { - if (is_array($options['body'])) { - $this->invalidBody(); + if (\is_array($options['body'])) { + throw $this->invalidBody(); } - $modify['body'] = Psr7\stream_for($options['body']); + $modify['body'] = Psr7\Utils::streamFor($options['body']); unset($options['body']); } - if (!empty($options['auth']) && is_array($options['auth'])) { + if (!empty($options['auth']) && \is_array($options['auth'])) { $value = $options['auth']; - $type = isset($value[2]) ? strtolower($value[2]) : 'basic'; + $type = isset($value[2]) ? \strtolower($value[2]) : 'basic'; switch ($type) { case 'basic': // Ensure that we don't have the header in different case and set the new value. - $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']); + $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']); $modify['set_headers']['Authorization'] = 'Basic ' - . base64_encode("$value[0]:$value[1]"); + . \base64_encode("$value[0]:$value[1]"); break; case 'digest': // @todo: Do not rely on curl - $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST; - $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; + $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST; + $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]"; break; case 'ntlm': - $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM; - $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; + $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM; + $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]"; break; } } if (isset($options['query'])) { $value = $options['query']; - if (is_array($value)) { - $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986); + if (\is_array($value)) { + $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986); } - if (!is_string($value)) { - throw new \InvalidArgumentException('query must be a string or array'); + if (!\is_string($value)) { + throw new InvalidArgumentException('query must be a string or array'); } $modify['query'] = $value; unset($options['query']); @@ -454,16 +429,16 @@ private function applyOptions(RequestInterface $request, array &$options) // Ensure that sink is not an invalid value. if (isset($options['sink'])) { // TODO: Add more sink validation? - if (is_bool($options['sink'])) { - throw new \InvalidArgumentException('sink must not be a boolean'); + if (\is_bool($options['sink'])) { + throw new InvalidArgumentException('sink must not be a boolean'); } } - $request = Psr7\modify_request($request, $modify); + $request = Psr7\Utils::modifyRequest($request, $modify); if ($request->getBody() instanceof Psr7\MultipartStream) { // Use a multipart/form-data POST if a Content-Type is not set. // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); + $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' . $request->getBody()->getBoundary(); } @@ -477,7 +452,7 @@ private function applyOptions(RequestInterface $request, array &$options) $modify['set_headers'][$k] = $v; } } - $request = Psr7\modify_request($request, $modify); + $request = Psr7\Utils::modifyRequest($request, $modify); // Don't pass this internal value along to middleware/handlers. unset($options['_conditional']); } @@ -486,14 +461,12 @@ private function applyOptions(RequestInterface $request, array &$options) } /** - * Throw Exception with pre-set message. - * @return void - * @throws \InvalidArgumentException Invalid body. + * Return an InvalidArgumentException with pre-set message. */ - private function invalidBody() + private function invalidBody(): InvalidArgumentException { - throw new \InvalidArgumentException('Passing in the "body" request ' - . 'option as an array to send a POST request has been deprecated. ' + return new InvalidArgumentException('Passing in the "body" request ' + . 'option as an array to send a request is not supported. ' . 'Please use the "form_params" request option to send a ' . 'application/x-www-form-urlencoded request, or the "multipart" ' . 'request option to send a multipart/form-data request.'); diff --git a/guzzlehttp/guzzle/src/ClientInterface.php b/guzzlehttp/guzzle/src/ClientInterface.php index 638b75dca..f257a1a30 100644 --- a/guzzlehttp/guzzle/src/ClientInterface.php +++ b/guzzlehttp/guzzle/src/ClientInterface.php @@ -1,4 +1,5 @@ request('GET', $uri, $options); + } + + /** + * Create and send an HTTP HEAD 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @throws GuzzleException + */ + public function head($uri, array $options = []): ResponseInterface + { + return $this->request('HEAD', $uri, $options); + } + + /** + * Create and send an HTTP PUT 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @throws GuzzleException + */ + public function put($uri, array $options = []): ResponseInterface + { + return $this->request('PUT', $uri, $options); + } + + /** + * Create and send an HTTP POST 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @throws GuzzleException + */ + public function post($uri, array $options = []): ResponseInterface + { + return $this->request('POST', $uri, $options); + } + + /** + * Create and send an HTTP PATCH 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @throws GuzzleException + */ + public function patch($uri, array $options = []): ResponseInterface + { + return $this->request('PATCH', $uri, $options); + } + + /** + * Create and send an HTTP DELETE 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + * + * @throws GuzzleException + */ + public function delete($uri, array $options = []): ResponseInterface + { + return $this->request('DELETE', $uri, $options); + } + + /** + * 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. + */ + abstract public function requestAsync(string $method, $uri, array $options = []): PromiseInterface; + + /** + * Create and send an asynchronous HTTP GET 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + */ + public function getAsync($uri, array $options = []): PromiseInterface + { + return $this->requestAsync('GET', $uri, $options); + } + + /** + * Create and send an asynchronous HTTP HEAD 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + */ + public function headAsync($uri, array $options = []): PromiseInterface + { + return $this->requestAsync('HEAD', $uri, $options); + } + + /** + * Create and send an asynchronous HTTP PUT 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + */ + public function putAsync($uri, array $options = []): PromiseInterface + { + return $this->requestAsync('PUT', $uri, $options); + } + + /** + * Create and send an asynchronous HTTP POST 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + */ + public function postAsync($uri, array $options = []): PromiseInterface + { + return $this->requestAsync('POST', $uri, $options); + } + + /** + * Create and send an asynchronous HTTP PATCH 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + */ + public function patchAsync($uri, array $options = []): PromiseInterface + { + return $this->requestAsync('PATCH', $uri, $options); + } + + /** + * Create and send an asynchronous HTTP DELETE 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|UriInterface $uri URI object or string. + * @param array $options Request options to apply. + */ + public function deleteAsync($uri, array $options = []): PromiseInterface + { + return $this->requestAsync('DELETE', $uri, $options); + } +} diff --git a/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/guzzlehttp/guzzle/src/Cookie/CookieJar.php index 38f98ad7c..d6757c654 100644 --- a/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ b/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -1,4 +1,5 @@ strictMode = $strictMode; @@ -39,10 +44,8 @@ public function __construct($strictMode = false, $cookieArray = []) * * @param array $cookies Cookies to create the jar from * @param string $domain Domain to set the cookies to - * - * @return self */ - public static function fromArray(array $cookies, $domain) + public static function fromArray(array $cookies, string $domain): self { $cookieJar = new self(); foreach ($cookies as $name => $value) { @@ -57,26 +60,15 @@ public static function fromArray(array $cookies, $domain) return $cookieJar; } - /** - * @deprecated - */ - public static function getCookieValue($value) - { - return $value; - } - /** * Evaluate if this cookie should be persisted to storage * that survives between requests. * - * @param SetCookie $cookie Being evaluated. - * @param bool $allowSessionCookies If we should persist session cookies - * @return bool + * @param SetCookie $cookie Being evaluated. + * @param bool $allowSessionCookies If we should persist session cookies */ - public static function shouldPersist( - SetCookie $cookie, - $allowSessionCookies = false - ) { + public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = false): bool + { if ($cookie->getExpires() || $allowSessionCookies) { if (!$cookie->getDiscard()) { return true; @@ -90,16 +82,13 @@ public static function shouldPersist( * Finds and returns the cookie based on the name * * @param string $name cookie name to search for + * * @return SetCookie|null cookie that was found or null if not found */ - public function getCookieByName($name) + public function getCookieByName(string $name): ?SetCookie { - // don't allow a non string name - if ($name === null || !is_scalar($name)) { - return null; - } foreach ($this->cookies as $cookie) { - if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) { + if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) { return $cookie; } } @@ -107,37 +96,43 @@ public function getCookieByName($name) return null; } - public function toArray() + /** + * @inheritDoc + */ + public function toArray(): array { - return array_map(function (SetCookie $cookie) { + return \array_map(static function (SetCookie $cookie): array { return $cookie->toArray(); }, $this->getIterator()->getArrayCopy()); } - public function clear($domain = null, $path = null, $name = null) + /** + * @inheritDoc + */ + public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void { if (!$domain) { $this->cookies = []; return; } elseif (!$path) { - $this->cookies = array_filter( + $this->cookies = \array_filter( $this->cookies, - function (SetCookie $cookie) use ($domain) { + static function (SetCookie $cookie) use ($domain): bool { return !$cookie->matchesDomain($domain); } ); } elseif (!$name) { - $this->cookies = array_filter( + $this->cookies = \array_filter( $this->cookies, - function (SetCookie $cookie) use ($path, $domain) { + static function (SetCookie $cookie) use ($path, $domain): bool { return !($cookie->matchesPath($path) && $cookie->matchesDomain($domain)); } ); } else { - $this->cookies = array_filter( + $this->cookies = \array_filter( $this->cookies, - function (SetCookie $cookie) use ($path, $domain, $name) { + static function (SetCookie $cookie) use ($path, $domain, $name) { return !($cookie->getName() == $name && $cookie->matchesPath($path) && $cookie->matchesDomain($domain)); @@ -146,17 +141,23 @@ function (SetCookie $cookie) use ($path, $domain, $name) { } } - public function clearSessionCookies() + /** + * @inheritDoc + */ + public function clearSessionCookies(): void { - $this->cookies = array_filter( + $this->cookies = \array_filter( $this->cookies, - function (SetCookie $cookie) { + static function (SetCookie $cookie): bool { return !$cookie->getDiscard() && $cookie->getExpires(); } ); } - public function setCookie(SetCookie $cookie) + /** + * @inheritDoc + */ + public function setCookie(SetCookie $cookie): bool { // If the name string is empty (but not 0), ignore the set-cookie // string entirely. @@ -170,10 +171,9 @@ public function setCookie(SetCookie $cookie) if ($result !== true) { if ($this->strictMode) { throw new \RuntimeException('Invalid cookie: ' . $result); - } else { - $this->removeCookieIfEmpty($cookie); - return false; } + $this->removeCookieIfEmpty($cookie); + return false; } // Resolve conflicts with previously set cookies @@ -217,27 +217,28 @@ public function setCookie(SetCookie $cookie) return true; } - public function count() + public function count(): int { - return count($this->cookies); + return \count($this->cookies); } - public function getIterator() + /** + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator { - return new \ArrayIterator(array_values($this->cookies)); + return new \ArrayIterator(\array_values($this->cookies)); } - public function extractCookies( - RequestInterface $request, - ResponseInterface $response - ) { + public function extractCookies(RequestInterface $request, ResponseInterface $response): void + { if ($cookieHeader = $response->getHeader('Set-Cookie')) { foreach ($cookieHeader as $cookie) { $sc = SetCookie::fromString($cookie); if (!$sc->getDomain()) { $sc->setDomain($request->getUri()->getHost()); } - if (0 !== strpos($sc->getPath(), '/')) { + if (0 !== \strpos($sc->getPath(), '/')) { $sc->setPath($this->getCookiePathFromRequest($request)); } $this->setCookie($sc); @@ -249,30 +250,28 @@ public function extractCookies( * Computes cookie path following RFC 6265 section 5.1.4 * * @link https://tools.ietf.org/html/rfc6265#section-5.1.4 - * - * @param RequestInterface $request - * @return string */ - private function getCookiePathFromRequest(RequestInterface $request) + private function getCookiePathFromRequest(RequestInterface $request): string { $uriPath = $request->getUri()->getPath(); - if ('' === $uriPath) { + if ('' === $uriPath) { return '/'; } - if (0 !== strpos($uriPath, '/')) { + if (0 !== \strpos($uriPath, '/')) { return '/'; } if ('/' === $uriPath) { return '/'; } - if (0 === $lastSlashPos = strrpos($uriPath, '/')) { + $lastSlashPos = \strrpos($uriPath, '/'); + if (0 === $lastSlashPos || false === $lastSlashPos) { return '/'; } - return substr($uriPath, 0, $lastSlashPos); + return \substr($uriPath, 0, $lastSlashPos); } - public function withCookieHeader(RequestInterface $request) + public function withCookieHeader(RequestInterface $request): RequestInterface { $values = []; $uri = $request->getUri(); @@ -292,17 +291,15 @@ public function withCookieHeader(RequestInterface $request) } return $values - ? $request->withHeader('Cookie', implode('; ', $values)) + ? $request->withHeader('Cookie', \implode('; ', $values)) : $request; } /** * If a cookie already exists and the server asks to set it again with a * null value, the cookie must be deleted. - * - * @param SetCookie $cookie */ - private function removeCookieIfEmpty(SetCookie $cookie) + private function removeCookieIfEmpty(SetCookie $cookie): void { $cookieValue = $cookie->getValue(); if ($cookieValue === null || $cookieValue === '') { diff --git a/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php index 6ee11885e..7df374b5b 100644 --- a/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +++ b/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php @@ -1,4 +1,5 @@ */ interface CookieJarInterface extends \Countable, \IteratorAggregate { @@ -26,7 +28,7 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate * * @return RequestInterface returns the modified request. */ - public function withCookieHeader(RequestInterface $request); + public function withCookieHeader(RequestInterface $request): RequestInterface; /** * Extract cookies from an HTTP response and store them in the CookieJar. @@ -34,10 +36,7 @@ public function withCookieHeader(RequestInterface $request); * @param RequestInterface $request Request that was sent * @param ResponseInterface $response Response that was received */ - public function extractCookies( - RequestInterface $request, - ResponseInterface $response - ); + public function extractCookies(RequestInterface $request, ResponseInterface $response): void; /** * Sets a cookie in the cookie jar. @@ -46,7 +45,7 @@ public function extractCookies( * * @return bool Returns true on success or false on failure */ - public function setCookie(SetCookie $cookie); + public function setCookie(SetCookie $cookie): bool; /** * Remove cookies currently held in the cookie jar. @@ -61,10 +60,8 @@ public function setCookie(SetCookie $cookie); * @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 */ - public function clear($domain = null, $path = null, $name = null); + public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void; /** * Discard all sessions cookies. @@ -73,12 +70,10 @@ public function clear($domain = null, $path = null, $name = null); * field set to true. To be called when the user agent shuts down according * to RFC 2965. */ - public function clearSessionCookies(); + public function clearSessionCookies(): void; /** * Converts the cookie jar to an array. - * - * @return array */ - public function toArray(); + public function toArray(): array; } diff --git a/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php b/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php index 3fb8600ef..290236d54 100644 --- a/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php +++ b/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php @@ -1,33 +1,40 @@ filename = $cookieFile; $this->storeSessionCookies = $storeSessionCookies; - if (file_exists($cookieFile)) { + if (\file_exists($cookieFile)) { $this->load($cookieFile); } } @@ -44,20 +51,21 @@ public function __destruct() * Saves the cookies to a file. * * @param string $filename File to save + * * @throws \RuntimeException if the file cannot be found or created */ - public function save($filename) + public function save(string $filename): void { $json = []; + /** @var SetCookie $cookie */ foreach ($this as $cookie) { - /** @var SetCookie $cookie */ if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { $json[] = $cookie->toArray(); } } - $jsonStr = \GuzzleHttp\json_encode($json); - if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) { + $jsonStr = Utils::jsonEncode($json); + if (false === \file_put_contents($filename, $jsonStr, \LOCK_EX)) { throw new \RuntimeException("Unable to save file {$filename}"); } } @@ -68,23 +76,25 @@ public function save($filename) * Old cookies are kept unless overwritten by newly loaded ones. * * @param string $filename Cookie file to load. + * * @throws \RuntimeException if the file cannot be loaded. */ - public function load($filename) + public function load(string $filename): void { - $json = file_get_contents($filename); + $json = \file_get_contents($filename); if (false === $json) { throw new \RuntimeException("Unable to load file {$filename}"); - } elseif ($json === '') { + } + if ($json === '') { return; } - $data = \GuzzleHttp\json_decode($json, true); - if (is_array($data)) { - foreach (json_decode($json, true) as $cookie) { + $data = Utils::jsonDecode($json, true); + if (\is_array($data)) { + foreach ($data as $cookie) { $this->setCookie(new SetCookie($cookie)); } - } elseif (strlen($data)) { + } elseif (\is_scalar($data) && !empty($data)) { throw new \RuntimeException("Invalid cookie file: {$filename}"); } } diff --git a/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php b/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php index 0224a2447..5d51ca982 100644 --- a/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php +++ b/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php @@ -1,4 +1,5 @@ sessionKey = $sessionKey; @@ -39,33 +44,33 @@ public function __destruct() /** * Save cookies to the client session */ - public function save() + public function save(): void { $json = []; + /** @var SetCookie $cookie */ foreach ($this as $cookie) { - /** @var SetCookie $cookie */ if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { $json[] = $cookie->toArray(); } } - $_SESSION[$this->sessionKey] = json_encode($json); + $_SESSION[$this->sessionKey] = \json_encode($json); } /** * Load the contents of the client session into the data array */ - protected function load() + protected function load(): void { if (!isset($_SESSION[$this->sessionKey])) { return; } - $data = json_decode($_SESSION[$this->sessionKey], true); - if (is_array($data)) { + $data = \json_decode($_SESSION[$this->sessionKey], true); + if (\is_array($data)) { foreach ($data as $cookie) { $this->setCookie(new SetCookie($cookie)); } - } elseif (strlen($data)) { + } elseif (\strlen($data)) { throw new \RuntimeException("Invalid cookie data"); } } diff --git a/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/guzzlehttp/guzzle/src/Cookie/SetCookie.php index 3d776a70b..602370d6f 100644 --- a/guzzlehttp/guzzle/src/Cookie/SetCookie.php +++ b/guzzlehttp/guzzle/src/Cookie/SetCookie.php @@ -1,4 +1,5 @@ null, 'Value' => null, @@ -19,42 +22,42 @@ class SetCookie 'HttpOnly' => false ]; - /** @var array Cookie data */ + /** + * @var array Cookie data + */ private $data; /** - * Create a new SetCookie object from a string + * Create a new SetCookie object from a string. * * @param string $cookie Set-Cookie header string - * - * @return self */ - public static function fromString($cookie) + public static function fromString(string $cookie): self { // Create the default return array $data = self::$defaults; // Explode the cookie string using a series of semicolons - $pieces = array_filter(array_map('trim', explode(';', $cookie))); + $pieces = \array_filter(\array_map('trim', \explode(';', $cookie))); // The name of the cookie (first kvp) must exist and include an equal sign. - if (empty($pieces[0]) || !strpos($pieces[0], '=')) { + if (!isset($pieces[0]) || \strpos($pieces[0], '=') === false) { return new self($data); } // Add the cookie pieces into the parsed data array foreach ($pieces as $part) { - $cookieParts = explode('=', $part, 2); - $key = trim($cookieParts[0]); + $cookieParts = \explode('=', $part, 2); + $key = \trim($cookieParts[0]); $value = isset($cookieParts[1]) - ? trim($cookieParts[1], " \n\r\t\0\x0B") + ? \trim($cookieParts[1], " \n\r\t\0\x0B") : true; // Only check for non-cookies when cookies have been found - if (empty($data['Name'])) { + if (!isset($data['Name'])) { $data['Name'] = $key; $data['Value'] = $value; } else { - foreach (array_keys(self::$defaults) as $search) { - if (!strcasecmp($search, $key)) { + foreach (\array_keys(self::$defaults) as $search) { + if (!\strcasecmp($search, $key)) { $data[$search] = $value; continue 2; } @@ -71,13 +74,19 @@ public static function fromString($cookie) */ public function __construct(array $data = []) { - $this->data = array_replace(self::$defaults, $data); + /** @var array|null $replaced will be null in case of replace error */ + $replaced = \array_replace(self::$defaults, $data); + if ($replaced === null) { + throw new \InvalidArgumentException('Unable to replace the default values for the Cookie.'); + } + + $this->data = $replaced; // Extract the Expires value and turn it into a UNIX timestamp if needed if (!$this->getExpires() && $this->getMaxAge()) { // Calculate the Expires date - $this->setExpires(time() + $this->getMaxAge()); - } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { - $this->setExpires($this->getExpires()); + $this->setExpires(\time() + $this->getMaxAge()); + } elseif (null !== ($expires = $this->getExpires()) && !\is_numeric($expires)) { + $this->setExpires($expires); } } @@ -87,23 +96,23 @@ public function __toString() foreach ($this->data as $k => $v) { if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) { if ($k === 'Expires') { - $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; + $str .= 'Expires=' . \gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; } else { $str .= ($v === true ? $k : "{$k}={$v}") . '; '; } } } - return rtrim($str, '; '); + return \rtrim($str, '; '); } - public function toArray() + public function toArray(): array { return $this->data; } /** - * Get the cookie name + * Get the cookie name. * * @return string */ @@ -113,19 +122,19 @@ public function getName() } /** - * Set the cookie name + * Set the cookie name. * * @param string $name Cookie name */ - public function setName($name) + public function setName($name): void { $this->data['Name'] = $name; } /** - * Get the cookie value + * Get the cookie value. * - * @return string + * @return string|null */ public function getValue() { @@ -133,17 +142,17 @@ public function getValue() } /** - * Set the cookie value + * Set the cookie value. * * @param string $value Cookie value */ - public function setValue($value) + public function setValue($value): void { $this->data['Value'] = $value; } /** - * Get the domain + * Get the domain. * * @return string|null */ @@ -153,17 +162,17 @@ public function getDomain() } /** - * Set the domain of the cookie + * Set the domain of the cookie. * * @param string $domain */ - public function setDomain($domain) + public function setDomain($domain): void { $this->data['Domain'] = $domain; } /** - * Get the path + * Get the path. * * @return string */ @@ -173,17 +182,17 @@ public function getPath() } /** - * Set the path of the cookie + * Set the path of the cookie. * * @param string $path Path of the cookie */ - public function setPath($path) + public function setPath($path): void { $this->data['Path'] = $path; } /** - * Maximum lifetime of the cookie in seconds + * Maximum lifetime of the cookie in seconds. * * @return int|null */ @@ -193,19 +202,19 @@ public function getMaxAge() } /** - * Set the max-age of the cookie + * Set the max-age of the cookie. * * @param int $maxAge Max age of the cookie in seconds */ - public function setMaxAge($maxAge) + public function setMaxAge($maxAge): void { $this->data['Max-Age'] = $maxAge; } /** - * The UNIX timestamp when the cookie Expires + * The UNIX timestamp when the cookie Expires. * - * @return mixed + * @return string|int|null */ public function getExpires() { @@ -213,19 +222,19 @@ public function getExpires() } /** - * Set the unix timestamp for which the cookie will expire + * Set the unix timestamp for which the cookie will expire. * - * @param int $timestamp Unix timestamp + * @param int|string $timestamp Unix timestamp or any English textual datetime description. */ - public function setExpires($timestamp) + public function setExpires($timestamp): void { - $this->data['Expires'] = is_numeric($timestamp) + $this->data['Expires'] = \is_numeric($timestamp) ? (int) $timestamp - : strtotime($timestamp); + : \strtotime($timestamp); } /** - * Get whether or not this is a secure cookie + * Get whether or not this is a secure cookie. * * @return bool|null */ @@ -235,17 +244,17 @@ public function getSecure() } /** - * Set whether or not the cookie is secure + * Set whether or not the cookie is secure. * * @param bool $secure Set to true or false if secure */ - public function setSecure($secure) + public function setSecure($secure): void { $this->data['Secure'] = $secure; } /** - * Get whether or not this is a session cookie + * Get whether or not this is a session cookie. * * @return bool|null */ @@ -255,17 +264,17 @@ public function getDiscard() } /** - * Set whether or not this is a session cookie + * Set whether or not this is a session cookie. * * @param bool $discard Set to true or false if this is a session cookie */ - public function setDiscard($discard) + public function setDiscard($discard): void { $this->data['Discard'] = $discard; } /** - * Get whether or not this is an HTTP only cookie + * Get whether or not this is an HTTP only cookie. * * @return bool */ @@ -275,11 +284,11 @@ public function getHttpOnly() } /** - * Set whether or not this is an HTTP only cookie + * Set whether or not this is an HTTP only cookie. * * @param bool $httpOnly Set to true or false if this is HTTP only */ - public function setHttpOnly($httpOnly) + public function setHttpOnly($httpOnly): void { $this->data['HttpOnly'] = $httpOnly; } @@ -298,10 +307,8 @@ public function setHttpOnly($httpOnly) * path is a %x2F ("/") character. * * @param string $requestPath Path to check against - * - * @return bool */ - public function matchesPath($requestPath) + public function matchesPath(string $requestPath): bool { $cookiePath = $this->getPath(); @@ -311,71 +318,71 @@ public function matchesPath($requestPath) } // Ensure that the cookie-path is a prefix of the request path. - if (0 !== strpos($requestPath, $cookiePath)) { + if (0 !== \strpos($requestPath, $cookiePath)) { return false; } // Match if the last character of the cookie-path is "/" - if (substr($cookiePath, -1, 1) === '/') { + if (\substr($cookiePath, -1, 1) === '/') { return true; } // Match if the first character not included in cookie path is "/" - return substr($requestPath, strlen($cookiePath), 1) === '/'; + return \substr($requestPath, \strlen($cookiePath), 1) === '/'; } /** - * Check if the cookie matches a domain value + * Check if the cookie matches a domain value. * * @param string $domain Domain to check against - * - * @return bool */ - public function matchesDomain($domain) + public function matchesDomain(string $domain): bool { + $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(), '.'); + // https://tools.ietf.org/html/rfc6265#section-5.2.3 + $cookieDomain = \ltrim($cookieDomain, '.'); // Domain not set or exact match. - if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { + if (!$cookieDomain || !\strcasecmp($domain, $cookieDomain)) { return true; } // Matching the subdomain according to RFC 6265. - // http://tools.ietf.org/html/rfc6265#section-5.1.3 - if (filter_var($domain, FILTER_VALIDATE_IP)) { + // https://tools.ietf.org/html/rfc6265#section-5.1.3 + if (\filter_var($domain, \FILTER_VALIDATE_IP)) { return false; } - return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/', $domain); + return (bool) \preg_match('/\.' . \preg_quote($cookieDomain, '/') . '$/', $domain); } /** - * Check if the cookie is expired - * - * @return bool + * Check if the cookie is expired. */ - public function isExpired() + public function isExpired(): bool { - return $this->getExpires() !== null && time() > $this->getExpires(); + return $this->getExpires() !== null && \time() > $this->getExpires(); } /** - * Check if the cookie is valid according to RFC 6265 + * Check if the cookie is valid according to RFC 6265. * * @return bool|string Returns true if valid or an error message if invalid */ public function validate() { - // Names must not be empty, but can be 0 $name = $this->getName(); - if (empty($name) && !is_numeric($name)) { + if ($name === '') { return 'The cookie name must not be empty'; } // Check if any of the invalid characters are present in the cookie name - if (preg_match( + if (\preg_match( '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/', $name )) { @@ -384,17 +391,17 @@ public function validate() . 'following characters: ()<>@,;:\"/?={}'; } - // Value must not be empty, but can be 0 + // Value must not be null. 0 and empty string are valid. Empty strings + // are technically against RFC 6265, but known to happen in the wild. $value = $this->getValue(); - if (empty($value) && !is_numeric($value)) { + if ($value === null) { return 'The cookie value must not be empty'; } - // Domains must not be empty, but can be 0 - // A "0" is not a valid internet domain, but may be used as server name - // in a private network. + // Domains must not be empty, but can be 0. "0" is not a valid internet + // domain, but may be used as server name in a private network. $domain = $this->getDomain(); - if (empty($domain) && !is_numeric($domain)) { + if ($domain === null || $domain === '') { return 'The cookie domain must not be empty'; } diff --git a/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/guzzlehttp/guzzle/src/Exception/BadResponseException.php index 427d896fb..a80956c9d 100644 --- a/guzzlehttp/guzzle/src/Exception/BadResponseException.php +++ b/guzzlehttp/guzzle/src/Exception/BadResponseException.php @@ -1,4 +1,5 @@ request = $request; + $this->handlerContext = $handlerContext; } /** - * @return null + * Get the request that caused the exception */ - public function getResponse() + public function getRequest(): RequestInterface { - return null; + return $this->request; } /** - * @return bool + * Get contextual information about the error from the underlying handler. + * + * The contents of this array will vary depending on which handler you are + * using. It may also be just an empty array. Relying on this data will + * couple you to a specific handler, but can give more debug information + * when needed. */ - public function hasResponse() + public function getHandlerContext(): array { - return false; + return $this->handlerContext; } } diff --git a/guzzlehttp/guzzle/src/Exception/GuzzleException.php b/guzzlehttp/guzzle/src/Exception/GuzzleException.php index 27b2722b0..fa3ed6998 100644 --- a/guzzlehttp/guzzle/src/Exception/GuzzleException.php +++ b/guzzlehttp/guzzle/src/Exception/GuzzleException.php @@ -1,23 +1,9 @@ getStatusCode() - : 0; + $code = $response ? $response->getStatusCode() : 0; parent::__construct($message, $code, $previous); $this->request = $request; $this->response = $response; @@ -39,46 +46,39 @@ public function __construct( /** * Wrap non-RequestExceptions with a RequestException - * - * @param RequestInterface $request - * @param \Exception $e - * - * @return RequestException */ - public static function wrapException(RequestInterface $request, \Exception $e) + public static function wrapException(RequestInterface $request, \Throwable $e): RequestException { - return $e instanceof RequestException - ? $e - : new RequestException($e->getMessage(), $request, null, $e); + return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e); } /** * Factory method to create a new exception with a normalized error message * - * @param RequestInterface $request Request - * @param ResponseInterface $response Response received - * @param \Exception $previous Previous exception - * @param array $ctx Optional handler context. - * - * @return self + * @param RequestInterface $request Request sent + * @param ResponseInterface $response Response received + * @param \Throwable|null $previous Previous exception + * @param array $handlerContext Optional handler context + * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer */ public static function create( RequestInterface $request, ResponseInterface $response = null, - \Exception $previous = null, - array $ctx = [] - ) { + \Throwable $previous = null, + array $handlerContext = [], + BodySummarizerInterface $bodySummarizer = null + ): self { if (!$response) { return new self( 'Error completing request', $request, null, $previous, - $ctx + $handlerContext ); } - $level = (int) floor($response->getStatusCode() / 100); + $level = (int) \floor($response->getStatusCode() / 100); if ($level === 4) { $label = 'Client error'; $className = ClientException::class; @@ -95,7 +95,7 @@ public static function create( // Client Error: `GET /` resulted in a `404 Not Found` response: // ... (truncated) - $message = sprintf( + $message = \sprintf( '%s: `%s %s` resulted in a `%s %s` response', $label, $request->getMethod(), @@ -104,42 +104,24 @@ public static function create( $response->getReasonPhrase() ); - $summary = static::getResponseBodySummary($response); + $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response); if ($summary !== null) { $message .= ":\n{$summary}\n"; } - return new $className($message, $request, $response, $previous, $ctx); - } - - /** - * Get a short summary of the response - * - * Will return `null` if the response is not printable. - * - * @param ResponseInterface $response - * - * @return string|null - */ - public static function getResponseBodySummary(ResponseInterface $response) - { - return \GuzzleHttp\Psr7\get_message_body_summary($response); + return new $className($message, $request, $response, $previous, $handlerContext); } /** * Obfuscates URI if there is a username and a password present - * - * @param UriInterface $uri - * - * @return UriInterface */ - private static function obfuscateUri(UriInterface $uri) + private static function obfuscateUri(UriInterface $uri): UriInterface { $userInfo = $uri->getUserInfo(); - if (false !== ($pos = strpos($userInfo, ':'))) { - return $uri->withUserInfo(substr($userInfo, 0, $pos), '***'); + if (false !== ($pos = \strpos($userInfo, ':'))) { + return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***'); } return $uri; @@ -147,30 +129,24 @@ private static function obfuscateUri(UriInterface $uri) /** * Get the request that caused the exception - * - * @return RequestInterface */ - public function getRequest() + public function getRequest(): RequestInterface { return $this->request; } /** * Get the associated response - * - * @return ResponseInterface|null */ - public function getResponse() + public function getResponse(): ?ResponseInterface { return $this->response; } /** * Check if a response was received - * - * @return bool */ - public function hasResponse() + public function hasResponse(): bool { return $this->response !== null; } @@ -182,10 +158,8 @@ public function hasResponse() * using. It may also be just an empty array. Relying on this data will * couple you to a specific handler, but can give more debug information * when needed. - * - * @return array */ - public function getHandlerContext() + public function getHandlerContext(): array { return $this->handlerContext; } diff --git a/guzzlehttp/guzzle/src/Exception/SeekException.php b/guzzlehttp/guzzle/src/Exception/SeekException.php deleted file mode 100644 index a77c28926..000000000 --- a/guzzlehttp/guzzle/src/Exception/SeekException.php +++ /dev/null @@ -1,27 +0,0 @@ -stream = $stream; - $msg = $msg ?: 'Could not seek the stream to position ' . $pos; - parent::__construct($msg); - } - - /** - * @return StreamInterface - */ - public function getStream() - { - return $this->stream; - } -} diff --git a/guzzlehttp/guzzle/src/Exception/ServerException.php b/guzzlehttp/guzzle/src/Exception/ServerException.php index 127094c14..8055e067c 100644 --- a/guzzlehttp/guzzle/src/Exception/ServerException.php +++ b/guzzlehttp/guzzle/src/Exception/ServerException.php @@ -1,4 +1,5 @@ maxHandles = $maxHandles; } - public function create(RequestInterface $request, array $options) + public function create(RequestInterface $request, array $options): EasyHandle { if (isset($options['curl']['body_as_string'])) { $options['_body_as_string'] = $options['curl']['body_as_string']; @@ -49,35 +62,33 @@ public function create(RequestInterface $request, array $options) // Add handler options from the request configuration options if (isset($options['curl'])) { - $conf = array_replace($conf, $options['curl']); + $conf = \array_replace($conf, $options['curl']); } - $conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy); - $easy->handle = $this->handles - ? array_pop($this->handles) - : curl_init(); + $conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy); + $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init(); curl_setopt_array($easy->handle, $conf); return $easy; } - public function release(EasyHandle $easy) + public function release(EasyHandle $easy): void { $resource = $easy->handle; unset($easy->handle); - if (count($this->handles) >= $this->maxHandles) { - curl_close($resource); + if (\count($this->handles) >= $this->maxHandles) { + \curl_close($resource); } else { // Remove all callback functions as they can hold onto references // and are not cleaned up by curl_reset. Using curl_setopt_array // does not work for some reason, so removing each one // individually. - curl_setopt($resource, CURLOPT_HEADERFUNCTION, null); - curl_setopt($resource, CURLOPT_READFUNCTION, null); - curl_setopt($resource, CURLOPT_WRITEFUNCTION, null); - curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null); - curl_reset($resource); + \curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null); + \curl_setopt($resource, \CURLOPT_READFUNCTION, null); + \curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null); + \curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null); + \curl_reset($resource); $this->handles[] = $resource; } } @@ -86,17 +97,11 @@ public function release(EasyHandle $easy) * Completes a cURL transaction, either returning a response promise or a * rejected promise. * - * @param callable $handler - * @param EasyHandle $easy - * @param CurlFactoryInterface $factory Dictates how the handle is released - * - * @return \GuzzleHttp\Promise\PromiseInterface + * @param callable(RequestInterface, array): PromiseInterface $handler + * @param CurlFactoryInterface $factory Dictates how the handle is released */ - public static function finish( - callable $handler, - EasyHandle $easy, - CurlFactoryInterface $factory - ) { + public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface + { if (isset($easy->options['on_stats'])) { self::invokeStats($easy); } @@ -117,10 +122,10 @@ public static function finish( return new FulfilledPromise($easy->response); } - private static function invokeStats(EasyHandle $easy) + private static function invokeStats(EasyHandle $easy): void { - $curlStats = curl_getinfo($easy->handle); - $curlStats['appconnect_time'] = curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME); + $curlStats = \curl_getinfo($easy->handle); + $curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME); $stats = new TransferStats( $easy->request, $easy->response, @@ -128,47 +133,57 @@ private static function invokeStats(EasyHandle $easy) $easy->errno, $curlStats ); - call_user_func($easy->options['on_stats'], $stats); + ($easy->options['on_stats'])($stats); } - private static function finishError( - callable $handler, - EasyHandle $easy, - CurlFactoryInterface $factory - ) { + /** + * @param callable(RequestInterface, array): PromiseInterface $handler + */ + private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface + { // Get error information and release the handle to the factory. $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']; + '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); // Retry when nothing is present or when curl failed to rewind. - if (empty($easy->options['_err_message']) - && (!$easy->errno || $easy->errno == 65) - ) { + if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) { return self::retryFailedRewind($handler, $easy, $ctx); } return self::createRejection($easy, $ctx); } - private static function createRejection(EasyHandle $easy, array $ctx) + private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface { static $connectionErrors = [ - CURLE_OPERATION_TIMEOUTED => true, - CURLE_COULDNT_RESOLVE_HOST => true, - CURLE_COULDNT_CONNECT => true, - CURLE_SSL_CONNECT_ERROR => true, - CURLE_GOT_NOTHING => true, + \CURLE_OPERATION_TIMEOUTED => true, + \CURLE_COULDNT_RESOLVE_HOST => true, + \CURLE_COULDNT_CONNECT => true, + \CURLE_SSL_CONNECT_ERROR => true, + \CURLE_GOT_NOTHING => true, ]; + if ($easy->createResponseException) { + return P\Create::rejectionFor( + new RequestException( + 'An error was encountered while creating the response', + $easy->request, + $easy->response, + $easy->createResponseException, + $ctx + ) + ); + } + // If an exception was encountered during the onHeaders event, then // return a rejected promise that wraps that exception. if ($easy->onHeadersException) { - return \GuzzleHttp\Promise\rejection_for( + return P\Create::rejectionFor( new RequestException( 'An error was encountered during the on_headers event', $easy->request, @@ -178,21 +193,16 @@ private static function createRejection(EasyHandle $easy, array $ctx) ) ); } - 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() - ); + + $message = \sprintf( + 'cURL error %s: %s (%s)', + $ctx['errno'], + $ctx['error'], + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' + ); + $uriString = (string) $easy->request->getUri(); + if ($uriString !== '' && false === \strpos($ctx['error'], $uriString)) { + $message .= \sprintf(' for %s', $uriString); } // Create a connection exception if it was a specific error code. @@ -200,37 +210,40 @@ private static function createRejection(EasyHandle $easy, array $ctx) ? new ConnectException($message, $easy->request, null, $ctx) : new RequestException($message, $easy->request, $easy->response, null, $ctx); - return \GuzzleHttp\Promise\rejection_for($error); + return P\Create::rejectionFor($error); } - private function getDefaultConf(EasyHandle $easy) + /** + * @return array + */ + private function getDefaultConf(EasyHandle $easy): array { $conf = [ - '_headers' => $easy->request->getHeaders(), - CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), - CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), - CURLOPT_RETURNTRANSFER => false, - CURLOPT_HEADER => false, - CURLOPT_CONNECTTIMEOUT => 150, + '_headers' => $easy->request->getHeaders(), + \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), + \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), + \CURLOPT_RETURNTRANSFER => false, + \CURLOPT_HEADER => false, + \CURLOPT_CONNECTTIMEOUT => 150, ]; - if (defined('CURLOPT_PROTOCOLS')) { - $conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; + if (\defined('CURLOPT_PROTOCOLS')) { + $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS; } $version = $easy->request->getProtocolVersion(); if ($version == 1.1) { - $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; + $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; } elseif ($version == 2.0) { - $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; + $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0; } else { - $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; + $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0; } return $conf; } - private function applyMethod(EasyHandle $easy, array &$conf) + private function applyMethod(EasyHandle $easy, array &$conf): void { $body = $easy->request->getBody(); $size = $body->getSize(); @@ -242,22 +255,22 @@ private function applyMethod(EasyHandle $easy, array &$conf) $method = $easy->request->getMethod(); if ($method === 'PUT' || $method === 'POST') { - // See http://tools.ietf.org/html/rfc7230#section-3.3.2 + // See https://tools.ietf.org/html/rfc7230#section-3.3.2 if (!$easy->request->hasHeader('Content-Length')) { - $conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; + $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; } } elseif ($method === 'HEAD') { - $conf[CURLOPT_NOBODY] = true; + $conf[\CURLOPT_NOBODY] = true; unset( - $conf[CURLOPT_WRITEFUNCTION], - $conf[CURLOPT_READFUNCTION], - $conf[CURLOPT_FILE], - $conf[CURLOPT_INFILE] + $conf[\CURLOPT_WRITEFUNCTION], + $conf[\CURLOPT_READFUNCTION], + $conf[\CURLOPT_FILE], + $conf[\CURLOPT_INFILE] ); } } - private function applyBody(RequestInterface $request, array $options, array &$conf) + private function applyBody(RequestInterface $request, array $options, array &$conf): void { $size = $request->hasHeader('Content-Length') ? (int) $request->getHeaderLine('Content-Length') @@ -265,40 +278,38 @@ private function applyBody(RequestInterface $request, array $options, array &$co // Send the body as a string if the size is less than 1MB OR if the // [curl][body_as_string] request value is set. - if (($size !== null && $size < 1000000) || - !empty($options['_body_as_string']) - ) { - $conf[CURLOPT_POSTFIELDS] = (string) $request->getBody(); + if (($size !== null && $size < 1000000) || !empty($options['_body_as_string'])) { + $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody(); // Don't duplicate the Content-Length header $this->removeHeader('Content-Length', $conf); $this->removeHeader('Transfer-Encoding', $conf); } else { - $conf[CURLOPT_UPLOAD] = true; + $conf[\CURLOPT_UPLOAD] = true; if ($size !== null) { - $conf[CURLOPT_INFILESIZE] = $size; + $conf[\CURLOPT_INFILESIZE] = $size; $this->removeHeader('Content-Length', $conf); } $body = $request->getBody(); if ($body->isSeekable()) { $body->rewind(); } - $conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) { + $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body) { return $body->read($length); }; } // If the Expect header is not present, prevent curl from adding it if (!$request->hasHeader('Expect')) { - $conf[CURLOPT_HTTPHEADER][] = 'Expect:'; + $conf[\CURLOPT_HTTPHEADER][] = 'Expect:'; } // cURL sometimes adds a content-type by default. Prevent this. if (!$request->hasHeader('Content-Type')) { - $conf[CURLOPT_HTTPHEADER][] = 'Content-Type:'; + $conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:'; } } - private function applyHeaders(EasyHandle $easy, array &$conf) + private function applyHeaders(EasyHandle $easy, array &$conf): void { foreach ($conf['_headers'] as $name => $values) { foreach ($values as $value) { @@ -306,16 +317,16 @@ private function applyHeaders(EasyHandle $easy, array &$conf) if ($value === '') { // cURL requires a special format for empty headers. // See https://github.com/guzzle/guzzle/issues/1882 for more details. - $conf[CURLOPT_HTTPHEADER][] = "$name;"; + $conf[\CURLOPT_HTTPHEADER][] = "$name;"; } else { - $conf[CURLOPT_HTTPHEADER][] = "$name: $value"; + $conf[\CURLOPT_HTTPHEADER][] = "$name: $value"; } } } // Remove the Accept header if one was not set if (!$easy->request->hasHeader('Accept')) { - $conf[CURLOPT_HTTPHEADER][] = 'Accept:'; + $conf[\CURLOPT_HTTPHEADER][] = 'Accept:'; } } @@ -325,115 +336,112 @@ private function applyHeaders(EasyHandle $easy, array &$conf) * @param string $name Case-insensitive header to remove * @param array $options Array of options to modify */ - private function removeHeader($name, array &$options) + private function removeHeader(string $name, array &$options): void { - foreach (array_keys($options['_headers']) as $key) { - if (!strcasecmp($key, $name)) { + foreach (\array_keys($options['_headers']) as $key) { + if (!\strcasecmp($key, $name)) { unset($options['_headers'][$key]); return; } } } - private function applyHandlerOptions(EasyHandle $easy, array &$conf) + private function applyHandlerOptions(EasyHandle $easy, array &$conf): void { $options = $easy->options; if (isset($options['verify'])) { if ($options['verify'] === false) { - unset($conf[CURLOPT_CAINFO]); - $conf[CURLOPT_SSL_VERIFYHOST] = 0; - $conf[CURLOPT_SSL_VERIFYPEER] = false; + unset($conf[\CURLOPT_CAINFO]); + $conf[\CURLOPT_SSL_VERIFYHOST] = 0; + $conf[\CURLOPT_SSL_VERIFYPEER] = false; } else { - $conf[CURLOPT_SSL_VERIFYHOST] = 2; - $conf[CURLOPT_SSL_VERIFYPEER] = true; - if (is_string($options['verify'])) { + $conf[\CURLOPT_SSL_VERIFYHOST] = 2; + $conf[\CURLOPT_SSL_VERIFYPEER] = true; + if (\is_string($options['verify'])) { // Throw an error if the file/folder/link path is not valid or doesn't exist. - if (!file_exists($options['verify'])) { - throw new \InvalidArgumentException( - "SSL CA bundle not found: {$options['verify']}" - ); + if (!\file_exists($options['verify'])) { + throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}"); } // If it's a directory or a link to a directory use CURLOPT_CAPATH. // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. - if (is_dir($options['verify']) || - (is_link($options['verify']) && is_dir(readlink($options['verify'])))) { - $conf[CURLOPT_CAPATH] = $options['verify']; + if ( + \is_dir($options['verify']) || + ( + \is_link($options['verify']) === true && + ($verifyLink = \readlink($options['verify'])) !== false && + \is_dir($verifyLink) + ) + ) { + $conf[\CURLOPT_CAPATH] = $options['verify']; } else { - $conf[CURLOPT_CAINFO] = $options['verify']; + $conf[\CURLOPT_CAINFO] = $options['verify']; } } } } - if (!empty($options['decode_content'])) { + if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) { $accept = $easy->request->getHeaderLine('Accept-Encoding'); if ($accept) { - $conf[CURLOPT_ENCODING] = $accept; + $conf[\CURLOPT_ENCODING] = $accept; } else { - $conf[CURLOPT_ENCODING] = ''; + $conf[\CURLOPT_ENCODING] = ''; // Don't let curl send the header over the wire - $conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; + $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; } } - if (isset($options['sink'])) { - $sink = $options['sink']; - if (!is_string($sink)) { - $sink = \GuzzleHttp\Psr7\stream_for($sink); - } elseif (!is_dir(dirname($sink))) { - // Ensure that the directory exists before failing in curl. - throw new \RuntimeException(sprintf( - 'Directory %s does not exist for sink value of %s', - dirname($sink), - $sink - )); - } else { - $sink = new LazyOpenStream($sink, 'w+'); - } - $easy->sink = $sink; - $conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) { - return $sink->write($write); - }; - } else { + if (!isset($options['sink'])) { // Use a default temp stream if no sink was set. - $conf[CURLOPT_FILE] = fopen('php://temp', 'w+'); - $easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]); + $options['sink'] = \fopen('php://temp', 'w+'); + } + $sink = $options['sink']; + if (!\is_string($sink)) { + $sink = \GuzzleHttp\Psr7\stream_for($sink); + } elseif (!\is_dir(\dirname($sink))) { + // Ensure that the directory exists before failing in curl. + throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink)); + } else { + $sink = new LazyOpenStream($sink, 'w+'); } + $easy->sink = $sink; + $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use ($sink): int { + return $sink->write($write); + }; + $timeoutRequiresNoSignal = false; if (isset($options['timeout'])) { $timeoutRequiresNoSignal |= $options['timeout'] < 1; - $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; + $conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; } // CURL default value is CURL_IPRESOLVE_WHATEVER if (isset($options['force_ip_resolve'])) { if ('v4' === $options['force_ip_resolve']) { - $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; + $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4; } elseif ('v6' === $options['force_ip_resolve']) { - $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6; + $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6; } } if (isset($options['connect_timeout'])) { $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1; - $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; + $conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; } - if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { - $conf[CURLOPT_NOSIGNAL] = true; + if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') { + $conf[\CURLOPT_NOSIGNAL] = true; } if (isset($options['proxy'])) { - if (!is_array($options['proxy'])) { - $conf[CURLOPT_PROXY] = $options['proxy']; + if (!\is_array($options['proxy'])) { + $conf[\CURLOPT_PROXY] = $options['proxy']; } else { $scheme = $easy->request->getUri()->getScheme(); if (isset($options['proxy'][$scheme])) { $host = $easy->request->getUri()->getHost(); - if (!isset($options['proxy']['no']) || - !\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no']) - ) { - $conf[CURLOPT_PROXY] = $options['proxy'][$scheme]; + if (!isset($options['proxy']['no']) || !Utils::isHostInNoProxy($host, $options['proxy']['no'])) { + $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme]; } } } @@ -441,58 +449,47 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf) if (isset($options['cert'])) { $cert = $options['cert']; - if (is_array($cert)) { - $conf[CURLOPT_SSLCERTPASSWD] = $cert[1]; + if (\is_array($cert)) { + $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1]; $cert = $cert[0]; } - if (!file_exists($cert)) { - throw new \InvalidArgumentException( - "SSL certificate not found: {$cert}" - ); + if (!\file_exists($cert)) { + throw new \InvalidArgumentException("SSL certificate not found: {$cert}"); } - $conf[CURLOPT_SSLCERT] = $cert; + $conf[\CURLOPT_SSLCERT] = $cert; } if (isset($options['ssl_key'])) { - if (is_array($options['ssl_key'])) { - if (count($options['ssl_key']) === 2) { - list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key']; + if (\is_array($options['ssl_key'])) { + if (\count($options['ssl_key']) === 2) { + [$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key']; } else { - list($sslKey) = $options['ssl_key']; + [$sslKey] = $options['ssl_key']; } } - $sslKey = isset($sslKey) ? $sslKey: $options['ssl_key']; + $sslKey = $sslKey ?? $options['ssl_key']; - if (!file_exists($sslKey)) { - throw new \InvalidArgumentException( - "SSL private key not found: {$sslKey}" - ); + if (!\file_exists($sslKey)) { + throw new \InvalidArgumentException("SSL private key not found: {$sslKey}"); } - $conf[CURLOPT_SSLKEY] = $sslKey; + $conf[\CURLOPT_SSLKEY] = $sslKey; } if (isset($options['progress'])) { $progress = $options['progress']; - if (!is_callable($progress)) { - throw new \InvalidArgumentException( - 'progress client option must be callable' - ); + if (!\is_callable($progress)) { + throw new \InvalidArgumentException('progress client option must be callable'); } - $conf[CURLOPT_NOPROGRESS] = false; - $conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) { - $args = func_get_args(); - // PHP 5.5 pushed the handle onto the start of the args - if (is_resource($args[0])) { - array_shift($args); - } - call_user_func_array($progress, $args); + $conf[\CURLOPT_NOPROGRESS] = false; + $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use ($progress) { + $progress($downloadSize, $downloaded, $uploadSize, $uploaded); }; } if (!empty($options['debug'])) { - $conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']); - $conf[CURLOPT_VERBOSE] = true; + $conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']); + $conf[\CURLOPT_VERBOSE] = true; } } @@ -504,12 +501,11 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf) * stream, and then encountered a "necessary data rewind wasn't possible" * error, causing the request to be sent through curl_multi_info_read() * without an error status. + * + * @param callable(RequestInterface, array): PromiseInterface $handler */ - private static function retryFailedRewind( - callable $handler, - EasyHandle $easy, - array $ctx - ) { + private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx): PromiseInterface + { try { // Only rewind if the body has been read from. $body = $easy->request->getBody(); @@ -542,27 +538,32 @@ private static function retryFailedRewind( return $handler($easy->request, $easy->options); } - private function createHeaderFn(EasyHandle $easy) + private function createHeaderFn(EasyHandle $easy): callable { if (isset($easy->options['on_headers'])) { $onHeaders = $easy->options['on_headers']; - if (!is_callable($onHeaders)) { + if (!\is_callable($onHeaders)) { throw new \InvalidArgumentException('on_headers must be callable'); } } else { $onHeaders = null; } - return function ($ch, $h) use ( + return static function ($ch, $h) use ( $onHeaders, $easy, &$startingResponse ) { - $value = trim($h); + $value = \trim($h); if ($value === '') { $startingResponse = true; - $easy->createResponse(); + try { + $easy->createResponse(); + } catch (\Exception $e) { + $easy->createResponseException = $e; + return -1; + } if ($onHeaders !== null) { try { $onHeaders($easy->response); @@ -579,7 +580,7 @@ private function createHeaderFn(EasyHandle $easy) } else { $easy->headers[] = $value; } - return strlen($h); + return \strlen($h); }; } } diff --git a/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php b/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php index b0fc23685..fe57ed5d5 100644 --- a/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php +++ b/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php @@ -1,4 +1,5 @@ factory = isset($options['handle_factory']) - ? $options['handle_factory'] - : new CurlFactory(3); + $this->factory = $options['handle_factory'] + ?? new CurlFactory(3); } - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (isset($options['delay'])) { - usleep($options['delay'] * 1000); + \usleep($options['delay'] * 1000); } $easy = $this->factory->create($request, $options); - curl_exec($easy->handle); - $easy->errno = curl_errno($easy->handle); + \curl_exec($easy->handle); + $easy->errno = \curl_errno($easy->handle); return CurlFactory::finish($this, $easy, $this->factory); } diff --git a/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php index 564c95f48..4e312631c 100644 --- a/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php +++ b/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php @@ -1,8 +1,10 @@ An array of delay times, indexed by handle id in `addRequest`. + * + * @see CurlMultiHandler::addRequest + */ private $delays = []; + + /** + * @var array An associative array of CURLMOPT_* options and corresponding values for curl_multi_setopt() + */ private $options = []; /** @@ -33,52 +63,62 @@ class CurlMultiHandler * out while selecting curl handles. Defaults to 1 second. * - options: An associative array of CURLMOPT_* options and * corresponding values for curl_multi_setopt() - * - * @param array $options */ public function __construct(array $options = []) { - $this->factory = isset($options['handle_factory']) - ? $options['handle_factory'] : new CurlFactory(50); + $this->factory = $options['handle_factory'] ?? new CurlFactory(50); if (isset($options['select_timeout'])) { $this->selectTimeout = $options['select_timeout']; - } elseif ($selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { - $this->selectTimeout = $selectTimeout; + } elseif ($selectTimeout = Utils::getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { + @trigger_error('Since guzzlehttp/guzzle 7.2.0: Using environment variable GUZZLE_CURL_SELECT_TIMEOUT is deprecated. Use option "select_timeout" instead.', \E_USER_DEPRECATED); + $this->selectTimeout = (int) $selectTimeout; } else { $this->selectTimeout = 1; } - $this->options = isset($options['options']) ? $options['options'] : []; + $this->options = $options['options'] ?? []; } + /** + * @param string $name + * + * @return resource|\CurlMultiHandle + * + * @throws \BadMethodCallException when another field as `_mh` will be gotten + * @throws \RuntimeException when curl can not initialize a multi handle + */ public function __get($name) { - if ($name === '_mh') { - $this->_mh = curl_multi_init(); + if ($name !== '_mh') { + throw new \BadMethodCallException("Can not get other property as '_mh'."); + } - foreach ($this->options as $option => $value) { - // A warning is raised in case of a wrong option. - curl_multi_setopt($this->_mh, $option, $value); - } + $multiHandle = \curl_multi_init(); + + if (false === $multiHandle) { + throw new \RuntimeException('Can not initialize curl multi handle.'); + } + + $this->_mh = $multiHandle; - // Further calls to _mh will return the value directly, without entering the - // __get() method at all. - return $this->_mh; + foreach ($this->options as $option => $value) { + // A warning is raised in case of a wrong option. + curl_multi_setopt($this->_mh, $option, $value); } - throw new \BadMethodCallException(); + return $this->_mh; } public function __destruct() { if (isset($this->_mh)) { - curl_multi_close($this->_mh); + \curl_multi_close($this->_mh); unset($this->_mh); } } - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { $easy = $this->factory->create($request, $options); $id = (int) $easy->handle; @@ -98,7 +138,7 @@ function () use ($id) { /** * Ticks the curl event loop. */ - public function tick() + public function tick(): void { // Add any delayed handles if needed. if ($this->delays) { @@ -106,7 +146,7 @@ public function tick() foreach ($this->delays as $id => $delay) { if ($currentTime >= $delay) { unset($this->delays[$id]); - curl_multi_add_handle( + \curl_multi_add_handle( $this->_mh, $this->handles[$id]['easy']->handle ); @@ -115,17 +155,15 @@ public function tick() } // Step through the task queue which may add additional requests. - P\queue()->run(); + P\Utils::queue()->run(); - if ($this->active && - curl_multi_select($this->_mh, $this->selectTimeout) === -1 - ) { + if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) { // Perform a usleep if a select returns -1. // See: https://bugs.php.net/bug.php?id=61141 - usleep(250); + \usleep(250); } - while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM); + while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM); $this->processMessages(); } @@ -133,26 +171,26 @@ public function tick() /** * Runs until all outstanding connections have completed. */ - public function execute() + public function execute(): void { - $queue = P\queue(); + $queue = P\Utils::queue(); while ($this->handles || !$queue->isEmpty()) { // If there are no transfers, then sleep for the next delay if (!$this->active && $this->delays) { - usleep($this->timeToNext()); + \usleep($this->timeToNext()); } $this->tick(); } } - private function addRequest(array $entry) + private function addRequest(array $entry): void { $easy = $entry['easy']; $id = (int) $easy->handle; $this->handles[$id] = $entry; if (empty($easy->options['delay'])) { - curl_multi_add_handle($this->_mh, $easy->handle); + \curl_multi_add_handle($this->_mh, $easy->handle); } else { $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000); } @@ -165,7 +203,7 @@ private function addRequest(array $entry) * * @return bool True on success, false on failure. */ - private function cancel($id) + private function cancel($id): bool { // Cannot cancel if it has been processed. if (!isset($this->handles[$id])) { @@ -174,17 +212,17 @@ private function cancel($id) $handle = $this->handles[$id]['easy']->handle; unset($this->delays[$id], $this->handles[$id]); - curl_multi_remove_handle($this->_mh, $handle); - curl_close($handle); + \curl_multi_remove_handle($this->_mh, $handle); + \curl_close($handle); return true; } - private function processMessages() + private function processMessages(): void { - while ($done = curl_multi_info_read($this->_mh)) { + while ($done = \curl_multi_info_read($this->_mh)) { $id = (int) $done['handle']; - curl_multi_remove_handle($this->_mh, $done['handle']); + \curl_multi_remove_handle($this->_mh, $done['handle']); if (!isset($this->handles[$id])) { // Probably was cancelled. @@ -195,25 +233,21 @@ private function processMessages() unset($this->handles[$id], $this->delays[$id]); $entry['easy']->errno = $done['result']; $entry['deferred']->resolve( - CurlFactory::finish( - $this, - $entry['easy'], - $this->factory - ) + CurlFactory::finish($this, $entry['easy'], $this->factory) ); } } - private function timeToNext() + private function timeToNext(): int { $currentTime = Utils::currentTime(); - $nextTime = PHP_INT_MAX; + $nextTime = \PHP_INT_MAX; foreach ($this->delays as $time) { if ($time < $nextTime) { $nextTime = $time; } } - return max(0, $nextTime - $currentTime) * 1000000; + return ((int) \max(0, $nextTime - $currentTime)) * 1000000; } } diff --git a/guzzlehttp/guzzle/src/Handler/EasyHandle.php b/guzzlehttp/guzzle/src/Handler/EasyHandle.php index 7754e9111..a68c62f08 100644 --- a/guzzlehttp/guzzle/src/Handler/EasyHandle.php +++ b/guzzlehttp/guzzle/src/Handler/EasyHandle.php @@ -1,7 +1,9 @@ headers)) { throw new \RuntimeException('No headers have been received'); } // HTTP-version SP status-code SP reason-phrase - $startLine = explode(' ', array_shift($this->headers), 3); - $headers = \GuzzleHttp\headers_from_lines($this->headers); - $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); - - if (!empty($this->options['decode_content']) - && isset($normalizedKeys['content-encoding']) - ) { - $headers['x-encoded-content-encoding'] - = $headers[$normalizedKeys['content-encoding']]; + $startLine = \explode(' ', \array_shift($this->headers), 3); + $headers = Utils::headersFromLines($this->headers); + $normalizedKeys = Utils::normalizeHeaderKeys($headers); + + if (!empty($this->options['decode_content']) && isset($normalizedKeys['content-encoding'])) { + $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']]; unset($headers[$normalizedKeys['content-encoding']]); if (isset($normalizedKeys['content-length'])) { - $headers['x-encoded-content-length'] - = $headers[$normalizedKeys['content-length']]; + $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']]; $bodyLength = (int) $this->sink->getSize(); if ($bodyLength) { @@ -72,21 +91,28 @@ public function createResponse() } } + $statusCode = (int) $startLine[1]; + // Attach a response to the easy handle with the parsed headers. $this->response = new Response( - $startLine[1], + $statusCode, $headers, $this->sink, - substr($startLine[0], 5), + \substr($startLine[0], 5), isset($startLine[2]) ? (string) $startLine[2] : null ); } + /** + * @param string $name + * + * @return void + * + * @throws \BadMethodCallException + */ public function __get($name) { - $msg = $name === 'handle' - ? 'The EasyHandle has been released' - : 'Invalid property: ' . $name; + $msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: ' . $name; throw new \BadMethodCallException($msg); } } diff --git a/guzzlehttp/guzzle/src/Handler/MockHandler.php b/guzzlehttp/guzzle/src/Handler/MockHandler.php index 5b312bc04..79664e279 100644 --- a/guzzlehttp/guzzle/src/Handler/MockHandler.php +++ b/guzzlehttp/guzzle/src/Handler/MockHandler.php @@ -1,81 +1,98 @@ |null $queue The parameters to be passed to the append function, as an indexed array. + * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled. + * @param callable|null $onRejected Callback to invoke when the return value is rejected. */ - public function __construct( - array $queue = null, - callable $onFulfilled = null, - callable $onRejected = null - ) { + public function __construct(array $queue = null, callable $onFulfilled = null, callable $onRejected = null) + { $this->onFulfilled = $onFulfilled; $this->onRejected = $onRejected; if ($queue) { - call_user_func_array([$this, 'append'], $queue); + // array_values included for BC + $this->append(...array_values($queue)); } } - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (!$this->queue) { throw new \OutOfBoundsException('Mock queue is empty'); } - if (isset($options['delay']) && is_numeric($options['delay'])) { - usleep($options['delay'] * 1000); + if (isset($options['delay']) && \is_numeric($options['delay'])) { + \usleep((int) $options['delay'] * 1000); } $this->lastRequest = $request; $this->lastOptions = $options; - $response = array_shift($this->queue); + $response = \array_shift($this->queue); if (isset($options['on_headers'])) { - if (!is_callable($options['on_headers'])) { + if (!\is_callable($options['on_headers'])) { throw new \InvalidArgumentException('on_headers must be callable'); } try { @@ -86,29 +103,30 @@ public function __invoke(RequestInterface $request, array $options) } } - if (is_callable($response)) { - $response = call_user_func($response, $request, $options); + if (\is_callable($response)) { + $response = $response($request, $options); } - $response = $response instanceof \Exception - ? \GuzzleHttp\Promise\rejection_for($response) - : \GuzzleHttp\Promise\promise_for($response); + $response = $response instanceof \Throwable + ? P\Create::rejectionFor($response) + : P\Create::promiseFor($response); return $response->then( - function ($value) use ($request, $options) { + function (?ResponseInterface $value) use ($request, $options) { $this->invokeStats($request, $options, $value); if ($this->onFulfilled) { - call_user_func($this->onFulfilled, $value); + ($this->onFulfilled)($value); } - if (isset($options['sink'])) { + + if ($value !== null && isset($options['sink'])) { $contents = (string) $value->getBody(); $sink = $options['sink']; - if (is_resource($sink)) { - fwrite($sink, $contents); - } elseif (is_string($sink)) { - file_put_contents($sink, $contents); - } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) { + if (\is_resource($sink)) { + \fwrite($sink, $contents); + } elseif (\is_string($sink)) { + \file_put_contents($sink, $contents); + } elseif ($sink instanceof StreamInterface) { $sink->write($contents); } } @@ -118,9 +136,9 @@ function ($value) use ($request, $options) { function ($reason) use ($request, $options) { $this->invokeStats($request, $options, null, $reason); if ($this->onRejected) { - call_user_func($this->onRejected, $reason); + ($this->onRejected)($reason); } - return \GuzzleHttp\Promise\rejection_for($reason); + return P\Create::rejectionFor($reason); } ); } @@ -128,68 +146,66 @@ function ($reason) use ($request, $options) { /** * Adds one or more variadic requests, exceptions, callables, or promises * to the queue. + * + * @param mixed ...$values */ - public function append() + public function append(...$values): void { - foreach (func_get_args() as $value) { + foreach ($values as $value) { if ($value instanceof ResponseInterface - || $value instanceof \Exception + || $value instanceof \Throwable || $value instanceof PromiseInterface - || is_callable($value) + || \is_callable($value) ) { $this->queue[] = $value; } else { - throw new \InvalidArgumentException('Expected a response or ' - . 'exception. Found ' . \GuzzleHttp\describe_type($value)); + throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found ' . Utils::describeType($value)); } } } /** * Get the last received request. - * - * @return RequestInterface */ - public function getLastRequest() + public function getLastRequest(): ?RequestInterface { return $this->lastRequest; } /** * Get the last received request options. - * - * @return array */ - public function getLastOptions() + public function getLastOptions(): array { return $this->lastOptions; } /** * Returns the number of remaining items in the queue. - * - * @return int */ - public function count() + public function count(): int { - return count($this->queue); + return \count($this->queue); } - public function reset() + public function reset(): void { $this->queue = []; } + /** + * @param mixed $reason Promise or reason. + */ private function invokeStats( RequestInterface $request, array $options, ResponseInterface $response = null, $reason = null - ) { + ): void { if (isset($options['on_stats'])) { - $transferTime = isset($options['transfer_time']) ? $options['transfer_time'] : 0; + $transferTime = $options['transfer_time'] ?? 0; $stats = new TransferStats($request, $response, $transferTime, $reason); - call_user_func($options['on_stats'], $stats); + ($options['on_stats'])($stats); } } } diff --git a/guzzlehttp/guzzle/src/Handler/Proxy.php b/guzzlehttp/guzzle/src/Handler/Proxy.php index f8b00be0b..f045b526c 100644 --- a/guzzlehttp/guzzle/src/Handler/Proxy.php +++ b/guzzlehttp/guzzle/src/Handler/Proxy.php @@ -1,11 +1,15 @@ getMessage(); // This list can probably get more comprehensive. - if (strpos($message, 'getaddrinfo') // DNS lookup failed - || strpos($message, 'Connection refused') - || strpos($message, "couldn't connect to host") // error on HHVM - || strpos($message, "connection attempt failed") + if (false !== \strpos($message, 'getaddrinfo') // DNS lookup failed + || false !== \strpos($message, 'Connection refused') + || false !== \strpos($message, "couldn't connect to host") // error on HHVM + || false !== \strpos($message, "connection attempt failed") ) { $e = new ConnectException($e->getMessage(), $request, $e); + } else { + $e = RequestException::wrapException($request, $e); } - $e = RequestException::wrapException($request, $e); $this->invokeStats($options, $request, $startTime, null, $e); - return \GuzzleHttp\Promise\rejection_for($e); + return P\Create::rejectionFor($e); } } private function invokeStats( array $options, RequestInterface $request, - $startTime, + ?float $startTime, ResponseInterface $response = null, - $error = null - ) { + \Throwable $error = null + ): void { if (isset($options['on_stats'])) { - $stats = new TransferStats( - $request, - $response, - Utils::currentTime() - $startTime, - $error, - [] - ); - call_user_func($options['on_stats'], $stats); + $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []); + ($options['on_stats'])($stats); } } - private function createResponse( - RequestInterface $request, - array $options, - $stream, - $startTime - ) { + /** + * @param resource $stream + */ + private function createResponse(RequestInterface $request, array $options, $stream, ?float $startTime): PromiseInterface + { $hdrs = $this->lastHeaders; $this->lastHeaders = []; - $parts = explode(' ', array_shift($hdrs), 3); - $ver = explode('/', $parts[0])[1]; - $status = $parts[1]; - $reason = isset($parts[2]) ? $parts[2] : null; - $headers = \GuzzleHttp\headers_from_lines($hdrs); - list($stream, $headers) = $this->checkDecode($options, $headers, $stream); - $stream = Psr7\stream_for($stream); + $parts = \explode(' ', \array_shift($hdrs), 3); + $ver = \explode('/', $parts[0])[1]; + $status = (int) $parts[1]; + $reason = $parts[2] ?? null; + $headers = Utils::headersFromLines($hdrs); + [$stream, $headers] = $this->checkDecode($options, $headers, $stream); + $stream = Psr7\Utils::streamFor($stream); $sink = $stream; - if (strcasecmp('HEAD', $request->getMethod())) { + if (\strcasecmp('HEAD', $request->getMethod())) { $sink = $this->createSink($stream, $options); } @@ -120,18 +120,14 @@ private function createResponse( } catch (\Exception $e) { $msg = 'An error was encountered during the on_headers event'; $ex = new RequestException($msg, $request, $response, $e); - return \GuzzleHttp\Promise\rejection_for($ex); + return P\Create::rejectionFor($ex); } } // Do not drain when the request is a HEAD request because they have // no body. if ($sink !== $stream) { - $this->drain( - $stream, - $sink, - $response->getHeaderLine('Content-Length') - ); + $this->drain($stream, $sink, $response->getHeaderLine('Content-Length')); } $this->invokeStats($options, $request, $startTime, $response, null); @@ -139,41 +135,37 @@ private function createResponse( return new FulfilledPromise($response); } - private function createSink(StreamInterface $stream, array $options) + private function createSink(StreamInterface $stream, array $options): StreamInterface { if (!empty($options['stream'])) { return $stream; } - $sink = isset($options['sink']) - ? $options['sink'] - : fopen('php://temp', 'r+'); + $sink = $options['sink'] ?? \fopen('php://temp', 'r+'); - return is_string($sink) - ? new Psr7\LazyOpenStream($sink, 'w+') - : Psr7\stream_for($sink); + return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\Utils::streamFor($sink); } - private function checkDecode(array $options, array $headers, $stream) + /** + * @param resource $stream + */ + private function checkDecode(array $options, array $headers, $stream): array { // Automatically decode responses when instructed. if (!empty($options['decode_content'])) { - $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); + $normalizedKeys = Utils::normalizeHeaderKeys($headers); if (isset($normalizedKeys['content-encoding'])) { $encoding = $headers[$normalizedKeys['content-encoding']]; if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') { - $stream = new Psr7\InflateStream( - Psr7\stream_for($stream) - ); - $headers['x-encoded-content-encoding'] - = $headers[$normalizedKeys['content-encoding']]; + $stream = new Psr7\InflateStream(Psr7\Utils::streamFor($stream)); + $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']]; + // Remove content-encoding header unset($headers[$normalizedKeys['content-encoding']]); + // Fix content-length header if (isset($normalizedKeys['content-length'])) { - $headers['x-encoded-content-length'] - = $headers[$normalizedKeys['content-length']]; - + $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']]; $length = (int) $stream->getSize(); if ($length === 0) { unset($headers[$normalizedKeys['content-length']]); @@ -191,27 +183,21 @@ private function checkDecode(array $options, array $headers, $stream) /** * Drains the source stream into the "sink" client option. * - * @param StreamInterface $source - * @param StreamInterface $sink - * @param string $contentLength Header specifying the amount of - * data to read. + * @param string $contentLength Header specifying the amount of + * data to read. * - * @return StreamInterface * @throws \RuntimeException when the sink option is invalid. */ - private function drain( - StreamInterface $source, - StreamInterface $sink, - $contentLength - ) { + private function drain(StreamInterface $source, StreamInterface $sink, string $contentLength): StreamInterface + { // If a content-length header is provided, then stop reading once // that number of bytes has been read. This can prevent infinitely // reading from a stream when dealing with servers that do not honor // Connection: Close headers. - Psr7\copy_to_stream( + Psr7\Utils::copyToStream( $source, $sink, - (strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 + (\strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 ); $sink->seek(0); @@ -226,12 +212,13 @@ private function drain( * @param callable $callback Callable that returns stream resource * * @return resource + * * @throws \RuntimeException on error */ private function createResource(callable $callback) { - $errors = null; - set_error_handler(function ($_, $msg, $file, $line) use (&$errors) { + $errors = []; + \set_error_handler(static function ($_, $msg, $file, $line) use (&$errors): bool { $errors[] = [ 'message' => $msg, 'file' => $file, @@ -241,26 +228,29 @@ private function createResource(callable $callback) }); $resource = $callback(); - restore_error_handler(); + \restore_error_handler(); if (!$resource) { $message = 'Error creating resource: '; foreach ($errors as $err) { foreach ($err as $key => $value) { - $message .= "[$key] $value" . PHP_EOL; + $message .= "[$key] $value" . \PHP_EOL; } } - throw new \RuntimeException(trim($message)); + throw new \RuntimeException(\trim($message)); } return $resource; } + /** + * @return resource + */ private function createStream(RequestInterface $request, array $options) { static $methods; if (!$methods) { - $methods = array_flip(get_class_methods(__CLASS__)); + $methods = \array_flip(\get_class_methods(__CLASS__)); } // HTTP/1.1 streams using the PHP stream wrapper require a @@ -279,7 +269,7 @@ private function createStream(RequestInterface $request, array $options) $params = []; $context = $this->getDefaultContext($request); - if (isset($options['on_headers']) && !is_callable($options['on_headers'])) { + if (isset($options['on_headers']) && !\is_callable($options['on_headers'])) { throw new \InvalidArgumentException('on_headers must be callable'); } @@ -293,42 +283,39 @@ private function createStream(RequestInterface $request, array $options) } if (isset($options['stream_context'])) { - if (!is_array($options['stream_context'])) { + if (!\is_array($options['stream_context'])) { throw new \InvalidArgumentException('stream_context must be an array'); } - $context = array_replace_recursive( - $context, - $options['stream_context'] - ); + $context = \array_replace_recursive($context, $options['stream_context']); } // Microsoft NTLM authentication only supported with curl handler - if (isset($options['auth']) - && is_array($options['auth']) - && isset($options['auth'][2]) - && 'ntlm' == $options['auth'][2] - ) { + if (isset($options['auth'][2]) && 'ntlm' === $options['auth'][2]) { throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler'); } $uri = $this->resolveHost($request, $options); - $context = $this->createResource( - function () use ($context, $params) { - return stream_context_create($context, $params); + $contextResource = $this->createResource( + static function () use ($context, $params) { + return \stream_context_create($context, $params); } ); return $this->createResource( - function () use ($uri, &$http_response_header, $context, $options) { - $resource = fopen((string) $uri, 'r', null, $context); + function () use ($uri, &$http_response_header, $contextResource, $context, $options, $request) { + $resource = \fopen((string) $uri, 'r', false, $contextResource); $this->lastHeaders = $http_response_header; + if (false === $resource) { + throw new ConnectException(sprintf('Connection refused for URI %s', $uri), $request, null, $context); + } + if (isset($options['read_timeout'])) { $readTimeout = $options['read_timeout']; $sec = (int) $readTimeout; $usec = ($readTimeout - $sec) * 100000; - stream_set_timeout($resource, $sec, $usec); + \stream_set_timeout($resource, $sec, $usec); } return $resource; @@ -336,42 +323,31 @@ function () use ($uri, &$http_response_header, $context, $options) { ); } - private function resolveHost(RequestInterface $request, array $options) + private function resolveHost(RequestInterface $request, array $options): UriInterface { $uri = $request->getUri(); - if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) { + if (isset($options['force_ip_resolve']) && !\filter_var($uri->getHost(), \FILTER_VALIDATE_IP)) { 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 - ); + $records = \dns_get_record($uri->getHost(), \DNS_A); + if (false === $records || !isset($records[0]['ip'])) { + 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 - ); + return $uri->withHost($records[0]['ip']); + } + if ('v6' === $options['force_ip_resolve']) { + $records = \dns_get_record($uri->getHost(), \DNS_AAAA); + if (false === $records || !isset($records[0]['ipv6'])) { + throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request); } - $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']'); + return $uri->withHost('[' . $records[0]['ipv6'] . ']'); } } return $uri; } - private function getDefaultContext(RequestInterface $request) + private function getDefaultContext(RequestInterface $request): array { $headers = ''; foreach ($request->getHeaders() as $name => $value) { @@ -400,55 +376,56 @@ private function getDefaultContext(RequestInterface $request) } } - $context['http']['header'] = rtrim($context['http']['header']); + $context['http']['header'] = \rtrim($context['http']['header']); return $context; } - private function add_proxy(RequestInterface $request, &$options, $value, &$params) + /** + * @param mixed $value as passed via Request transfer options. + */ + private function add_proxy(RequestInterface $request, array &$options, $value, array &$params): void { - if (!is_array($value)) { + if (!\is_array($value)) { $options['http']['proxy'] = $value; } else { $scheme = $request->getUri()->getScheme(); if (isset($value[$scheme])) { - if (!isset($value['no']) - || !\GuzzleHttp\is_host_in_noproxy( - $request->getUri()->getHost(), - $value['no'] - ) - ) { + if (!isset($value['no']) || !Utils::isHostInNoProxy($request->getUri()->getHost(), $value['no'])) { $options['http']['proxy'] = $value[$scheme]; } } } } - private function add_timeout(RequestInterface $request, &$options, $value, &$params) + /** + * @param mixed $value as passed via Request transfer options. + */ + private function add_timeout(RequestInterface $request, array &$options, $value, array &$params): void { if ($value > 0) { $options['http']['timeout'] = $value; } } - private function add_verify(RequestInterface $request, &$options, $value, &$params) + /** + * @param mixed $value as passed via Request transfer options. + */ + private function add_verify(RequestInterface $request, array &$options, $value, array &$params): void { - if ($value === true) { - // PHP 5.6 or greater will find the system cert by default. When - // < 5.6, use the Guzzle bundled cacert. - if (PHP_VERSION_ID < 50600) { - $options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle(); - } - } elseif (is_string($value)) { - $options['ssl']['cafile'] = $value; - if (!file_exists($value)) { - throw new \RuntimeException("SSL CA bundle not found: $value"); - } - } elseif ($value === false) { + if ($value === false) { $options['ssl']['verify_peer'] = false; $options['ssl']['verify_peer_name'] = false; + return; - } else { + } + + if (\is_string($value)) { + $options['ssl']['cafile'] = $value; + if (!\file_exists($value)) { + throw new \RuntimeException("SSL CA bundle not found: $value"); + } + } elseif ($value !== true) { throw new \InvalidArgumentException('Invalid verify request option'); } @@ -457,88 +434,93 @@ private function add_verify(RequestInterface $request, &$options, $value, &$para $options['ssl']['allow_self_signed'] = false; } - private function add_cert(RequestInterface $request, &$options, $value, &$params) + /** + * @param mixed $value as passed via Request transfer options. + */ + private function add_cert(RequestInterface $request, array &$options, $value, array &$params): void { - if (is_array($value)) { + if (\is_array($value)) { $options['ssl']['passphrase'] = $value[1]; $value = $value[0]; } - if (!file_exists($value)) { + if (!\file_exists($value)) { throw new \RuntimeException("SSL certificate not found: {$value}"); } $options['ssl']['local_cert'] = $value; } - private function add_progress(RequestInterface $request, &$options, $value, &$params) + /** + * @param mixed $value as passed via Request transfer options. + */ + private function add_progress(RequestInterface $request, array &$options, $value, array &$params): void { - $this->addNotification( + self::addNotification( $params, - function ($code, $a, $b, $c, $transferred, $total) use ($value) { - if ($code == STREAM_NOTIFY_PROGRESS) { + static function ($code, $a, $b, $c, $transferred, $total) use ($value) { + if ($code == \STREAM_NOTIFY_PROGRESS) { $value($total, $transferred, null, null); } } ); } - private function add_debug(RequestInterface $request, &$options, $value, &$params) + /** + * @param mixed $value as passed via Request transfer options. + */ + private function add_debug(RequestInterface $request, array &$options, $value, array &$params): void { if ($value === false) { return; } static $map = [ - STREAM_NOTIFY_CONNECT => 'CONNECT', - STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', - STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', - STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', - STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', - STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', - STREAM_NOTIFY_PROGRESS => 'PROGRESS', - STREAM_NOTIFY_FAILURE => 'FAILURE', - STREAM_NOTIFY_COMPLETED => 'COMPLETED', - STREAM_NOTIFY_RESOLVE => 'RESOLVE', + \STREAM_NOTIFY_CONNECT => 'CONNECT', + \STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', + \STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', + \STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', + \STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', + \STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', + \STREAM_NOTIFY_PROGRESS => 'PROGRESS', + \STREAM_NOTIFY_FAILURE => 'FAILURE', + \STREAM_NOTIFY_COMPLETED => 'COMPLETED', + \STREAM_NOTIFY_RESOLVE => 'RESOLVE', ]; - static $args = ['severity', 'message', 'message_code', - 'bytes_transferred', 'bytes_max']; + static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max']; - $value = \GuzzleHttp\debug_resource($value); + $value = Utils::debugResource($value); $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment(''); - $this->addNotification( + self::addNotification( $params, - function () use ($ident, $value, $map, $args) { - $passed = func_get_args(); - $code = array_shift($passed); - fprintf($value, '<%s> [%s] ', $ident, $map[$code]); - foreach (array_filter($passed) as $i => $v) { - fwrite($value, $args[$i] . ': "' . $v . '" '); + static function (int $code, ...$passed) use ($ident, $value, $map, $args): void { + \fprintf($value, '<%s> [%s] ', $ident, $map[$code]); + foreach (\array_filter($passed) as $i => $v) { + \fwrite($value, $args[$i] . ': "' . $v . '" '); } - fwrite($value, "\n"); + \fwrite($value, "\n"); } ); } - private function addNotification(array &$params, callable $notify) + private static function addNotification(array &$params, callable $notify): void { // Wrap the existing function if needed. if (!isset($params['notification'])) { $params['notification'] = $notify; } else { - $params['notification'] = $this->callArray([ + $params['notification'] = self::callArray([ $params['notification'], $notify ]); } } - private function callArray(array $functions) + private static function callArray(array $functions): callable { - return function () use ($functions) { - $args = func_get_args(); + return static function (...$args) use ($functions) { foreach ($functions as $fn) { - call_user_func_array($fn, $args); + $fn(...$args); } }; } diff --git a/guzzlehttp/guzzle/src/HandlerStack.php b/guzzlehttp/guzzle/src/HandlerStack.php index 6a49cc069..b67239e7b 100644 --- a/guzzlehttp/guzzle/src/HandlerStack.php +++ b/guzzlehttp/guzzle/src/HandlerStack.php @@ -1,4 +1,5 @@ push(Middleware::httpErrors(), 'http_errors'); $stack->push(Middleware::redirect(), 'allow_redirects'); $stack->push(Middleware::cookies(), 'cookies'); @@ -49,7 +56,7 @@ public static function create(callable $handler = null) } /** - * @param callable $handler Underlying HTTP handler. + * @param null|callable(RequestInterface, array): PromiseInterface $handler Underlying HTTP handler. */ public function __construct(callable $handler = null) { @@ -59,9 +66,6 @@ public function __construct(callable $handler = null) /** * Invokes the handler stack as a composed handler * - * @param RequestInterface $request - * @param array $options - * * @return ResponseInterface|PromiseInterface */ public function __invoke(RequestInterface $request, array $options) @@ -80,12 +84,13 @@ public function __toString() { $depth = 0; $stack = []; - if ($this->handler) { + + if ($this->handler !== null) { $stack[] = "0) Handler: " . $this->debugCallable($this->handler); } $result = ''; - foreach (array_reverse($this->stack) as $tuple) { + foreach (\array_reverse($this->stack) as $tuple) { $depth++; $str = "{$depth}) Name: '{$tuple[1]}', "; $str .= "Function: " . $this->debugCallable($tuple[0]); @@ -93,7 +98,7 @@ public function __toString() $stack[] = $str; } - foreach (array_keys($stack) as $k) { + foreach (\array_keys($stack) as $k) { $result .= "< {$stack[$k]}\n"; } @@ -103,10 +108,10 @@ public function __toString() /** * Set the HTTP handler that actually returns a promise. * - * @param callable $handler Accepts a request and array of options and - * returns a Promise. + * @param callable(RequestInterface, array): PromiseInterface $handler Accepts a request and array of options and + * returns a Promise. */ - public function setHandler(callable $handler) + public function setHandler(callable $handler): void { $this->handler = $handler; $this->cached = null; @@ -114,33 +119,31 @@ public function setHandler(callable $handler) /** * Returns true if the builder has a handler. - * - * @return bool */ - public function hasHandler() + public function hasHandler(): bool { - return (bool) $this->handler; + return $this->handler !== null ; } /** * Unshift a middleware to the bottom of the stack. * - * @param callable $middleware Middleware function - * @param string $name Name to register for this middleware. + * @param callable(callable): callable $middleware Middleware function + * @param string $name Name to register for this middleware. */ - public function unshift(callable $middleware, $name = null) + public function unshift(callable $middleware, ?string $name = null): void { - array_unshift($this->stack, [$middleware, $name]); + \array_unshift($this->stack, [$middleware, $name]); $this->cached = null; } /** * Push a middleware to the top of the stack. * - * @param callable $middleware Middleware function - * @param string $name Name to register for this middleware. + * @param callable(callable): callable $middleware Middleware function + * @param string $name Name to register for this middleware. */ - public function push(callable $middleware, $name = '') + public function push(callable $middleware, string $name = ''): void { $this->stack[] = [$middleware, $name]; $this->cached = null; @@ -149,11 +152,11 @@ public function push(callable $middleware, $name = '') /** * Add a middleware before another middleware by name. * - * @param string $findName Middleware to find - * @param callable $middleware Middleware function - * @param string $withName Name to register for this middleware. + * @param string $findName Middleware to find + * @param callable(callable): callable $middleware Middleware function + * @param string $withName Name to register for this middleware. */ - public function before($findName, callable $middleware, $withName = '') + public function before(string $findName, callable $middleware, string $withName = ''): void { $this->splice($findName, $withName, $middleware, true); } @@ -161,11 +164,11 @@ public function before($findName, callable $middleware, $withName = '') /** * Add a middleware after another middleware by name. * - * @param string $findName Middleware to find - * @param callable $middleware Middleware function - * @param string $withName Name to register for this middleware. + * @param string $findName Middleware to find + * @param callable(callable): callable $middleware Middleware function + * @param string $withName Name to register for this middleware. */ - public function after($findName, callable $middleware, $withName = '') + public function after(string $findName, callable $middleware, string $withName = ''): void { $this->splice($findName, $withName, $middleware, false); } @@ -175,13 +178,13 @@ public function after($findName, callable $middleware, $withName = '') * * @param callable|string $remove Middleware to remove by instance or name. */ - public function remove($remove) + public function remove($remove): void { $this->cached = null; - $idx = is_callable($remove) ? 0 : 1; - $this->stack = array_values(array_filter( + $idx = \is_callable($remove) ? 0 : 1; + $this->stack = \array_values(\array_filter( $this->stack, - function ($tuple) use ($idx, $remove) { + static function ($tuple) use ($idx, $remove) { return $tuple[$idx] !== $remove; } )); @@ -190,16 +193,17 @@ function ($tuple) use ($idx, $remove) { /** * Compose the middleware and handler into a single callable function. * - * @return callable + * @return callable(RequestInterface, array): PromiseInterface */ - public function resolve() + public function resolve(): callable { - if (!$this->cached) { - if (!($prev = $this->handler)) { + if ($this->cached === null) { + if (($prev = $this->handler) === null) { throw new \LogicException('No handler has been specified'); } - foreach (array_reverse($this->stack) as $fn) { + foreach (\array_reverse($this->stack) as $fn) { + /** @var callable(RequestInterface, array): PromiseInterface $prev */ $prev = $fn[0]($prev); } @@ -209,11 +213,7 @@ public function resolve() return $this->cached; } - /** - * @param string $name - * @return int - */ - private function findByName($name) + private function findByName(string $name): int { foreach ($this->stack as $k => $v) { if ($v[1] === $name) { @@ -226,13 +226,8 @@ private function findByName($name) /** * Splices a function into the middleware list at a specific position. - * - * @param string $findName - * @param string $withName - * @param callable $middleware - * @param bool $before */ - private function splice($findName, $withName, callable $middleware, $before) + private function splice(string $findName, string $withName, callable $middleware, bool $before): void { $this->cached = null; $idx = $this->findByName($findName); @@ -240,38 +235,37 @@ private function splice($findName, $withName, callable $middleware, $before) if ($before) { if ($idx === 0) { - array_unshift($this->stack, $tuple); + \array_unshift($this->stack, $tuple); } else { $replacement = [$tuple, $this->stack[$idx]]; - array_splice($this->stack, $idx, 1, $replacement); + \array_splice($this->stack, $idx, 1, $replacement); } - } elseif ($idx === count($this->stack) - 1) { + } elseif ($idx === \count($this->stack) - 1) { $this->stack[] = $tuple; } else { $replacement = [$this->stack[$idx], $tuple]; - array_splice($this->stack, $idx, 1, $replacement); + \array_splice($this->stack, $idx, 1, $replacement); } } /** * Provides a debug string for a given callable. * - * @param array|callable $fn Function to write as a string. - * - * @return string + * @param callable $fn Function to write as a string. */ - private function debugCallable($fn) + private function debugCallable($fn): string { - if (is_string($fn)) { + if (\is_string($fn)) { return "callable({$fn})"; } - if (is_array($fn)) { - return is_string($fn[0]) + if (\is_array($fn)) { + return \is_string($fn[0]) ? "callable({$fn[0]}::{$fn[1]})" - : "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])"; + : "callable(['" . \get_class($fn[0]) . "', '{$fn[1]}'])"; } - return 'callable(' . spl_object_hash($fn) . ')'; + /** @var object $fn */ + return 'callable(' . \spl_object_hash($fn) . ')'; } } diff --git a/guzzlehttp/guzzle/src/MessageFormatter.php b/guzzlehttp/guzzle/src/MessageFormatter.php index dc36bb524..238770f8e 100644 --- a/guzzlehttp/guzzle/src/MessageFormatter.php +++ b/guzzlehttp/guzzle/src/MessageFormatter.php @@ -1,4 +1,5 @@ >>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}"; - const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}'; + public const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}"; + public const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}"; + public const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}'; - /** @var string Template used to format log messages */ + /** + * @var string Template used to format log messages + */ private $template; /** * @param string $template Log message template */ - public function __construct($template = self::CLF) + public function __construct(?string $template = self::CLF) { $this->template = $template ?: self::CLF; } @@ -57,20 +64,16 @@ public function __construct($template = self::CLF) /** * Returns a formatted message string. * - * @param RequestInterface $request Request that was sent - * @param ResponseInterface $response Response that was received - * @param \Exception $error Exception that was received - * - * @return string + * @param RequestInterface $request Request that was sent + * @param ResponseInterface|null $response Response that was received + * @param \Throwable|null $error Exception that was received */ - public function format( - RequestInterface $request, - ResponseInterface $response = null, - \Exception $error = null - ) { + public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string + { $cache = []; - return preg_replace_callback( + /** @var string */ + return \preg_replace_callback( '/{\s*([A-Za-z_\-\.0-9]+)\s*}/', function (array $matches) use ($request, $response, $error, &$cache) { if (isset($cache[$matches[1]])) { @@ -80,20 +83,20 @@ function (array $matches) use ($request, $response, $error, &$cache) { $result = ''; switch ($matches[1]) { case 'request': - $result = Psr7\str($request); + $result = Psr7\Message::toString($request); break; case 'response': - $result = $response ? Psr7\str($response) : ''; + $result = $response ? Psr7\Message::toString($response) : ''; break; case 'req_headers': - $result = trim($request->getMethod() + $result = \trim($request->getMethod() . ' ' . $request->getRequestTarget()) . ' HTTP/' . $request->getProtocolVersion() . "\r\n" . $this->headers($request); break; case 'res_headers': $result = $response ? - sprintf( + \sprintf( 'HTTP/%s %d %s', $response->getProtocolVersion(), $response->getStatusCode(), @@ -102,17 +105,29 @@ function (array $matches) use ($request, $response, $error, &$cache) { : 'NULL'; break; case 'req_body': - $result = $request->getBody(); + $result = $request->getBody()->__toString(); break; case 'res_body': - $result = $response ? $response->getBody() : 'NULL'; + if (!$response instanceof ResponseInterface) { + $result = 'NULL'; + break; + } + + $body = $response->getBody(); + + if (!$body->isSeekable()) { + $result = 'RESPONSE_NOT_LOGGEABLE'; + break; + } + + $result = $response->getBody()->__toString(); break; case 'ts': case 'date_iso_8601': - $result = gmdate('c'); + $result = \gmdate('c'); break; case 'date_common_log': - $result = date('d/M/Y:H:i:s O'); + $result = \date('d/M/Y:H:i:s O'); break; case 'method': $result = $request->getMethod(); @@ -139,7 +154,7 @@ function (array $matches) use ($request, $response, $error, &$cache) { $result = $request->getHeaderLine('Host'); break; case 'hostname': - $result = gethostname(); + $result = \gethostname(); break; case 'code': $result = $response ? $response->getStatusCode() : 'NULL'; @@ -152,11 +167,11 @@ function (array $matches) use ($request, $response, $error, &$cache) { break; default: // handle prefixed dynamic headers - if (strpos($matches[1], 'req_header_') === 0) { - $result = $request->getHeaderLine(substr($matches[1], 11)); - } elseif (strpos($matches[1], 'res_header_') === 0) { + if (\strpos($matches[1], 'req_header_') === 0) { + $result = $request->getHeaderLine(\substr($matches[1], 11)); + } elseif (\strpos($matches[1], 'res_header_') === 0) { $result = $response - ? $response->getHeaderLine(substr($matches[1], 11)) + ? $response->getHeaderLine(\substr($matches[1], 11)) : 'NULL'; } } @@ -170,16 +185,14 @@ function (array $matches) use ($request, $response, $error, &$cache) { /** * Get headers from message as string - * - * @return string */ - private function headers(MessageInterface $message) + private function headers(MessageInterface $message): string { $result = ''; foreach ($message->getHeaders() as $name => $values) { - $result .= $name . ': ' . implode(', ', $values) . "\r\n"; + $result .= $name . ': ' . \implode(', ', $values) . "\r\n"; } - return trim($result); + return \trim($result); } } diff --git a/guzzlehttp/guzzle/src/MessageFormatterInterface.php b/guzzlehttp/guzzle/src/MessageFormatterInterface.php new file mode 100644 index 000000000..a39ac248e --- /dev/null +++ b/guzzlehttp/guzzle/src/MessageFormatterInterface.php @@ -0,0 +1,18 @@ +withCookieHeader($request); return $handler($request, $options) ->then( - function ($response) use ($cookieJar, $request) { + static function (ResponseInterface $response) use ($cookieJar, $request): ResponseInterface { $cookieJar->extractCookies($request, $response); return $response; } @@ -47,22 +49,24 @@ function ($response) use ($cookieJar, $request) { * Middleware that throws exceptions for 4xx or 5xx responses when the * "http_error" request option is set to true. * - * @return callable Returns a function that accepts the next handler. + * @param BodySummarizerInterface|null $bodySummarizer The body summarizer to use in exception messages. + * + * @return callable(callable): callable Returns a function that accepts the next handler. */ - public static function httpErrors() + public static function httpErrors(BodySummarizerInterface $bodySummarizer = null): callable { - return function (callable $handler) { - return function ($request, array $options) use ($handler) { + return static function (callable $handler) use ($bodySummarizer): callable { + return static function ($request, array $options) use ($handler, $bodySummarizer) { if (empty($options['http_errors'])) { return $handler($request, $options); } return $handler($request, $options)->then( - function (ResponseInterface $response) use ($request) { + static function (ResponseInterface $response) use ($request, $bodySummarizer) { $code = $response->getStatusCode(); if ($code < 400) { return $response; } - throw RequestException::create($request, $response); + throw RequestException::create($request, $response, null, [], $bodySummarizer); } ); }; @@ -72,21 +76,22 @@ 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(callable): callable Returns a function that accepts the next handler. * - * @return callable Returns a function that accepts the next handler. * @throws \InvalidArgumentException if container is not an array or ArrayAccess. */ - public static function history(&$container) + public static function history(&$container): callable { - if (!is_array($container) && !$container instanceof \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) { - return function ($request, array $options) use ($handler, &$container) { + return static function (callable $handler) use (&$container): callable { + return static function (RequestInterface $request, array $options) use ($handler, &$container) { return $handler($request, $options)->then( - function ($value) use ($request, &$container, $options) { + static function ($value) use ($request, &$container, $options) { $container[] = [ 'request' => $request, 'response' => $value, @@ -95,14 +100,14 @@ function ($value) use ($request, &$container, $options) { ]; return $value; }, - function ($reason) use ($request, &$container, $options) { + static function ($reason) use ($request, &$container, $options) { $container[] = [ 'request' => $request, 'response' => null, 'error' => $reason, 'options' => $options ]; - return \GuzzleHttp\Promise\rejection_for($reason); + return P\Create::rejectionFor($reason); } ); }; @@ -122,10 +127,10 @@ function ($reason) use ($request, &$container, $options) { * * @return callable Returns a function that accepts the next handler. */ - public static function tap(callable $before = null, callable $after = null) + public static function tap(callable $before = null, callable $after = null): callable { - return function (callable $handler) use ($before, $after) { - return function ($request, array $options) use ($handler, $before, $after) { + return static function (callable $handler) use ($before, $after): callable { + return static function (RequestInterface $request, array $options) use ($handler, $before, $after) { if ($before) { $before($request, $options); } @@ -143,9 +148,9 @@ public static function tap(callable $before = null, callable $after = null) * * @return callable Returns a function that accepts the next handler. */ - public static function redirect() + public static function redirect(): callable { - return function (callable $handler) { + return static function (callable $handler): RedirectMiddleware { return new RedirectMiddleware($handler); }; } @@ -165,9 +170,9 @@ public static function redirect() * * @return callable Returns a function that accepts the next handler. */ - public static function retry(callable $decider, callable $delay = null) + public static function retry(callable $decider, callable $delay = null): callable { - return function (callable $handler) use ($decider, $delay) { + return static function (callable $handler) use ($decider, $delay): RetryMiddleware { return new RetryMiddleware($decider, $handler, $delay); }; } @@ -176,29 +181,34 @@ public static function retry(callable $decider, callable $delay = null) * Middleware that logs requests, responses, and errors using a message * formatter. * - * @param LoggerInterface $logger Logs messages. - * @param MessageFormatter $formatter Formatter used to create message strings. - * @param string $logLevel Level at which to log requests. + * @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests. + * + * @param LoggerInterface $logger Logs messages. + * @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings. + * @param string $logLevel Level at which to log requests. * * @return callable Returns a function that accepts the next handler. */ - public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = 'info' /* \Psr\Log\LogLevel::INFO */) + public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable { - return function (callable $handler) use ($logger, $formatter, $logLevel) { - return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) { + // To be compatible with Guzzle 7.1.x we need to allow users to pass a MessageFormatter + if (!$formatter instanceof MessageFormatter && !$formatter instanceof MessageFormatterInterface) { + throw new \LogicException(sprintf('Argument 2 to %s::log() must be of type %s', self::class, MessageFormatterInterface::class)); + } + + return static function (callable $handler) use ($logger, $formatter, $logLevel): callable { + return static function (RequestInterface $request, array $options = []) use ($handler, $logger, $formatter, $logLevel) { return $handler($request, $options)->then( - function ($response) use ($logger, $request, $formatter, $logLevel) { + static function ($response) use ($logger, $request, $formatter, $logLevel): ResponseInterface { $message = $formatter->format($request, $response); $logger->log($logLevel, $message); return $response; }, - function ($reason) use ($logger, $request, $formatter) { - $response = $reason instanceof RequestException - ? $reason->getResponse() - : null; - $message = $formatter->format($request, $response, $reason); - $logger->notice($message); - return \GuzzleHttp\Promise\rejection_for($reason); + static function ($reason) use ($logger, $request, $formatter): PromiseInterface { + $response = $reason instanceof RequestException ? $reason->getResponse() : null; + $message = $formatter->format($request, $response, P\Create::exceptionFor($reason)); + $logger->error($message); + return P\Create::rejectionFor($reason); } ); }; @@ -208,12 +218,10 @@ function ($reason) use ($logger, $request, $formatter) { /** * This middleware adds a default content-type if possible, a default * content-length or transfer-encoding header, and the expect header. - * - * @return callable */ - public static function prepareBody() + public static function prepareBody(): callable { - return function (callable $handler) { + return static function (callable $handler): PrepareBodyMiddleware { return new PrepareBodyMiddleware($handler); }; } @@ -224,12 +232,11 @@ public static function prepareBody() * * @param callable $fn Function that accepts a RequestInterface and returns * a RequestInterface. - * @return callable */ - public static function mapRequest(callable $fn) + public static function mapRequest(callable $fn): callable { - return function (callable $handler) use ($fn) { - return function ($request, array $options) use ($handler, $fn) { + return static function (callable $handler) use ($fn): callable { + return static function (RequestInterface $request, array $options) use ($handler, $fn) { return $handler($fn($request), $options); }; }; @@ -241,12 +248,11 @@ public static function mapRequest(callable $fn) * * @param callable $fn Function that accepts a ResponseInterface and * returns a ResponseInterface. - * @return callable */ - public static function mapResponse(callable $fn) + public static function mapResponse(callable $fn): callable { - return function (callable $handler) use ($fn) { - return function ($request, array $options) use ($handler, $fn) { + return static function (callable $handler) use ($fn): callable { + return static function (RequestInterface $request, array $options) use ($handler, $fn) { return $handler($request, $options)->then($fn); }; }; diff --git a/guzzlehttp/guzzle/src/Pool.php b/guzzlehttp/guzzle/src/Pool.php index 5838db4f4..6277c61fb 100644 --- a/guzzlehttp/guzzle/src/Pool.php +++ b/guzzlehttp/guzzle/src/Pool.php @@ -1,6 +1,8 @@ $rfn) { if ($rfn instanceof RequestInterface) { yield $key => $client->sendAsync($rfn, $opts); - } elseif (is_callable($rfn)) { + } elseif (\is_callable($rfn)) { yield $key => $rfn($opts); } else { - throw new \InvalidArgumentException('Each value yielded by ' - . 'the iterator must be a Psr7\Http\Message\RequestInterface ' - . 'or a callable that returns a promise that fulfills ' - . 'with a Psr7\Message\Http\ResponseInterface object.'); + throw new \InvalidArgumentException('Each value yielded by the iterator must be a Psr7\Http\Message\RequestInterface or a callable that returns a promise that fulfills with a Psr7\Message\Http\ResponseInterface object.'); } } }; @@ -72,10 +69,8 @@ public function __construct( /** * Get promise - * - * @return PromiseInterface */ - public function promise() + public function promise(): PromiseInterface { return $this->each->promise(); } @@ -91,41 +86,37 @@ public function promise() * @param ClientInterface $client Client used to send the requests * @param array|\Iterator $requests Requests to send concurrently. * @param array $options Passes through the options available in - * {@see GuzzleHttp\Pool::__construct} + * {@see \GuzzleHttp\Pool::__construct} * * @return array Returns an array containing the response or an exception * in the same order that the requests were sent. + * * @throws \InvalidArgumentException if the event format is incorrect. */ - public static function batch( - ClientInterface $client, - $requests, - array $options = [] - ) { + public static function batch(ClientInterface $client, $requests, array $options = []): array + { $res = []; self::cmpCallback($options, 'fulfilled', $res); self::cmpCallback($options, 'rejected', $res); $pool = new static($client, $requests, $options); $pool->promise()->wait(); - ksort($res); + \ksort($res); return $res; } /** * Execute callback(s) - * - * @return void */ - private static function cmpCallback(array &$options, $name, array &$results) + private static function cmpCallback(array &$options, string $name, array &$results): void { if (!isset($options[$name])) { - $options[$name] = function ($v, $k) use (&$results) { + $options[$name] = static function ($v, $k) use (&$results) { $results[$k] = $v; }; } else { $currentFn = $options[$name]; - $options[$name] = function ($v, $k) use (&$results, $currentFn) { + $options[$name] = static function ($v, $k) use (&$results, $currentFn) { $currentFn($v, $k); $results[$k] = $v; }; diff --git a/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php index 568a1e906..7ca628338 100644 --- a/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +++ b/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php @@ -1,34 +1,32 @@ nextHandler = $nextHandler; } - /** - * @param RequestInterface $request - * @param array $options - * - * @return PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { $fn = $this->nextHandler; @@ -42,7 +40,7 @@ public function __invoke(RequestInterface $request, array $options) // Add a default content-type if possible. if (!$request->hasHeader('Content-Type')) { if ($uri = $request->getBody()->getMetadata('uri')) { - if ($type = Psr7\mimetype_from_filename($uri)) { + if (is_string($uri) && $type = Psr7\MimeType::fromFilename($uri)) { $modify['set_headers']['Content-Type'] = $type; } } @@ -63,25 +61,20 @@ public function __invoke(RequestInterface $request, array $options) // Add the expect header if needed. $this->addExpectHeader($request, $options, $modify); - return $fn(Psr7\modify_request($request, $modify), $options); + return $fn(Psr7\Utils::modifyRequest($request, $modify), $options); } /** * Add expect header - * - * @return void */ - private function addExpectHeader( - RequestInterface $request, - array $options, - array &$modify - ) { + private function addExpectHeader(RequestInterface $request, array $options, array &$modify): void + { // Determine if the Expect header should be used if ($request->hasHeader('Expect')) { return; } - $expect = isset($options['expect']) ? $options['expect'] : null; + $expect = $options['expect'] ?? null; // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 if ($expect === false || $request->getProtocolVersion() < 1.1) { diff --git a/guzzlehttp/guzzle/src/RedirectMiddleware.php b/guzzlehttp/guzzle/src/RedirectMiddleware.php index e4644b7ac..1dd38614f 100644 --- a/guzzlehttp/guzzle/src/RedirectMiddleware.php +++ b/guzzlehttp/guzzle/src/RedirectMiddleware.php @@ -1,10 +1,10 @@ 5, 'protocols' => ['http', 'https'], @@ -29,24 +34,20 @@ class RedirectMiddleware 'track_redirects' => false, ]; - /** @var callable */ + /** + * @var callable(RequestInterface, array): PromiseInterface + */ private $nextHandler; /** - * @param callable $nextHandler Next handler to invoke. + * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke. */ public function __construct(callable $nextHandler) { $this->nextHandler = $nextHandler; } - /** - * @param RequestInterface $request - * @param array $options - * - * @return PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { $fn = $this->nextHandler; @@ -56,7 +57,7 @@ public function __invoke(RequestInterface $request, array $options) if ($options['allow_redirects'] === true) { $options['allow_redirects'] = self::$defaultSettings; - } elseif (!is_array($options['allow_redirects'])) { + } elseif (!\is_array($options['allow_redirects'])) { throw new \InvalidArgumentException('allow_redirects must be true, false, or array'); } else { // Merge the default settings with the provided settings @@ -74,36 +75,27 @@ public function __invoke(RequestInterface $request, array $options) } /** - * @param RequestInterface $request - * @param array $options - * @param ResponseInterface $response - * * @return ResponseInterface|PromiseInterface */ - public function checkRedirect( - RequestInterface $request, - array $options, - ResponseInterface $response - ) { - if (substr($response->getStatusCode(), 0, 1) != '3' + public function checkRedirect(RequestInterface $request, array $options, ResponseInterface $response) + { + if (\strpos((string) $response->getStatusCode(), '3') !== 0 || !$response->hasHeader('Location') ) { return $response; } - $this->guardMax($request, $options); + $this->guardMax($request, $response, $options); $nextRequest = $this->modifyRequest($request, $options, $response); if (isset($options['allow_redirects']['on_redirect'])) { - call_user_func( - $options['allow_redirects']['on_redirect'], + ($options['allow_redirects']['on_redirect'])( $request, $response, $nextRequest->getUri() ); } - /** @var PromiseInterface|ResponseInterface $promise */ $promise = $this($nextRequest, $options); // Add headers to be able to track history of redirects. @@ -120,20 +112,19 @@ public function checkRedirect( /** * Enable tracking on promise. - * - * @return PromiseInterface */ - private function withTracking(PromiseInterface $promise, $uri, $statusCode) + private function withTracking(PromiseInterface $promise, string $uri, int $statusCode): PromiseInterface { return $promise->then( - function (ResponseInterface $response) use ($uri, $statusCode) { + static function (ResponseInterface $response) use ($uri, $statusCode) { // Note that we are pushing to the front of the list as this // would be an earlier response than what is currently present // in the history header. $historyHeader = $response->getHeader(self::HISTORY_HEADER); $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER); - array_unshift($historyHeader, $uri); - array_unshift($statusHeader, $statusCode); + \array_unshift($historyHeader, $uri); + \array_unshift($statusHeader, (string) $statusCode); + return $response->withHeader(self::HISTORY_HEADER, $historyHeader) ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader); } @@ -143,38 +134,22 @@ function (ResponseInterface $response) use ($uri, $statusCode) { /** * Check for too many redirects * - * @return void - * * @throws TooManyRedirectsException Too many redirects. */ - private function guardMax(RequestInterface $request, array &$options) + private function guardMax(RequestInterface $request, ResponseInterface $response, array &$options): void { - $current = isset($options['__redirect_count']) - ? $options['__redirect_count'] - : 0; + $current = $options['__redirect_count'] + ?? 0; $options['__redirect_count'] = $current + 1; $max = $options['allow_redirects']['max']; if ($options['__redirect_count'] > $max) { - throw new TooManyRedirectsException( - "Will not follow more than {$max} redirects", - $request - ); + throw new TooManyRedirectsException("Will not follow more than {$max} redirects", $request, $response); } } - /** - * @param RequestInterface $request - * @param array $options - * @param ResponseInterface $response - * - * @return RequestInterface - */ - public function modifyRequest( - RequestInterface $request, - array $options, - ResponseInterface $response - ) { + public function modifyRequest(RequestInterface $request, array $options, ResponseInterface $response): RequestInterface + { // Request modifications to apply. $modify = []; $protocols = $options['allow_redirects']['protocols']; @@ -186,18 +161,21 @@ public function modifyRequest( if ($statusCode == 303 || ($statusCode <= 302 && !$options['allow_redirects']['strict']) ) { - $modify['method'] = 'GET'; + $safeMethods = ['GET', 'HEAD', 'OPTIONS']; + $requestMethod = $request->getMethod(); + + $modify['method'] = in_array($requestMethod, $safeMethods) ? $requestMethod : 'GET'; $modify['body'] = ''; } $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']; + $idnOptions = ($options['idn_conversion'] === true) ? \IDNA_DEFAULT : $options['idn_conversion']; $uri = Utils::idnUriConvert($uri, $idnOptions); } $modify['uri'] = $uri; - Psr7\rewind_body($request); + Psr7\Message::rewindBody($request); // Add the Referer header if it is told to do so and only // add the header if we are not redirecting from https to http. @@ -215,39 +193,22 @@ public function modifyRequest( $modify['remove_headers'][] = 'Authorization'; } - return Psr7\modify_request($request, $modify); + return Psr7\Utils::modifyRequest($request, $modify); } /** * Set the appropriate URL on the request based on the location header - * - * @param RequestInterface $request - * @param ResponseInterface $response - * @param array $protocols - * - * @return UriInterface */ - private function redirectUri( - RequestInterface $request, - ResponseInterface $response, - array $protocols - ) { + private function redirectUri(RequestInterface $request, ResponseInterface $response, array $protocols): UriInterface + { $location = Psr7\UriResolver::resolve( $request->getUri(), new Psr7\Uri($response->getHeaderLine('Location')) ); // Ensure that the redirect URI is allowed based on the protocols. - if (!in_array($location->getScheme(), $protocols)) { - throw new BadResponseException( - sprintf( - 'Redirect URI, %s, does not use one of the allowed redirect protocols: %s', - $location, - implode(', ', $protocols) - ), - $request, - $response - ); + if (!\in_array($location->getScheme(), $protocols)) { + throw new BadResponseException(\sprintf('Redirect URI, %s, does not use one of the allowed redirect protocols: %s', $location, \implode(', ', $protocols)), $request, $response); } return $location; diff --git a/guzzlehttp/guzzle/src/RequestOptions.php b/guzzlehttp/guzzle/src/RequestOptions.php index 355f658f0..20b31bc20 100644 --- a/guzzlehttp/guzzle/src/RequestOptions.php +++ b/guzzlehttp/guzzle/src/RequestOptions.php @@ -1,4 +1,5 @@ decider = $decider; $this->nextHandler = $nextHandler; $this->delay = $delay ?: __CLASS__ . '::exponentialDelay'; @@ -45,22 +50,14 @@ public function __construct( /** * Default exponential backoff delay function. * - * @param int $retries - * * @return int milliseconds. */ - public static function exponentialDelay($retries) + public static function exponentialDelay(int $retries): int { - return (int) pow(2, $retries - 1) * 1000; + return (int) \pow(2, $retries - 1) * 1000; } - /** - * @param RequestInterface $request - * @param array $options - * - * @return PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (!isset($options['retries'])) { $options['retries'] = 0; @@ -76,52 +73,43 @@ public function __invoke(RequestInterface $request, array $options) /** * Execute fulfilled closure - * - * @return mixed */ - private function onFulfilled(RequestInterface $req, array $options) + private function onFulfilled(RequestInterface $request, array $options): callable { - return function ($value) use ($req, $options) { - if (!call_user_func( - $this->decider, + return function ($value) use ($request, $options) { + if (!($this->decider)( $options['retries'], - $req, + $request, $value, null )) { return $value; } - return $this->doRetry($req, $options, $value); + return $this->doRetry($request, $options, $value); }; } /** * Execute rejected closure - * - * @return callable */ - private function onRejected(RequestInterface $req, array $options) + private function onRejected(RequestInterface $req, array $options): callable { return function ($reason) use ($req, $options) { - if (!call_user_func( - $this->decider, + if (!($this->decider)( $options['retries'], $req, null, $reason )) { - return \GuzzleHttp\Promise\rejection_for($reason); + return P\Create::rejectionFor($reason); } return $this->doRetry($req, $options); }; } - /** - * @return self - */ - private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) + private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null): PromiseInterface { - $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); + $options['delay'] = ($this->delay)(++$options['retries'], $response); return $this($request, $options); } diff --git a/guzzlehttp/guzzle/src/TransferStats.php b/guzzlehttp/guzzle/src/TransferStats.php index 87fb3c001..7b46c2b56 100644 --- a/guzzlehttp/guzzle/src/TransferStats.php +++ b/guzzlehttp/guzzle/src/TransferStats.php @@ -1,4 +1,5 @@ request = $request; $this->response = $response; @@ -38,30 +58,23 @@ public function __construct( $this->handlerStats = $handlerStats; } - /** - * @return RequestInterface - */ - public function getRequest() + public function getRequest(): RequestInterface { return $this->request; } /** * Returns the response that was received (if any). - * - * @return ResponseInterface|null */ - public function getResponse() + public function getResponse(): ?ResponseInterface { return $this->response; } /** * Returns true if a response was received. - * - * @return bool */ - public function hasResponse() + public function hasResponse(): bool { return $this->response !== null; } @@ -82,10 +95,8 @@ public function getHandlerErrorData() /** * Get the effective URI the request was sent to. - * - * @return UriInterface */ - public function getEffectiveUri() + public function getEffectiveUri(): UriInterface { return $this->request->getUri(); } @@ -95,17 +106,15 @@ public function getEffectiveUri() * * @return float|null Time in seconds. */ - public function getTransferTime() + public function getTransferTime(): ?float { return $this->transferTime; } /** * Gets an array of all of the handler specific transfer data. - * - * @return array */ - public function getHandlerStats() + public function getHandlerStats(): array { return $this->handlerStats; } @@ -117,10 +126,8 @@ public function getHandlerStats() * * @return mixed|null */ - public function getHandlerStat($stat) + public function getHandlerStat(string $stat) { - return isset($this->handlerStats[$stat]) - ? $this->handlerStats[$stat] - : null; + return isset($this->handlerStats[$stat]) ? $this->handlerStats[$stat] : null; } } diff --git a/guzzlehttp/guzzle/src/UriTemplate.php b/guzzlehttp/guzzle/src/UriTemplate.php deleted file mode 100644 index 96dcfd09c..000000000 --- a/guzzlehttp/guzzle/src/UriTemplate.php +++ /dev/null @@ -1,237 +0,0 @@ - ['prefix' => '', 'joiner' => ',', 'query' => false], - '+' => ['prefix' => '', 'joiner' => ',', 'query' => false], - '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false], - '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false], - '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false], - ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true], - '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true], - '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true] - ]; - - /** @var array Delimiters */ - private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$', - '&', '\'', '(', ')', '*', '+', ',', ';', '=']; - - /** @var array Percent encoded delimiters */ - private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D', - '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', - '%3B', '%3D']; - - public function expand($template, array $variables) - { - if (false === strpos($template, '{')) { - return $template; - } - - $this->template = $template; - $this->variables = $variables; - - return preg_replace_callback( - '/\{([^\}]+)\}/', - [$this, 'expandMatch'], - $this->template - ); - } - - /** - * Parse an expression into parts - * - * @param string $expression Expression to parse - * - * @return array Returns an associative array of parts - */ - private function parseExpression($expression) - { - $result = []; - - if (isset(self::$operatorHash[$expression[0]])) { - $result['operator'] = $expression[0]; - $expression = substr($expression, 1); - } else { - $result['operator'] = ''; - } - - foreach (explode(',', $expression) as $value) { - $value = trim($value); - $varspec = []; - if ($colonPos = strpos($value, ':')) { - $varspec['value'] = substr($value, 0, $colonPos); - $varspec['modifier'] = ':'; - $varspec['position'] = (int) substr($value, $colonPos + 1); - } elseif (substr($value, -1) === '*') { - $varspec['modifier'] = '*'; - $varspec['value'] = substr($value, 0, -1); - } else { - $varspec['value'] = (string) $value; - $varspec['modifier'] = ''; - } - $result['values'][] = $varspec; - } - - return $result; - } - - /** - * Process an expansion - * - * @param array $matches Matches met in the preg_replace_callback - * - * @return string Returns the replacement string - */ - private function expandMatch(array $matches) - { - static $rfc1738to3986 = ['+' => '%20', '%7e' => '~']; - - $replacements = []; - $parsed = self::parseExpression($matches[1]); - $prefix = self::$operatorHash[$parsed['operator']]['prefix']; - $joiner = self::$operatorHash[$parsed['operator']]['joiner']; - $useQuery = self::$operatorHash[$parsed['operator']]['query']; - - foreach ($parsed['values'] as $value) { - if (!isset($this->variables[$value['value']])) { - continue; - } - - $variable = $this->variables[$value['value']]; - $actuallyUseQuery = $useQuery; - $expanded = ''; - - if (is_array($variable)) { - $isAssoc = $this->isAssoc($variable); - $kvp = []; - foreach ($variable as $key => $var) { - if ($isAssoc) { - $key = rawurlencode($key); - $isNestedArray = is_array($var); - } else { - $isNestedArray = false; - } - - if (!$isNestedArray) { - $var = rawurlencode($var); - if ($parsed['operator'] === '+' || - $parsed['operator'] === '#' - ) { - $var = $this->decodeReserved($var); - } - } - - if ($value['modifier'] === '*') { - if ($isAssoc) { - if ($isNestedArray) { - // Nested arrays must allow for deeply nested - // structures. - $var = strtr( - http_build_query([$key => $var]), - $rfc1738to3986 - ); - } else { - $var = $key . '=' . $var; - } - } elseif ($key > 0 && $actuallyUseQuery) { - $var = $value['value'] . '=' . $var; - } - } - - $kvp[$key] = $var; - } - - if (empty($variable)) { - $actuallyUseQuery = false; - } elseif ($value['modifier'] === '*') { - $expanded = implode($joiner, $kvp); - if ($isAssoc) { - // Don't prepend the value name when using the explode - // modifier with an associative array. - $actuallyUseQuery = false; - } - } else { - if ($isAssoc) { - // When an associative array is encountered and the - // explode modifier is not set, then the result must be - // a comma separated list of keys followed by their - // respective values. - foreach ($kvp as $k => &$v) { - $v = $k . ',' . $v; - } - } - $expanded = implode(',', $kvp); - } - } else { - if ($value['modifier'] === ':') { - $variable = substr($variable, 0, $value['position']); - } - $expanded = rawurlencode($variable); - if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { - $expanded = $this->decodeReserved($expanded); - } - } - - if ($actuallyUseQuery) { - if (!$expanded && $joiner !== '&') { - $expanded = $value['value']; - } else { - $expanded = $value['value'] . '=' . $expanded; - } - } - - $replacements[] = $expanded; - } - - $ret = implode($joiner, $replacements); - if ($ret && $prefix) { - return $prefix . $ret; - } - - return $ret; - } - - /** - * Determines if an array is associative. - * - * This makes the assumption that input arrays are sequences or hashes. - * This assumption is a tradeoff for accuracy in favor of speed, but it - * should work in almost every case where input is supplied for a URI - * template. - * - * @param array $array Array to check - * - * @return bool - */ - private function isAssoc(array $array) - { - return $array && array_keys($array)[0] !== 0; - } - - /** - * Removes percent encoding on reserved characters (used with + and # - * modifiers). - * - * @param string $string String to fix - * - * @return string - */ - private function decodeReserved($string) - { - return str_replace(self::$delimsPct, self::$delims, $string); - } -} diff --git a/guzzlehttp/guzzle/src/Utils.php b/guzzlehttp/guzzle/src/Utils.php index c698acbf0..f4848b74b 100644 --- a/guzzlehttp/guzzle/src/Utils.php +++ b/guzzlehttp/guzzle/src/Utils.php @@ -1,41 +1,336 @@ getHost()) { $asciiHost = self::idnToAsci($uri->getHost(), $options, $info); if ($asciiHost === false) { - $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; + $errorBitSet = $info['errors'] ?? 0; - $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { + $errorConstants = array_filter(array_keys(get_defined_constants()), static function ($name) { return substr($name, 0, 11) === 'IDNA_ERROR_'; }); @@ -52,11 +347,10 @@ public static function idnUriConvert(UriInterface $uri, $options = 0) } throw new InvalidArgumentException($errorMessage); - } else { - if ($uri->getHost() !== $asciiHost) { - // Replace URI only if the ASCII version is different - $uri = $uri->withHost($asciiHost); - } + } + if ($uri->getHost() !== $asciiHost) { + // Replace URI only if the ASCII version is different + $uri = $uri->withHost($asciiHost); } } @@ -64,29 +358,30 @@ public static function idnUriConvert(UriInterface $uri, $options = 0) } /** - * @param string $domain - * @param int $options - * @param array $info - * - * @return string|false + * @internal */ - private static function idnToAsci($domain, $options, &$info = []) + public static function getenv(string $name): ?string { - if (\preg_match('%^[ -~]+$%', $domain) === 1) { - return $domain; + if (isset($_SERVER[$name])) { + return (string) $_SERVER[$name]; } - if (\extension_loaded('intl') && defined('INTL_IDNA_VARIANT_UTS46')) { - return \idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $info); + if (\PHP_SAPI === 'cli' && ($value = \getenv($name)) !== false && $value !== null) { + return (string) $value; } - /* - * The Idn class is marked as @internal. Verify that class and method exists. - */ - if (method_exists(Idn::class, 'idn_to_ascii')) { - return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info); + return null; + } + + /** + * @return string|false + */ + private static function idnToAsci(string $domain, int $options, ?array &$info = []) + { + if (\function_exists('idn_to_ascii') && \defined('INTL_IDNA_VARIANT_UTS46')) { + return \idn_to_ascii($domain, $options, \INTL_IDNA_VARIANT_UTS46, $info); } - throw new \RuntimeException('ext-intl or symfony/polyfill-intl-idn not loaded or too old'); + throw new \Error('ext-idn or symfony/polyfill-intl-idn not loaded or too old'); } } diff --git a/guzzlehttp/guzzle/src/functions.php b/guzzlehttp/guzzle/src/functions.php index c2afd8c7b..a70d2cbf3 100644 --- a/guzzlehttp/guzzle/src/functions.php +++ b/guzzlehttp/guzzle/src/functions.php @@ -1,77 +1,34 @@ expand($template, $variables); -} +namespace GuzzleHttp; /** * Debug function used to describe the provided value type and class. * - * @param mixed $input + * @param mixed $input Any type of variable to describe the type of. This + * parameter misses a typehint because of that. * * @return string Returns a string containing the type of the variable and * if a class is provided, the class name. + * + * @deprecated describe_type will be removed in guzzlehttp/guzzle:8.0. Use Utils::describeType instead. */ -function describe_type($input) +function describe_type($input): string { - switch (gettype($input)) { - case 'object': - return 'object(' . get_class($input) . ')'; - case 'array': - return 'array(' . count($input) . ')'; - default: - ob_start(); - var_dump($input); - // normalize float vs double - return str_replace('double(', 'float(', rtrim(ob_get_clean())); - } + return Utils::describeType($input); } /** * Parses an array of header lines into an associative array of headers. * * @param iterable $lines Header lines array of strings in the following - * format: "Name: Value" - * @return array + * format: "Name: Value" + * + * @deprecated headers_from_lines will be removed in guzzlehttp/guzzle:8.0. Use Utils::headersFromLines instead. */ -function headers_from_lines($lines) +function headers_from_lines(iterable $lines): array { - $headers = []; - - foreach ($lines as $line) { - $parts = explode(':', $line, 2); - $headers[trim($parts[0])][] = isset($parts[1]) - ? trim($parts[1]) - : null; - } - - return $headers; + return Utils::headersFromLines($lines); } /** @@ -80,16 +37,12 @@ function headers_from_lines($lines) * @param mixed $value Optional value * * @return resource + * + * @deprecated debug_resource will be removed in guzzlehttp/guzzle:8.0. Use Utils::debugResource instead. */ function debug_resource($value = null) { - if (is_resource($value)) { - return $value; - } elseif (defined('STDOUT')) { - return STDOUT; - } - - return fopen('php://output', 'w'); + return Utils::debugResource($value); } /** @@ -97,50 +50,25 @@ function debug_resource($value = null) * * The returned handler is not wrapped by any default middlewares. * - * @return callable Returns the best handler for the given system. * @throws \RuntimeException if no viable Handler is available. + * + * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system. + * + * @deprecated choose_handler will be removed in guzzlehttp/guzzle:8.0. Use Utils::chooseHandler instead. */ -function choose_handler() +function choose_handler(): callable { - $handler = null; - if (function_exists('curl_multi_exec') && function_exists('curl_exec')) { - $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler()); - } elseif (function_exists('curl_exec')) { - $handler = new CurlHandler(); - } elseif (function_exists('curl_multi_exec')) { - $handler = new CurlMultiHandler(); - } - - if (ini_get('allow_url_fopen')) { - $handler = $handler - ? Proxy::wrapStreaming($handler, new StreamHandler()) - : new StreamHandler(); - } elseif (!$handler) { - throw new \RuntimeException('GuzzleHttp requires cURL, the ' - . 'allow_url_fopen ini setting, or a custom HTTP handler.'); - } - - return $handler; + return Utils::chooseHandler(); } /** - * Get the default User-Agent string to use with Guzzle + * Get the default User-Agent string to use with Guzzle. * - * @return string + * @deprecated default_user_agent will be removed in guzzlehttp/guzzle:8.0. Use Utils::defaultUserAgent instead. */ -function default_user_agent() +function default_user_agent(): string { - static $defaultAgent = ''; - - if (!$defaultAgent) { - $defaultAgent = 'GuzzleHttp/' . Client::VERSION; - if (extension_loaded('curl') && function_exists('curl_version')) { - $defaultAgent .= ' curl/' . \curl_version()['version']; - } - $defaultAgent .= ' PHP/' . PHP_VERSION; - } - - return $defaultAgent; + return Utils::defaultUserAgent(); } /** @@ -154,82 +82,24 @@ function default_user_agent() * * Note: the result of this function is cached for subsequent calls. * - * @return string * @throws \RuntimeException if no bundle can be found. + * + * @deprecated default_ca_bundle will be removed in guzzlehttp/guzzle:8.0. This function is not needed in PHP 5.6+. */ -function default_ca_bundle() +function default_ca_bundle(): string { - static $cached = null; - static $cafiles = [ - // Red Hat, CentOS, Fedora (provided by the ca-certificates package) - '/etc/pki/tls/certs/ca-bundle.crt', - // Ubuntu, Debian (provided by the ca-certificates package) - '/etc/ssl/certs/ca-certificates.crt', - // FreeBSD (provided by the ca_root_nss package) - '/usr/local/share/certs/ca-root-nss.crt', - // SLES 12 (provided by the ca-certificates package) - '/var/lib/ca-certificates/ca-bundle.pem', - // OS X provided by homebrew (using the default path) - '/usr/local/etc/openssl/cert.pem', - // Google app engine - '/etc/ca-certificates.crt', - // Windows? - 'C:\\windows\\system32\\curl-ca-bundle.crt', - 'C:\\windows\\curl-ca-bundle.crt', - ]; - - if ($cached) { - return $cached; - } - - if ($ca = ini_get('openssl.cafile')) { - return $cached = $ca; - } - - if ($ca = ini_get('curl.cainfo')) { - return $cached = $ca; - } - - foreach ($cafiles as $filename) { - if (file_exists($filename)) { - return $cached = $filename; - } - } - - 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 -supply the path on disk to a certificate bundle to the 'verify' request -option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not -need a specific certificate bundle, then Mozilla provides a commonly used CA -bundle which can be downloaded here (provided by the maintainer of cURL): -https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once -you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP -ini setting to point to the path to the file, allowing you to omit the 'verify' -request option. See http://curl.haxx.se/docs/sslcerts.html for more -information. -EOT - ); + return Utils::defaultCaBundle(); } /** * Creates an associative array of lowercase header names to the actual * header casing. * - * @param array $headers - * - * @return array + * @deprecated normalize_header_keys will be removed in guzzlehttp/guzzle:8.0. Use Utils::normalizeHeaderKeys instead. */ -function normalize_header_keys(array $headers) +function normalize_header_keys(array $headers): array { - $result = []; - foreach (array_keys($headers) as $key) { - $result[strtolower($key)] = $key; - } - - return $result; + return Utils::normalizeHeaderKeys($headers); } /** @@ -246,89 +116,52 @@ function normalize_header_keys(array $headers) * 3. The area starts with "." and the area is the last part of the host. e.g. * '.mit.edu' will match any host that ends with '.mit.edu'. * - * @param string $host Host to check against the patterns. - * @param array $noProxyArray An array of host patterns. + * @param string $host Host to check against the patterns. + * @param string[] $noProxyArray An array of host patterns. + * + * @throws Exception\InvalidArgumentException * - * @return bool + * @deprecated is_host_in_noproxy will be removed in guzzlehttp/guzzle:8.0. Use Utils::isHostInNoProxy instead. */ -function is_host_in_noproxy($host, array $noProxyArray) +function is_host_in_noproxy(string $host, array $noProxyArray): bool { - if (strlen($host) === 0) { - throw new \InvalidArgumentException('Empty host provided'); - } - - // Strip port if present. - if (strpos($host, ':')) { - $host = explode($host, ':', 2)[0]; - } - - foreach ($noProxyArray as $area) { - // Always match on wildcards. - if ($area === '*') { - return true; - } elseif (empty($area)) { - // Don't match on empty values. - continue; - } elseif ($area === $host) { - // Exact matches. - return true; - } else { - // Special match if the area when prefixed with ".". Remove any - // existing leading "." and add a new leading ".". - $area = '.' . ltrim($area, '.'); - if (substr($host, -(strlen($area))) === $area) { - return true; - } - } - } - - return false; + return Utils::isHostInNoProxy($host, $noProxyArray); } /** * Wrapper for json_decode that throws when an error occurs. * * @param string $json JSON data to parse - * @param bool $assoc When true, returned objects will be converted + * @param bool $assoc When true, returned objects will be converted * into associative arrays. * @param int $depth User specified recursion depth. * @param int $options Bitmask of JSON decode options. * - * @return mixed + * @return object|array|string|int|float|bool|null + * * @throws Exception\InvalidArgumentException if the JSON cannot be decoded. - * @link http://www.php.net/manual/en/function.json-decode.php + * + * @link https://www.php.net/manual/en/function.json-decode.php + * @deprecated json_decode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonDecode instead. */ -function json_decode($json, $assoc = false, $depth = 512, $options = 0) +function json_decode(string $json, bool $assoc = false, int $depth = 512, int $options = 0) { - $data = \json_decode($json, $assoc, $depth, $options); - if (JSON_ERROR_NONE !== json_last_error()) { - throw new Exception\InvalidArgumentException( - 'json_decode error: ' . json_last_error_msg() - ); - } - - return $data; + return Utils::jsonDecode($json, $assoc, $depth, $options); } /** * Wrapper for JSON encoding that throws when an error occurs. * * @param mixed $value The value being encoded - * @param int $options JSON encode option bitmask - * @param int $depth Set the maximum depth. Must be greater than zero. + * @param int $options JSON encode option bitmask + * @param int $depth Set the maximum depth. Must be greater than zero. * - * @return string * @throws Exception\InvalidArgumentException if the JSON cannot be encoded. - * @link http://www.php.net/manual/en/function.json-encode.php + * + * @link https://www.php.net/manual/en/function.json-encode.php + * @deprecated json_encode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonEncode instead. */ -function json_encode($value, $options = 0, $depth = 512) +function json_encode($value, int $options = 0, int $depth = 512): string { - $json = \json_encode($value, $options, $depth); - if (JSON_ERROR_NONE !== json_last_error()) { - throw new Exception\InvalidArgumentException( - 'json_encode error: ' . json_last_error_msg() - ); - } - - return $json; + return Utils::jsonEncode($value, $options, $depth); } diff --git a/guzzlehttp/guzzle/src/functions_include.php b/guzzlehttp/guzzle/src/functions_include.php index a93393acc..6636a4224 100644 --- a/guzzlehttp/guzzle/src/functions_include.php +++ b/guzzlehttp/guzzle/src/functions_include.php @@ -1,6 +1,6 @@ + +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. diff --git a/guzzlehttp/uri-template/README.md b/guzzlehttp/uri-template/README.md new file mode 100644 index 000000000..9902449be --- /dev/null +++ b/guzzlehttp/uri-template/README.md @@ -0,0 +1,29 @@ +# uri-template + +**THIS PACKAGE IS STILL UNDER DEVELOPMENT** if you use it make sure you lock into a specific version. + +## Install + +Via Composer + +``` bash +$ composer require guzzlehttp/uri-template +``` + +## Change log + +Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. + +## Testing + +``` bash +$ make test +``` + +## Security + +If you discover any security related issues, please email security@guzzlephp.org instead of using the issue tracker. + +## License + +The MIT License (MIT). Please see [License File](LICENSE.md) for more information. diff --git a/guzzlehttp/uri-template/composer.json b/guzzlehttp/uri-template/composer.json new file mode 100644 index 000000000..335a4b224 --- /dev/null +++ b/guzzlehttp/uri-template/composer.json @@ -0,0 +1,61 @@ +{ + "name": "guzzlehttp/uri-template", + "type": "library", + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "homepage": "https://github.com/guzzlehttp/uri-template", + "license": "MIT", + "authors": [ + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos", + "role": "Developer" + } + ], + "repositories": [ + { + "type": "package", + "package": { + "name": "uri-template/tests", + "version": "1.0.0", + "dist": { + "url": "https://github.com/uri-templates/uritemplate-test/archive/520fdd8b0f78779d12178c357a986e0e727f4bd0.zip", + "type": "zip" + } + } + } + ], + "require": { + "php" : "^7.1 || ^8.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "phpunit/phpunit" : "^7.5.15 || ^8.5 || ^9.3", + "uri-template/tests": "1.0.0" + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\Tests\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "config": { + "preferred-install": "dist", + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/guzzlehttp/uri-template/src/UriTemplate.php b/guzzlehttp/uri-template/src/UriTemplate.php new file mode 100644 index 000000000..31915f4d6 --- /dev/null +++ b/guzzlehttp/uri-template/src/UriTemplate.php @@ -0,0 +1,296 @@ + Hash for quick operator lookups + */ + private static $operatorHash = [ + '' => ['prefix' => '', 'joiner' => ',', 'query' => false], + '+' => ['prefix' => '', 'joiner' => ',', 'query' => false], + '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false], + '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false], + '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false], + ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true], + '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true], + '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true], + ]; + + /** + * @var string[] Delimiters + */ + private static $delims = [ + ':', + '/', + '?', + '#', + '[', + ']', + '@', + '!', + '$', + '&', + '\'', + '(', + ')', + '*', + '+', + ',', + ';', + '=', + ]; + + /** + * @var string[] Percent encoded delimiters + */ + private static $delimsPct = [ + '%3A', + '%2F', + '%3F', + '%23', + '%5B', + '%5D', + '%40', + '%21', + '%24', + '%26', + '%27', + '%28', + '%29', + '%2A', + '%2B', + '%2C', + '%3B', + '%3D', + ]; + + /** + * @param array $variables Variables to use in the template expansion + * + * @throws \RuntimeException + */ + public static function expand(string $template, array $variables): string + { + if (false === \strpos($template, '{')) { + return $template; + } + + /** @var string|null */ + $result = \preg_replace_callback( + '/\{([^\}]+)\}/', + self::expandMatchCallback($variables), + $template + ); + + if (null === $result) { + throw new \RuntimeException(\sprintf('Unable to process template: %s', \preg_last_error_msg())); + } + + return $result; + } + + /** + * @param array $variables Variables to use in the template expansion + * + * @return callable(string[]): string + */ + private static function expandMatchCallback(array $variables): callable + { + return static function (array $matches) use ($variables): string { + return self::expandMatch($matches, $variables); + }; + } + + /** + * Process an expansion + * + * @param array $variables Variables to use in the template expansion + * @param string[] $matches Matches met in the preg_replace_callback + * + * @return string Returns the replacement string + */ + private static function expandMatch(array $matches, array $variables): string + { + $replacements = []; + $parsed = self::parseExpression($matches[1]); + $prefix = self::$operatorHash[$parsed['operator']]['prefix']; + $joiner = self::$operatorHash[$parsed['operator']]['joiner']; + $useQuery = self::$operatorHash[$parsed['operator']]['query']; + $allUndefined = true; + + foreach ($parsed['values'] as $value) { + if (!isset($variables[$value['value']])) { + continue; + } + + /** @var mixed */ + $variable = $variables[$value['value']]; + $actuallyUseQuery = $useQuery; + $expanded = ''; + + if (\is_array($variable)) { + $isAssoc = self::isAssoc($variable); + $kvp = []; + /** @var mixed $var */ + foreach ($variable as $key => $var) { + if ($isAssoc) { + $key = \rawurlencode((string) $key); + $isNestedArray = \is_array($var); + } else { + $isNestedArray = false; + } + + if (!$isNestedArray) { + $var = \rawurlencode((string) $var); + if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { + $var = self::decodeReserved($var); + } + } + + if ($value['modifier'] === '*') { + if ($isAssoc) { + if ($isNestedArray) { + // Nested arrays must allow for deeply nested structures. + $var = \http_build_query([$key => $var], '', '&', \PHP_QUERY_RFC3986); + } else { + $var = \sprintf('%s=%s', (string) $key, (string) $var); + } + } elseif ($key > 0 && $actuallyUseQuery) { + $var = \sprintf('%s=%s', $value['value'], (string) $var); + } + } + + /** @var string */ + $kvp[$key] = $var; + } + + if (0 === \count($variable)) { + $actuallyUseQuery = false; + } elseif ($value['modifier'] === '*') { + $expanded = \implode($joiner, $kvp); + if ($isAssoc) { + // Don't prepend the value name when using the explode + // modifier with an associative array. + $actuallyUseQuery = false; + } + } else { + if ($isAssoc) { + // When an associative array is encountered and the + // explode modifier is not set, then the result must be + // a comma separated list of keys followed by their + // respective values. + foreach ($kvp as $k => &$v) { + $v = \sprintf('%s,%s', $k, $v); + } + } + $expanded = \implode(',', $kvp); + } + } else { + $allUndefined = false; + if ($value['modifier'] === ':' && isset($value['position'])) { + $variable = \substr((string) $variable, 0, $value['position']); + } + $expanded = \rawurlencode((string) $variable); + if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { + $expanded = self::decodeReserved($expanded); + } + } + + if ($actuallyUseQuery) { + if (!$expanded && $joiner !== '&') { + $expanded = $value['value']; + } else { + $expanded = \sprintf('%s=%s', $value['value'], $expanded); + } + } + + $replacements[] = $expanded; + } + + $ret = \implode($joiner, $replacements); + + if ('' === $ret) { + // Spec section 3.2.4 and 3.2.5 + if (false === $allUndefined && ('#' === $prefix || '.' === $prefix)) { + return $prefix; + } + } else { + if ('' !== $prefix) { + return \sprintf('%s%s', $prefix, $ret); + } + } + + return $ret; + } + + /** + * Parse an expression into parts + * + * @param string $expression Expression to parse + * + * @return array{operator:string, values:array} + */ + private static function parseExpression(string $expression): array + { + $result = []; + + if (isset(self::$operatorHash[$expression[0]])) { + $result['operator'] = $expression[0]; + /** @var string */ + $expression = \substr($expression, 1); + } else { + $result['operator'] = ''; + } + + $result['values'] = []; + foreach (\explode(',', $expression) as $value) { + $value = \trim($value); + $varspec = []; + if ($colonPos = \strpos($value, ':')) { + $varspec['value'] = (string) \substr($value, 0, $colonPos); + $varspec['modifier'] = ':'; + $varspec['position'] = (int) \substr($value, $colonPos + 1); + } elseif (\substr($value, -1) === '*') { + $varspec['modifier'] = '*'; + $varspec['value'] = (string) \substr($value, 0, -1); + } else { + $varspec['value'] = $value; + $varspec['modifier'] = ''; + } + $result['values'][] = $varspec; + } + + return $result; + } + + /** + * Determines if an array is associative. + * + * This makes the assumption that input arrays are sequences or hashes. + * This assumption is a tradeoff for accuracy in favor of speed, but it + * should work in almost every case where input is supplied for a URI + * template. + */ + private static function isAssoc(array $array): bool + { + return $array && \array_keys($array)[0] !== 0; + } + + /** + * Removes percent encoding on reserved characters (used with + and # + * modifiers). + */ + private static function decodeReserved(string $string): string + { + return \str_replace(self::$delimsPct, self::$delims, $string); + } +} diff --git a/justinrainbow/json-schema/.gitattributes b/justinrainbow/json-schema/.gitattributes deleted file mode 100644 index beeff5b85..000000000 --- a/justinrainbow/json-schema/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -/docs export-ignore -/tests export-ignore -.gitignore export-ignore -.travis.yml export-ignore -phpunit.dist.xml export-ignore diff --git a/justinrainbow/json-schema/composer.json b/justinrainbow/json-schema/composer.json index 884a69710..fcacd40c3 100644 --- a/justinrainbow/json-schema/composer.json +++ b/justinrainbow/json-schema/composer.json @@ -31,7 +31,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", - "json-schema/JSON-Schema-Test-Suite": "1.2.0", + "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, "extra": { @@ -53,7 +53,7 @@ { "type": "package", "package": { - "name": "json-schema/JSON-Schema-Test-Suite", + "name": "json-schema/json-schema-test-suite", "version": "1.2.0", "source": { "type": "git", diff --git a/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php b/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php index e194cb0e4..8effd4ba2 100644 --- a/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php +++ b/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php @@ -59,7 +59,7 @@ public function check(&$value, $schema = null, JsonPointer $path = null, $i = nu * @param JsonPointer $path * @param string $i */ - public function validateTypes(&$value, $schema = null, JsonPointer $path, $i = null) + public function validateTypes(&$value, $schema, JsonPointer $path, $i = null) { // check array if ($this->getTypeCheck()->isArray($value)) { @@ -105,7 +105,7 @@ public function validateTypes(&$value, $schema = null, JsonPointer $path, $i = n * @param JsonPointer $path * @param string $i */ - protected function validateCommonProperties(&$value, $schema = null, JsonPointer $path, $i = '') + protected function validateCommonProperties(&$value, $schema, JsonPointer $path, $i = '') { // if it extends another schema, it must pass that schema as well if (isset($schema->extends)) { @@ -151,7 +151,7 @@ protected function validateCommonProperties(&$value, $schema = null, JsonPointer ); } } else { - // If the value is both undefined and not required, skip remaining checks + // if the value is both undefined and not required, skip remaining checks // in this method which assume an actual, defined instance when validating. if ($value instanceof self) { return; diff --git a/microsoft/azure-storage-blob/ChangeLog.md b/microsoft/azure-storage-blob/ChangeLog.md index e6be01f7f..212e1fa44 100644 --- a/microsoft/azure-storage-blob/ChangeLog.md +++ b/microsoft/azure-storage-blob/ChangeLog.md @@ -1,3 +1,10 @@ +2020.12 - version 1.5.2 +* Resolved an issue where access condition does not work for large block blob uploads. +* Guzzle version is now updated to support both 6.x and 7.x. + +2020.08 - version 1.5.1 +* Lower case query parameter names. + 2020.01 - version 1.5.0 * Added support to include deleted in blob list. diff --git a/microsoft/azure-storage-blob/composer.json b/microsoft/azure-storage-blob/composer.json index 5d9be170e..b74c369e7 100644 --- a/microsoft/azure-storage-blob/composer.json +++ b/microsoft/azure-storage-blob/composer.json @@ -1,6 +1,6 @@ { "name": "microsoft/azure-storage-blob", - "version": "1.5.0", + "version": "1.5.2", "description": "This project provides a set of PHP client libraries that make it easy to access Microsoft Azure Storage Blob APIs.", "keywords": [ "php", "azure", "storage", "sdk", "blob" ], "license": "MIT", @@ -12,7 +12,7 @@ ], "require": { "php": ">=5.6.0", - "microsoft/azure-storage-common": "~1.4" + "microsoft/azure-storage-common": "~1.5" }, "autoload": { "psr-4": { diff --git a/microsoft/azure-storage-blob/src/Blob/BlobRestProxy.php b/microsoft/azure-storage-blob/src/Blob/BlobRestProxy.php index e3868749f..d2d3cc3f6 100644 --- a/microsoft/azure-storage-blob/src/Blob/BlobRestProxy.php +++ b/microsoft/azure-storage-blob/src/Blob/BlobRestProxy.php @@ -864,17 +864,17 @@ public function listContainersAsync( ); $this->addOptionalQueryParam( $queryParams, - Resources::QP_PREFIX, + Resources::QP_PREFIX_LOWERCASE, $options->getPrefix() ); $this->addOptionalQueryParam( $queryParams, - Resources::QP_MARKER, + Resources::QP_MARKER_LOWERCASE, $options->getNextMarker() ); $this->addOptionalQueryParam( $queryParams, - Resources::QP_MAX_RESULTS, + Resources::QP_MAX_RESULTS_LOWERCASE, $options->getMaxResults() ); $isInclude = $options->getIncludeMetadata(); @@ -1522,12 +1522,12 @@ public function listBlobsAsync( ); $this->addOptionalQueryParam( $queryParams, - Resources::QP_PREFIX, + Resources::QP_PREFIX_LOWERCASE, str_replace('\\', '/', $options->getPrefix()) ); $this->addOptionalQueryParam( $queryParams, - Resources::QP_MARKER, + Resources::QP_MARKER_LOWERCASE, $options->getNextMarker() ); $this->addOptionalQueryParam( @@ -1537,7 +1537,7 @@ public function listBlobsAsync( ); $this->addOptionalQueryParam( $queryParams, - Resources::QP_MAX_RESULTS, + Resources::QP_MAX_RESULTS_LOWERCASE, $options->getMaxResults() ); diff --git a/microsoft/azure-storage-blob/src/Blob/Internal/BlobResources.php b/microsoft/azure-storage-blob/src/Blob/Internal/BlobResources.php index c7f30419d..73eb34ba9 100644 --- a/microsoft/azure-storage-blob/src/Blob/Internal/BlobResources.php +++ b/microsoft/azure-storage-blob/src/Blob/Internal/BlobResources.php @@ -41,7 +41,7 @@ class BlobResources extends Resources { // @codingStandardsIgnoreStart - const BLOB_SDK_VERSION = '1.5.0'; + const BLOB_SDK_VERSION = '1.5.2'; const STORAGE_API_LATEST_VERSION = '2017-11-09'; // Error messages diff --git a/microsoft/azure-storage-blob/src/Blob/Models/BlobProperties.php b/microsoft/azure-storage-blob/src/Blob/Models/BlobProperties.php index aa8d62055..a81b0a877 100644 --- a/microsoft/azure-storage-blob/src/Blob/Models/BlobProperties.php +++ b/microsoft/azure-storage-blob/src/Blob/Models/BlobProperties.php @@ -866,7 +866,7 @@ private function setCommonBlobProperties(array $clean) Utilities::tryGetValue($clean, Resources::CONTENT_LANGUAGE) ); $this->setContentType( - Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) + Utilities::tryGetValue($clean, Resources::CONTENT_TYPE_LOWER_CASE) ); if (Utilities::tryGetValue($clean, Resources::CONTENT_MD5) && diff --git a/microsoft/azure-storage-blob/src/Blob/Models/CommitBlobBlocksOptions.php b/microsoft/azure-storage-blob/src/Blob/Models/CommitBlobBlocksOptions.php index 6ef773fbb..632270c6e 100644 --- a/microsoft/azure-storage-blob/src/Blob/Models/CommitBlobBlocksOptions.php +++ b/microsoft/azure-storage-blob/src/Blob/Models/CommitBlobBlocksOptions.php @@ -217,6 +217,7 @@ public static function create($options) $result->setContentDisposition($options->getContentDisposition()); $result->setMetadata($options->getMetadata()); $result->setLeaseId($options->getLeaseId()); + $result->setAccessConditions($options->getAccessConditions()); return $result; } diff --git a/microsoft/azure-storage-blob/src/Blob/Models/ListBlobBlocksResult.php b/microsoft/azure-storage-blob/src/Blob/Models/ListBlobBlocksResult.php index c879d976b..c9421ca99 100644 --- a/microsoft/azure-storage-blob/src/Blob/Models/ListBlobBlocksResult.php +++ b/microsoft/azure-storage-blob/src/Blob/Models/ListBlobBlocksResult.php @@ -104,7 +104,7 @@ public static function create(array $headers, array $parsed) ) ); $result->setContentType( - Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) + Utilities::tryGetValue($clean, Resources::CONTENT_TYPE_LOWER_CASE) ); $result->uncommittedBlocks = self::getEntries( diff --git a/microsoft/azure-storage-blob/src/Blob/Models/UndeleteBlobOptions.php b/microsoft/azure-storage-blob/src/Blob/Models/UndeleteBlobOptions.php new file mode 100644 index 000000000..b6c268a3b --- /dev/null +++ b/microsoft/azure-storage-blob/src/Blob/Models/UndeleteBlobOptions.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Blob\Models; + +/** + * Optional parameters for deleteBlob wrapper + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Blob\Models + * @author Azure Storage PHP SDK + * @copyright 2016 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class UndeleteBlobOptions extends BlobServiceOptions +{ +} diff --git a/microsoft/azure-storage-common/ChangeLog.md b/microsoft/azure-storage-common/ChangeLog.md index 5a0254de0..0f3418b86 100644 --- a/microsoft/azure-storage-common/ChangeLog.md +++ b/microsoft/azure-storage-common/ChangeLog.md @@ -1,3 +1,16 @@ +2020.12 - version 1.5.1 +* Guzzle version is now updated to support both 6.x and 7.x. + +2020.08 - version 1.5.0 +* Resolved TLS 1.2 issue and some test issues. +* Check $uri null type before array/string access. +* Accept DateTimeImmutable as EdmType input. +* Added client-request-id to requests. +* Updated getContinuationToken return type. +* Call static methods using `static::` not `self::`. +* Added $isSecondary parameter for appendBlobRetryDecider. +* Retry on no response from server after a successful connection + 2020.01 - version 1.4.1 * Changed to perform override existence instead of value check for ‘$options[‘verify’]’ in ‘ServiceRestProxy’. diff --git a/microsoft/azure-storage-common/composer.json b/microsoft/azure-storage-common/composer.json index a924baa09..8afe15c52 100644 --- a/microsoft/azure-storage-common/composer.json +++ b/microsoft/azure-storage-common/composer.json @@ -1,6 +1,6 @@ { "name": "microsoft/azure-storage-common", - "version": "1.4.1", + "version": "1.5.1", "description": "This project provides a set of common code shared by Azure Storage Blob, Table, Queue and File PHP client libraries.", "keywords": [ "php", "azure", "storage", "sdk", "common" ], "license": "MIT", @@ -12,11 +12,11 @@ ], "require": { "php": ">=5.6.0", - "guzzlehttp/guzzle": "~6.0" + "guzzlehttp/guzzle": "~6.0|^7.0" }, "autoload": { "psr-4": { "MicrosoftAzure\\Storage\\Common\\": "src/Common" } } -} \ No newline at end of file +} diff --git a/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedKeyAuthScheme.php b/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedKeyAuthScheme.php index d9a88bffe..afc23fcb8 100644 --- a/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedKeyAuthScheme.php +++ b/microsoft/azure-storage-common/src/Common/Internal/Authentication/SharedKeyAuthScheme.php @@ -115,7 +115,7 @@ protected function computeSignature( $stringToSign[] = strtoupper($httpMethod); foreach ($this->includedHeaders as $header) { - $stringToSign[] = Utilities::tryGetValue($headers, $header); + $stringToSign[] = Utilities::tryGetValueInsensitive($header, $headers); } if (count($canonicalizedHeaders) > 0) { diff --git a/microsoft/azure-storage-common/src/Common/Internal/Authentication/TokenAuthScheme.php b/microsoft/azure-storage-common/src/Common/Internal/Authentication/TokenAuthScheme.php new file mode 100644 index 000000000..d654cc1b7 --- /dev/null +++ b/microsoft/azure-storage-common/src/Common/Internal/Authentication/TokenAuthScheme.php @@ -0,0 +1,73 @@ + + * @copyright 2019 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Common\Internal\Authentication; + +use GuzzleHttp\Psr7\Request; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Validate; + +/** + * Azure authentication scheme for token credential. + * + * @ignore + * @category Microsoft + * @package MicrosoftAzure\Storage\Common\Internal\Authentication + * @author Azure Storage PHP SDK + * @copyright 2019 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class TokenAuthScheme implements IAuthScheme +{ + /** + * The authentication token + */ + protected $tokenRef; + + /** + * Constructor. + * + * @param string $token the token used for AAD authentication. + */ + public function __construct(&$token) + { + $this->tokenRef =& $token; + } + + /** + * Adds authentication header to the request headers. + * + * @param \GuzzleHttp\Psr7\Request $request HTTP request object. + * + * @abstract + * + * @return \GuzzleHttp\Psr7\Request + */ + public function signRequest(Request $request) + { + $bearerToken = "Bearer ". $this->tokenRef; + return $request->withHeader(Resources::AUTHENTICATION, $bearerToken); + } +} diff --git a/microsoft/azure-storage-common/src/Common/Internal/Http/HttpCallContext.php b/microsoft/azure-storage-common/src/Common/Internal/Http/HttpCallContext.php index e0805adfa..31eba33e6 100644 --- a/microsoft/azure-storage-common/src/Common/Internal/Http/HttpCallContext.php +++ b/microsoft/azure-storage-common/src/Common/Internal/Http/HttpCallContext.php @@ -414,7 +414,9 @@ public function __toString() $headers = Resources::EMPTY_STRING; $uri = $this->_uri; - if ($uri[strlen($uri)-1] != '/') { + if ($uri === null) { + $uri = '/'; + } elseif ($uri[strlen($uri)-1] != '/') { $uri = $uri.'/'; } diff --git a/microsoft/azure-storage-common/src/Common/Internal/Middlewares/CommonRequestMiddleware.php b/microsoft/azure-storage-common/src/Common/Internal/Middlewares/CommonRequestMiddleware.php index 6d7e5978a..4da9ba0bd 100644 --- a/microsoft/azure-storage-common/src/Common/Internal/Middlewares/CommonRequestMiddleware.php +++ b/microsoft/azure-storage-common/src/Common/Internal/Middlewares/CommonRequestMiddleware.php @@ -105,9 +105,9 @@ protected function onRequest(RequestInterface $request) $date = gmdate(Resources::AZURE_DATE_FORMAT, time()); $result = $result->withHeader(Resources::DATE, $date); - //Adding request-ID if not specified by the user. - if (!$result->hasHeader(Resources::X_MS_REQUEST_ID)) { - $result = $result->withHeader(Resources::X_MS_REQUEST_ID, \uniqid()); + //Adding client request-ID if not specified by the user. + if (!$result->hasHeader(Resources::X_MS_CLIENT_REQUEST_ID)) { + $result = $result->withHeader(Resources::X_MS_CLIENT_REQUEST_ID, \uniqid()); } //Sign the request if authentication scheme is not null. $request = $this->authenticationScheme == null ? diff --git a/microsoft/azure-storage-common/src/Common/Internal/Resources.php b/microsoft/azure-storage-common/src/Common/Internal/Resources.php index 973fa4625..48128d4f1 100644 --- a/microsoft/azure-storage-common/src/Common/Internal/Resources.php +++ b/microsoft/azure-storage-common/src/Common/Internal/Resources.php @@ -158,6 +158,7 @@ class Resources const X_MS_CONTINUATION_NEXTPARTITIONKEY = 'x-ms-continuation-nextpartitionkey'; const X_MS_CONTINUATION_NEXTROWKEY = 'x-ms-continuation-nextrowkey'; const X_MS_REQUEST_ID = 'x-ms-request-id'; + const X_MS_CLIENT_REQUEST_ID = 'x-ms-client-request-id'; const X_MS_CONTINUATION_LOCATION_MODE = 'x-ms-continuation-location-mode'; const X_MS_TYPE = 'x-ms-type'; const X_MS_CONTENT_LENGTH = 'x-ms-content-length'; @@ -178,7 +179,8 @@ class Resources const CONTENT_LENGTH = 'content-length'; const CONTENT_LENGTH_NO_SPACE = 'contentlength'; const CONTENT_MD5 = 'content-md5'; - const CONTENT_TYPE = 'content-type'; + const CONTENT_TYPE_LOWER_CASE = 'content-type'; + const CONTENT_TYPE = 'Content-Type'; const CONTENT_ID = 'content-id'; const CONTENT_RANGE = 'content-range'; const CACHE_CONTROL = 'cache-control'; @@ -239,16 +241,19 @@ class Resources const BEARER = 'Bearer '; // Header values - const COMMON_SDK_VERSION = '1.4.1'; + const COMMON_SDK_VERSION = '1.5.1'; const INT32_MAX = 2147483647; const INT32_MIN = -2147483648; // Query parameter names const QP_ENTRIES = 'Entries'; const QP_PREFIX = 'Prefix'; + const QP_PREFIX_LOWERCASE = 'prefix'; const QP_MAX_RESULTS = 'MaxResults'; - const QP_METADATA = 'Metadata'; + const QP_MAX_RESULTS_LOWERCASE = 'maxresults'; const QP_MARKER = 'Marker'; + const QP_MARKER_LOWERCASE = 'marker'; + const QP_METADATA = 'Metadata'; const QP_NEXT_MARKER = 'NextMarker'; const QP_COMP = 'comp'; const QP_INCLUDE = 'include'; diff --git a/microsoft/azure-storage-common/src/Common/Internal/ServiceRestProxy.php b/microsoft/azure-storage-common/src/Common/Internal/ServiceRestProxy.php index ee560fb08..1b911e594 100644 --- a/microsoft/azure-storage-common/src/Common/Internal/ServiceRestProxy.php +++ b/microsoft/azure-storage-common/src/Common/Internal/ServiceRestProxy.php @@ -120,6 +120,11 @@ private static function createClient(array $options) "allow_redirects" => true, "exceptions" => true, "decode_content" => true, + "config" => [ + "curl" => [ + CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2 + ] + ] ), 'cookies' => true, 'verify' => $verify, @@ -296,11 +301,11 @@ protected function createRequest( $uri = $uri->withQuery($queryString); } - // add post parameters into bodys + // add post parameters into bodies $actualBody = null; if (empty($body)) { - if (empty($headers['content-type'])) { - $headers['content-type'] = 'application/x-www-form-urlencoded'; + if (empty($headers[Resources::CONTENT_TYPE])) { + $headers[Resources::CONTENT_TYPE] = Resources::URL_ENCODED_CONTENT_TYPE; $actualBody = Psr7\build_query($postParameters); } } else { diff --git a/microsoft/azure-storage-common/src/Common/Internal/Validate.php b/microsoft/azure-storage-common/src/Common/Internal/Validate.php index 4517e7da0..1d2926847 100644 --- a/microsoft/azure-storage-common/src/Common/Internal/Validate.php +++ b/microsoft/azure-storage-common/src/Common/Internal/Validate.php @@ -180,7 +180,7 @@ public static function isTrue($isSatisfied, $failureMessage) } /** - * Throws exception if the provided $date is not of type \DateTime + * Throws exception if the provided $date doesn't implement \DateTimeInterface * * @param mixed $date variable to check against. * @@ -190,8 +190,8 @@ public static function isTrue($isSatisfied, $failureMessage) */ public static function isDate($date) { - if (gettype($date) != 'object' || get_class($date) != 'DateTime') { - throw new InvalidArgumentTypeException('DateTime'); + if (gettype($date) != 'object' || !($date instanceof \DateTimeInterface)) { + throw new InvalidArgumentTypeException('DateTimeInterface'); } } diff --git a/microsoft/azure-storage-common/src/Common/MarkerContinuationTokenTrait.php b/microsoft/azure-storage-common/src/Common/MarkerContinuationTokenTrait.php index 7ef5308ba..4532c46c6 100644 --- a/microsoft/azure-storage-common/src/Common/MarkerContinuationTokenTrait.php +++ b/microsoft/azure-storage-common/src/Common/MarkerContinuationTokenTrait.php @@ -63,7 +63,7 @@ public function setMarker($marker) /** * Getter for continuationToken * - * @return ContinuationToken + * @return MarkerContinuationToken */ public function getContinuationToken() { diff --git a/microsoft/azure-storage-common/src/Common/Middlewares/RetryMiddlewareFactory.php b/microsoft/azure-storage-common/src/Common/Middlewares/RetryMiddlewareFactory.php index ca841e70c..f024ef7ab 100644 --- a/microsoft/azure-storage-common/src/Common/Middlewares/RetryMiddlewareFactory.php +++ b/microsoft/azure-storage-common/src/Common/Middlewares/RetryMiddlewareFactory.php @@ -123,12 +123,12 @@ public static function create( //accumulation method. $intervalCalculator = $accumulationMethod == self::LINEAR_INTERVAL_ACCUMULATION ? - self::createLinearDelayCalculator($interval) : - self::createExponentialDelayCalculator($interval); + static::createLinearDelayCalculator($interval) : + static::createExponentialDelayCalculator($interval); //Get the retry decider according to the type of the retry and //the number of retries. - $retryDecider = self::createRetryDecider($type, $numberOfRetries, $retryConnect); + $retryDecider = static::createRetryDecider($type, $numberOfRetries, $retryConnect); //construct the retry middle ware. return new RetryMiddleware($intervalCalculator, $retryDecider); @@ -171,16 +171,19 @@ protected static function createRetryDecider($type, $maxRetries, $retryConnect) return $retryConnect; } else { $response = $exception->getResponse(); + if (!$response) { + return true; + } } } if ($type == self::GENERAL_RETRY_TYPE) { - return self::generalRetryDecider( + return static::generalRetryDecider( $response->getStatusCode(), $isSecondary ); } else { - return self::appendBlobRetryDecider( + return static::appendBlobRetryDecider( $response->getStatusCode(), $isSecondary ); @@ -193,7 +196,8 @@ protected static function createRetryDecider($type, $maxRetries, $retryConnect) /** * Decide if the given status code indicate the request should be retried. * - * @param int $statusCode status code of the previous request. + * @param int $statusCode Status code of the previous request. + * @param bool $isSecondary Whether the request is sent to secondary endpoint. * * @return bool true if the request should be retried. */ @@ -216,11 +220,12 @@ protected static function generalRetryDecider($statusCode, $isSecondary) * Decide if the given status code indicate the request should be retried. * This is for append blob. * - * @param int $statusCode status code of the previous request. + * @param int $statusCode Status code of the previous request. + * @param bool $isSecondary Whether the request is sent to secondary endpoint. * * @return bool true if the request should be retried. */ - protected static function appendBlobRetryDecider($statusCode) + protected static function appendBlobRetryDecider($statusCode, $isSecondary) { //The retry logic is different for append blob. //First it will need to record the former status code if it is @@ -228,7 +233,7 @@ protected static function appendBlobRetryDecider($statusCode) //needs to be retried. Currently this is not implemented so will //only adapt to the general retry decider. //TODO: add logic for append blob's retry when implemented. - $retry = self::generalRetryDecider($statusCode); + $retry = static::generalRetryDecider($statusCode, $isSecondary); return $retry; } diff --git a/php-http/guzzle6-adapter/composer.json b/php-http/guzzle6-adapter/composer.json deleted file mode 100644 index 8592ebaf6..000000000 --- a/php-http/guzzle6-adapter/composer.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "php-http/guzzle6-adapter", - "description": "Guzzle 6 HTTP Adapter", - "license": "MIT", - "keywords": ["guzzle", "http"], - "homepage": "http://httplug.io", - "authors": [ - { - "name": "David de Boer", - "email": "david@ddeboer.nl" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "require": { - "php": "^7.1", - "php-http/httplug": "^2.0", - "psr/http-client": "^1.0", - "guzzlehttp/guzzle": "^6.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^7.4", - "php-http/client-integration-tests": "^2.0" - }, - "provide": { - "php-http/client-implementation": "1.0", - "php-http/async-client-implementation": "1.0", - "psr/http-client-implementation": "1.0" - }, - "autoload": { - "psr-4": { - "Http\\Adapter\\Guzzle6\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Http\\Adapter\\Guzzle6\\Tests\\": "tests/" - } - }, - "scripts": { - "test": "vendor/bin/phpunit", - "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml" - }, - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - } -} diff --git a/php-http/guzzle6-adapter/puli.json b/php-http/guzzle6-adapter/puli.json deleted file mode 100644 index bd2961464..000000000 --- a/php-http/guzzle6-adapter/puli.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "1.0", - "name": "php-http/guzzle6-adapter", - "bindings": { - "04b5a002-71a8-473d-a8df-75671551b84a": { - "_class": "Puli\\Discovery\\Binding\\ClassBinding", - "class": "Http\\Adapter\\Guzzle6\\Client", - "type": "Http\\Client\\HttpClient" - }, - "9c856476-7f6b-43df-a740-15420a5f839c": { - "_class": "Puli\\Discovery\\Binding\\ClassBinding", - "class": "Http\\Adapter\\Guzzle6\\Client", - "type": "Http\\Client\\HttpAsyncClient" - } - } -} diff --git a/php-http/guzzle7-adapter/CHANGELOG.md b/php-http/guzzle7-adapter/CHANGELOG.md new file mode 100644 index 000000000..a397b213c --- /dev/null +++ b/php-http/guzzle7-adapter/CHANGELOG.md @@ -0,0 +1,14 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [0.1.1] - 2020-10-21 + +* Allow installation with PHP 8 + +## [0.1.0] - 2020-08-16 + +First release diff --git a/php-http/guzzle6-adapter/LICENSE b/php-http/guzzle7-adapter/LICENSE similarity index 89% rename from php-http/guzzle6-adapter/LICENSE rename to php-http/guzzle7-adapter/LICENSE index 48741e416..0d6ce83b8 100644 --- a/php-http/guzzle6-adapter/LICENSE +++ b/php-http/guzzle7-adapter/LICENSE @@ -1,5 +1,4 @@ -Copyright (c) 2014-2015 Eric GELOEN -Copyright (c) 2015-2016 PHP HTTP Team +Copyright (c) 2020 PHP HTTP Team 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/php-http/guzzle7-adapter/README.md b/php-http/guzzle7-adapter/README.md new file mode 100644 index 000000000..7e6b5b5dc --- /dev/null +++ b/php-http/guzzle7-adapter/README.md @@ -0,0 +1,45 @@ +# Guzzle 7 HTTP Adapter + +[![Latest Version](https://img.shields.io/github/release/php-http/guzzle7-adapter.svg?style=flat-square)](https://github.com/php-http/guzzle7-adapter/releases) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) +[![Total Downloads](https://img.shields.io/packagist/dt/php-http/guzzle7-adapter.svg?style=flat-square)](https://packagist.org/packages/php-http/guzzle7-adapter) + +**Guzzle 7 HTTP Adapter.** + +## Install + +Via Composer + +``` bash +$ composer require php-http/guzzle7-adapter +``` + +## Documentation + +Please see the [official documentation](http://docs.php-http.org/en/latest/clients/guzzle7-adapter.html). + +## Testing + +First launch the http server: + +```bash +$ ./vendor/bin/http_test_server > /dev/null 2>&1 & +``` + +Then the test suite: + +``` bash +$ composer test +``` + +## Contributing + +Please see our [contributing guide](http://docs.php-http.org/en/latest/development/contributing.html). + +## Security + +If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org). + +## License + +The MIT License (MIT). Please see [License File](LICENSE) for more information. diff --git a/php-http/guzzle7-adapter/composer.json b/php-http/guzzle7-adapter/composer.json new file mode 100644 index 000000000..3299d2eb7 --- /dev/null +++ b/php-http/guzzle7-adapter/composer.json @@ -0,0 +1,43 @@ +{ + "name": "php-http/guzzle7-adapter", + "description": "Guzzle 7 HTTP Adapter", + "license": "MIT", + "keywords": ["guzzle", "http"], + "homepage": "http://httplug.io", + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "require": { + "php": "^7.2 | ^8.0", + "php-http/httplug": "^2.0", + "psr/http-client": "^1.0", + "guzzlehttp/guzzle": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3", + "php-http/client-integration-tests": "^3.0" + }, + "provide": { + "php-http/client-implementation": "1.0", + "php-http/async-client-implementation": "1.0", + "psr/http-client-implementation": "1.0" + }, + "autoload": { + "psr-4": { + "Http\\Adapter\\Guzzle7\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Http\\Adapter\\Guzzle7\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.2.x-dev" + } + } +} diff --git a/php-http/guzzle7-adapter/phpstan.neon.dist b/php-http/guzzle7-adapter/phpstan.neon.dist new file mode 100644 index 000000000..d42940e93 --- /dev/null +++ b/php-http/guzzle7-adapter/phpstan.neon.dist @@ -0,0 +1,5 @@ +parameters: + level: 5 + reportUnmatchedIgnoredErrors: false + paths: + - src diff --git a/php-http/guzzle7-adapter/psalm.baseline.xml b/php-http/guzzle7-adapter/psalm.baseline.xml new file mode 100644 index 000000000..96ab42cf9 --- /dev/null +++ b/php-http/guzzle7-adapter/psalm.baseline.xml @@ -0,0 +1,8 @@ + + + + + $exception->getResponse() + + + diff --git a/php-http/guzzle7-adapter/psalm.xml b/php-http/guzzle7-adapter/psalm.xml new file mode 100644 index 000000000..d70acfe4f --- /dev/null +++ b/php-http/guzzle7-adapter/psalm.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/php-http/guzzle6-adapter/src/Client.php b/php-http/guzzle7-adapter/src/Client.php similarity index 68% rename from php-http/guzzle6-adapter/src/Client.php rename to php-http/guzzle7-adapter/src/Client.php index b90fcd3e8..a92ab06bd 100644 --- a/php-http/guzzle6-adapter/src/Client.php +++ b/php-http/guzzle7-adapter/src/Client.php @@ -2,40 +2,41 @@ declare(strict_types=1); -namespace Http\Adapter\Guzzle6; +namespace Http\Adapter\Guzzle7; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\ClientInterface; use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; +use GuzzleHttp\Utils; use Http\Client\HttpAsyncClient; use Http\Client\HttpClient; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** - * HTTP Adapter for Guzzle 6. + * HTTP Adapter for Guzzle 7. * - * @author David de Boer + * @author Tobias Nyholm */ final class Client implements HttpClient, HttpAsyncClient { /** * @var ClientInterface */ - private $client; + private $guzzle; - public function __construct(?ClientInterface $client = null) + public function __construct(?ClientInterface $guzzle = null) { - if (!$client) { - $client = self::buildClient(); + if (!$guzzle) { + $guzzle = self::buildClient(); } - $this->client = $client; + $this->guzzle = $guzzle; } /** - * Factory method to create the Guzzle 6 adapter with custom Guzzle configuration. + * Factory method to create the Guzzle 7 adapter with custom Guzzle configuration. */ public static function createWithConfig(array $config): Client { @@ -47,9 +48,7 @@ public static function createWithConfig(array $config): Client */ public function sendRequest(RequestInterface $request): ResponseInterface { - $promise = $this->sendAsyncRequest($request); - - return $promise->wait(); + return $this->sendAsyncRequest($request)->wait(); } /** @@ -57,7 +56,7 @@ public function sendRequest(RequestInterface $request): ResponseInterface */ public function sendAsyncRequest(RequestInterface $request) { - $promise = $this->client->sendAsync($request); + $promise = $this->guzzle->sendAsync($request); return new Promise($promise, $request); } @@ -67,7 +66,7 @@ public function sendAsyncRequest(RequestInterface $request) */ private static function buildClient(array $config = []): GuzzleClient { - $handlerStack = new HandlerStack(\GuzzleHttp\choose_handler()); + $handlerStack = new HandlerStack(Utils::chooseHandler()); $handlerStack->push(Middleware::prepareBody(), 'prepare_body'); $config = array_merge(['handler' => $handlerStack], $config); diff --git a/php-http/guzzle6-adapter/src/Exception/UnexpectedValueException.php b/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php similarity index 75% rename from php-http/guzzle6-adapter/src/Exception/UnexpectedValueException.php rename to php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php index e7244fefc..f4731be07 100644 --- a/php-http/guzzle6-adapter/src/Exception/UnexpectedValueException.php +++ b/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php @@ -1,6 +1,6 @@ request = $request; @@ -63,9 +61,9 @@ public function __construct(PromiseInterface $promise, RequestInterface $request } elseif ($reason instanceof GuzzleExceptions\GuzzleException) { $this->exception = $this->handleException($reason, $request); } elseif ($reason instanceof \Throwable) { - $this->exception = new HttplugException\TransferException('Invalid exception returned from Guzzle6', 0, $reason); + $this->exception = new HttplugException\TransferException('Invalid exception returned from Guzzle7', 0, $reason); } else { - $this->exception = new UnexpectedValueException('Reason returned from Guzzle6 must be an Exception'); + $this->exception = new UnexpectedValueException('Reason returned from Guzzle7 must be an Exception'); } throw $this->exception; @@ -107,17 +105,10 @@ public function wait($unwrap = true) /** * Converts a Guzzle exception into an Httplug exception. * - * @param GuzzleExceptions\GuzzleException $exception - * @param RequestInterface $request - * * @return HttplugException */ private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request) { - if ($exception instanceof GuzzleExceptions\SeekException) { - return new HttplugException\RequestException($exception->getMessage(), $request, $exception); - } - if ($exception instanceof GuzzleExceptions\ConnectException) { return new HttplugException\NetworkException($exception->getMessage(), $exception->getRequest(), $exception); } diff --git a/php-http/httplug/composer.json b/php-http/httplug/composer.json index 9adab2293..268b27ec7 100644 --- a/php-http/httplug/composer.json +++ b/php-http/httplug/composer.json @@ -1,9 +1,12 @@ { "name": "php-http/httplug", "description": "HTTPlug, the HTTP client abstraction for PHP", - "license": "MIT", - "keywords": ["http", "client"], + "keywords": [ + "http", + "client" + ], "homepage": "http://httplug.io", + "license": "MIT", "authors": [ { "name": "Eric GELOEN", @@ -11,18 +14,24 @@ }, { "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "require": { - "php": "^7.0", - "psr/http-message": "^1.0", + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", "psr/http-client": "^1.0", - "php-http/promise": "^1.0" + "psr/http-message": "^1.0" }, "require-dev": { - "phpspec/phpspec": "^4.3.4|^5.0|^6.0", - "friends-of-phpspec/phpspec-code-coverage" : "^4.1" + "friends-of-phpspec/phpspec-code-coverage": "^4.1", + "phpspec/phpspec": "^5.1 || ^6.0" + }, + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } }, "autoload": { "psr-4": { @@ -32,10 +41,5 @@ "scripts": { "test": "vendor/bin/phpspec run", "test-ci": "vendor/bin/phpspec run -c phpspec.ci.yml" - }, - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } } } diff --git a/php-http/httplug/src/Exception/HttpException.php b/php-http/httplug/src/Exception/HttpException.php index 38337b5a9..6c2a007a0 100644 --- a/php-http/httplug/src/Exception/HttpException.php +++ b/php-http/httplug/src/Exception/HttpException.php @@ -20,10 +20,7 @@ class HttpException extends RequestException protected $response; /** - * @param string $message - * @param RequestInterface $request - * @param ResponseInterface $response - * @param \Exception|null $previous + * @param string $message */ public function __construct( $message, diff --git a/php-http/httplug/src/Exception/NetworkException.php b/php-http/httplug/src/Exception/NetworkException.php index d52a356d7..9b4f1e8fd 100644 --- a/php-http/httplug/src/Exception/NetworkException.php +++ b/php-http/httplug/src/Exception/NetworkException.php @@ -2,8 +2,8 @@ namespace Http\Client\Exception; -use Psr\Http\Message\RequestInterface; use Psr\Http\Client\NetworkExceptionInterface as PsrNetworkException; +use Psr\Http\Message\RequestInterface; /** * Thrown when the request cannot be completed because of network issues. @@ -17,9 +17,7 @@ class NetworkException extends TransferException implements PsrNetworkException use RequestAwareTrait; /** - * @param string $message - * @param RequestInterface $request - * @param \Exception|null $previous + * @param string $message */ public function __construct($message, RequestInterface $request, \Exception $previous = null) { diff --git a/php-http/httplug/src/Exception/RequestException.php b/php-http/httplug/src/Exception/RequestException.php index b548335dd..f6c60ce56 100644 --- a/php-http/httplug/src/Exception/RequestException.php +++ b/php-http/httplug/src/Exception/RequestException.php @@ -2,8 +2,8 @@ namespace Http\Client\Exception; -use Psr\Http\Message\RequestInterface; use Psr\Http\Client\RequestExceptionInterface as PsrRequestException; +use Psr\Http\Message\RequestInterface; /** * Exception for when a request failed, providing access to the failed request. @@ -18,9 +18,7 @@ class RequestException extends TransferException implements PsrRequestException use RequestAwareTrait; /** - * @param string $message - * @param RequestInterface $request - * @param \Exception|null $previous + * @param string $message */ public function __construct($message, RequestInterface $request, \Exception $previous = null) { diff --git a/php-http/httplug/src/HttpAsyncClient.php b/php-http/httplug/src/HttpAsyncClient.php index bc9d5eec4..c3b9d61aa 100644 --- a/php-http/httplug/src/HttpAsyncClient.php +++ b/php-http/httplug/src/HttpAsyncClient.php @@ -17,7 +17,7 @@ interface HttpAsyncClient * * Exceptions related to processing the request are available from the returned Promise. * - * @return Promise Resolves a PSR-7 Response or fails with an Http\Client\Exception. + * @return Promise resolves a PSR-7 Response or fails with an Http\Client\Exception * * @throws \Exception If processing the request is impossible (eg. bad configuration). */ diff --git a/php-http/httplug/src/Promise/HttpFulfilledPromise.php b/php-http/httplug/src/Promise/HttpFulfilledPromise.php index 6779e4479..1ad32cd53 100644 --- a/php-http/httplug/src/Promise/HttpFulfilledPromise.php +++ b/php-http/httplug/src/Promise/HttpFulfilledPromise.php @@ -13,9 +13,6 @@ final class HttpFulfilledPromise implements Promise */ private $response; - /** - * @param ResponseInterface $response - */ public function __construct(ResponseInterface $response) { $this->response = $response; diff --git a/php-http/httplug/src/Promise/HttpRejectedPromise.php b/php-http/httplug/src/Promise/HttpRejectedPromise.php index bfb0738f1..8af97dead 100644 --- a/php-http/httplug/src/Promise/HttpRejectedPromise.php +++ b/php-http/httplug/src/Promise/HttpRejectedPromise.php @@ -12,9 +12,6 @@ final class HttpRejectedPromise implements Promise */ private $exception; - /** - * @param Exception $exception - */ public function __construct(Exception $exception) { $this->exception = $exception; diff --git a/php-http/promise/composer.json b/php-http/promise/composer.json index ff1d2cee3..812167bc8 100644 --- a/php-http/promise/composer.json +++ b/php-http/promise/composer.json @@ -14,9 +14,12 @@ "email": "mark.sagikazar@gmail.com" } ], + "require": { + "php" : "^7.1 || ^8.0" + }, "require-dev": { - "phpspec/phpspec": "^2.4", - "henrikbjorn/phpspec-code-coverage" : "^1.0" + "friends-of-phpspec/phpspec-code-coverage" : "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" }, "autoload": { "psr-4": { diff --git a/php-http/promise/src/Promise.php b/php-http/promise/src/Promise.php index e2cf5f89e..3258ed0d3 100644 --- a/php-http/promise/src/Promise.php +++ b/php-http/promise/src/Promise.php @@ -36,10 +36,10 @@ interface Promise * If you do not care about one of the cases, you can set the corresponding callable to null * The callback will be called when the value arrived and never more than once. * - * @param callable $onFulfilled Called when a response will be available. - * @param callable $onRejected Called when an exception occurs. + * @param callable|null $onFulfilled called when a response will be available + * @param callable|null $onRejected called when an exception occurs * - * @return Promise A new resolved promise with value of the executed callback (onFulfilled / onRejected). + * @return Promise a new resolved promise with value of the executed callback (onFulfilled / onRejected) */ public function then(callable $onFulfilled = null, callable $onRejected = null); @@ -63,7 +63,7 @@ public function getState(); * * @return mixed Resolved value, null if $unwrap is set to false * - * @throws \Exception The rejection reason if $unwrap is set to true and the request failed. + * @throws \Exception the rejection reason if $unwrap is set to true and the request failed */ public function wait($unwrap = true); } diff --git a/php-opencloud/openstack/CONTRIBUTING.md b/php-opencloud/openstack/CONTRIBUTING.md index 6c45b6316..8661ec7e7 100644 --- a/php-opencloud/openstack/CONTRIBUTING.md +++ b/php-opencloud/openstack/CONTRIBUTING.md @@ -239,7 +239,7 @@ Additionally, integration tests require image called `cirros` exists. You interact with integration tests through a runner script: ```bash -php ./tests/integration/run.php +php ./tests/integration/run.php [-s=BlockStorage|Compute|Identity|Images|Networking|ObjectStore] [--debug=1|2] ``` It supports these command-line flags: diff --git a/php-opencloud/openstack/README.md b/php-opencloud/openstack/README.md index 199b6e169..6b6084085 100644 --- a/php-opencloud/openstack/README.md +++ b/php-opencloud/openstack/README.md @@ -7,7 +7,7 @@ `php-opencloud/openstack` is an SDK which allows PHP developers to easily connect to OpenStack APIs in a simple and idiomatic way. This binding is specifically designed for OpenStack APIs, but other provider SDKs are available. Multiple OpenStack services, and versions of services, are supported. - + ## Links * [Official documentation](https://php-openstack-sdk.readthedocs.io/en/latest/) @@ -15,18 +15,37 @@ OpenStack services, and versions of services, are supported. * [Contributing guide](/CONTRIBUTING.md) * [Code of Conduct](/CODE_OF_CONDUCT.md) -## Getting help + +## We need your help :smiley: + +We invest a large amount of work to ensure this SDK works with many OpenStack distributions via running end-to-end +integration tests with a real cluster. + +If you or your organization are in a position that can help us access popular distributions as listed below, do reach +out by open an issue in github. + +| Distribution | | +|---------------------|-------------------------| +|OpenStack RDO | :white_check_mark: | +|Red Hat OpenStack | Need sponsor! | +|OVH OpenStack | Need sponsor! | +|SUSE OpenStack | Need sponsor! | +|Canonical OpenStack | Need sponsor! | +|RackSpace OpenStack | Need sponsor! | + +## Join the community - Meet us on Slack: https://phpopencloud.slack.com ([Get your invitation](https://launchpass.com/phpopencloud)) - Report an issue: https://github.com/php-opencloud/openstack/issues - ## Version Guidance -| Version | Status | PHP Version | End of life | +| Version | Status | PHP Version | Support until | | --------- | --------------------------- | ------------- | ----------------------- | -| `^3.0` | Latest | `>=7.0` | March 2020 | -| `^2.0` | Maintained (Bug fixes only) | `>=7.0,<7.2` | March 2018 | +| `^3.1` | Latest | `>=7.2.5` | Oct 2023 | +| `^3.0` | Bug fixed only | `>=7.0` | Oct 2020 | +| `^2.0` | EOL (Bug fixes only) | `>=7.0,<7.2` | March 2018 | + ## Upgrade from 2.x to 3.x diff --git a/php-opencloud/openstack/composer.json b/php-opencloud/openstack/composer.json index b38a5f791..f2a8d9c32 100644 --- a/php-opencloud/openstack/composer.json +++ b/php-opencloud/openstack/composer.json @@ -33,8 +33,9 @@ } }, "require": { - "php": "~7.0", - "guzzlehttp/guzzle": "^6.1", + "php": "^7.2.5", + "guzzlehttp/guzzle": "^7.0", + "guzzlehttp/uri-template": "0.2", "justinrainbow/json-schema": "^5.2" }, "require-dev": { diff --git a/php-opencloud/openstack/phpunit.xml.dist b/php-opencloud/openstack/phpunit.xml.dist index 032b639b4..05ba70a11 100644 --- a/php-opencloud/openstack/phpunit.xml.dist +++ b/php-opencloud/openstack/phpunit.xml.dist @@ -8,7 +8,11 @@ tests/unit - + + + + + ./src @@ -19,5 +23,4 @@ - \ No newline at end of file diff --git a/php-opencloud/openstack/src/Common/Api/OperatorTrait.php b/php-opencloud/openstack/src/Common/Api/OperatorTrait.php index ccbe34ab0..4e796d0a1 100644 --- a/php-opencloud/openstack/src/Common/Api/OperatorTrait.php +++ b/php-opencloud/openstack/src/Common/Api/OperatorTrait.php @@ -7,9 +7,9 @@ use GuzzleHttp\ClientInterface; use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\PromiseInterface; -use function GuzzleHttp\uri_template; use OpenStack\Common\Resource\ResourceInterface; use OpenStack\Common\Transport\RequestSerializer; +use OpenStack\Common\Transport\Utils; use Psr\Http\Message\ResponseInterface; trait OperatorTrait @@ -109,7 +109,8 @@ protected function sendRequest(Operation $operation, array $userValues = [], boo $options = (new RequestSerializer())->serializeOptions($operation, $userValues); $method = $async ? 'requestAsync' : 'request'; - $uri = uri_template($operation->getPath(), $userValues); + + $uri = Utils::uri_template($operation->getPath(), $userValues); return $this->client->$method($operation->getMethod(), $uri, $options); } diff --git a/php-opencloud/openstack/src/Common/Transport/HandlerStack.php b/php-opencloud/openstack/src/Common/Transport/HandlerStack.php index fee59d010..d0205d58d 100644 --- a/php-opencloud/openstack/src/Common/Transport/HandlerStack.php +++ b/php-opencloud/openstack/src/Common/Transport/HandlerStack.php @@ -4,17 +4,16 @@ namespace OpenStack\Common\Transport; -use function GuzzleHttp\choose_handler; use GuzzleHttp\HandlerStack as GuzzleStack; +use GuzzleHttp\Utils; class HandlerStack extends GuzzleStack { - public static function create(callable $handler = null): self + public static function create(?callable $handler = null): GuzzleStack { - $stack = new self($handler ?: choose_handler()); - - $stack->push(Middleware::httpErrors()); - $stack->push(Middleware::prepareBody()); + $stack = new self($handler ?: Utils::chooseHandler()); + $stack->push(Middleware::httpErrors(), 'http_errors'); + $stack->push(Middleware::prepareBody(), 'prepare_body'); return $stack; } diff --git a/php-opencloud/openstack/src/Common/Transport/Utils.php b/php-opencloud/openstack/src/Common/Transport/Utils.php index 3b5a26811..35ae5842a 100644 --- a/php-opencloud/openstack/src/Common/Transport/Utils.php +++ b/php-opencloud/openstack/src/Common/Transport/Utils.php @@ -4,7 +4,8 @@ namespace OpenStack\Common\Transport; -use function GuzzleHttp\Psr7\uri_for; +use GuzzleHttp\Psr7\Utils as GuzzleUtils; +use GuzzleHttp\UriTemplate\UriTemplate; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; @@ -73,11 +74,28 @@ public static function normalizeUrl(string $url): string */ public static function addPaths(UriInterface $uri, ...$paths): UriInterface { - return uri_for(rtrim((string) $uri, '/').'/'.implode('/', $paths)); + return GuzzleUtils::uriFor(rtrim((string) $uri, '/').'/'.implode('/', $paths)); } public static function appendPath(UriInterface $uri, $path): UriInterface { - return uri_for(rtrim((string) $uri, '/').'/'.$path); + return GuzzleUtils::uriFor(rtrim((string) $uri, '/').'/'.$path); + } + + /** + * Expands a URI template. + * + * @param string $template URI template + * @param array $variables Template variables + */ + public static function uri_template($template, array $variables): string + { + if (extension_loaded('uri_template')) { + // @codeCoverageIgnoreStart + return \uri_template($template, $variables); + // @codeCoverageIgnoreEnd + } + + return UriTemplate::expand($template, $variables); } } diff --git a/php-opencloud/openstack/src/Compute/v2/Params.php b/php-opencloud/openstack/src/Compute/v2/Params.php index e61ae3adc..b8a8b73ee 100644 --- a/php-opencloud/openstack/src/Compute/v2/Params.php +++ b/php-opencloud/openstack/src/Compute/v2/Params.php @@ -356,6 +356,11 @@ public function blockDeviceMapping(): array 'sentAs' => 'volume_size', 'description' => 'Size of the volume created if we are doing vol creation', ], + 'volumeType' => [ + 'type' => self::STRING_TYPE, + 'sentAs' => 'volume_type', + 'description' => 'The type of volume which the compute service will create and attach to the server.', + ], ], ], ]; diff --git a/php-opencloud/openstack/src/Images/v2/Params.php b/php-opencloud/openstack/src/Images/v2/Params.php index 94a7c9c61..4b8c31fd4 100644 --- a/php-opencloud/openstack/src/Images/v2/Params.php +++ b/php-opencloud/openstack/src/Images/v2/Params.php @@ -24,7 +24,7 @@ public function visibility(): array 'location' => self::JSON, 'type' => self::STRING_TYPE, 'description' => 'Image visibility. Public or private. Default is public.', - 'enum' => ['private', 'public'], + 'enum' => ['private', 'public', 'community', 'shared'], ]; } @@ -196,10 +196,10 @@ public function data(): array public function memberId(): array { return [ - 'location' => self::JSON, - 'sentAs' => 'member', - 'type' => self::STRING_TYPE, - 'documeted' => false, + 'location' => self::JSON, + 'sentAs' => 'member', + 'type' => self::STRING_TYPE, + 'documented' => false, ]; } diff --git a/php-opencloud/openstack/src/Metric/v1/Gnocchi/Models/Resource.php b/php-opencloud/openstack/src/Metric/v1/Gnocchi/Models/Resource.php index e106ec107..33c39d89a 100644 --- a/php-opencloud/openstack/src/Metric/v1/Gnocchi/Models/Resource.php +++ b/php-opencloud/openstack/src/Metric/v1/Gnocchi/Models/Resource.php @@ -6,6 +6,7 @@ use OpenStack\Common\Resource\OperatorResource; use OpenStack\Common\Resource\Retrievable; +use OpenStack\Common\Transport\Utils; use OpenStack\Metric\v1\Gnocchi\Api; /** @@ -132,7 +133,7 @@ public function getMetricMeasures(array $options = []): array $response = $this->execute($this->api->getResourceMetricMeasures(), $options); - return \GuzzleHttp\json_decode($response->getBody()); + return Utils::jsonDecode($response); } /** diff --git a/php-opencloud/openstack/src/OpenStack.php b/php-opencloud/openstack/src/OpenStack.php index ac4944840..3da8700f6 100644 --- a/php-opencloud/openstack/src/OpenStack.php +++ b/php-opencloud/openstack/src/OpenStack.php @@ -5,9 +5,9 @@ namespace OpenStack; use GuzzleHttp\Client; -use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware as GuzzleMiddleware; use OpenStack\Common\Service\Builder; +use OpenStack\Common\Transport\HandlerStack; use OpenStack\Common\Transport\Utils; use OpenStack\Identity\v3\Service; @@ -56,7 +56,8 @@ private function getDefaultIdentityService(array $options): Service && !empty($options['logger']) && !empty($options['messageFormatter']) ) { - $stack->push(GuzzleMiddleware::log($options['logger'], $options['messageFormatter'])); + $logMiddleware = GuzzleMiddleware::log($options['logger'], $options['messageFormatter']); + $stack->push($logMiddleware, 'logger'); } $clientOptions = [