diff --git a/composer.lock b/composer.lock index e99a1b9f25366ff96c6266e4a527cc30ddaac5e3..3f8c373dd424849f82a22f52aaa127d72fb55df0 100644 --- a/composer.lock +++ b/composer.lock @@ -459,21 +459,21 @@ }, { "name": "guzzlehttp/guzzle", - "version": "4.1.0", + "version": "4.1.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "85a0ba7de064493c928a8bcdc5eef01e0bde9953" + "reference": "012b2aecbda4e38f119c19580898685851015fa7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/85a0ba7de064493c928a8bcdc5eef01e0bde9953", - "reference": "85a0ba7de064493c928a8bcdc5eef01e0bde9953", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/012b2aecbda4e38f119c19580898685851015fa7", + "reference": "012b2aecbda4e38f119c19580898685851015fa7", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/streams": "~1.0", + "guzzlehttp/streams": "~1.3", "php": ">=5.4.0" }, "require-dev": { @@ -487,7 +487,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "4.1.x-dev" } }, "autoload": { @@ -520,32 +520,32 @@ "rest", "web service" ], - "time": "2014-05-28 05:13:19" + "time": "2014-07-16 03:01:02" }, { "name": "guzzlehttp/streams", - "version": "1.0.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/streams.git", - "reference": "d249beffe5fa5e0da3855974bcc2dd9082069ccf" + "reference": "d6aaa91cfdbae86355dd2a168a3ca536755898a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/streams/zipball/d249beffe5fa5e0da3855974bcc2dd9082069ccf", - "reference": "d249beffe5fa5e0da3855974bcc2dd9082069ccf", + "url": "https://api.github.com/repos/guzzle/streams/zipball/d6aaa91cfdbae86355dd2a168a3ca536755898a2", + "reference": "d6aaa91cfdbae86355dd2a168a3ca536755898a2", "shasum": "" }, "require": { "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "4.*" + "phpunit/phpunit": "~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -573,7 +573,7 @@ "Guzzle", "stream" ], - "time": "2014-03-25 18:31:28" + "time": "2014-07-15 22:02:02" }, { "name": "kriswallsmith/assetic", @@ -2393,12 +2393,8 @@ "time": "2013-06-12 19:46:58" } ], - "packages-dev": [ - - ], - "aliases": [ - - ], + "packages-dev": [], + "aliases": [], "minimum-stability": "stable", "stability-flags": { "symfony/yaml": 20, @@ -2411,7 +2407,5 @@ "platform": { "php": ">=5.4.2" }, - "platform-dev": [ - - ] + "platform-dev": [] } diff --git a/core/vendor/composer/ClassLoader.php b/core/vendor/composer/ClassLoader.php index a7105553143a422546083f2bb49dd6a79a280a6a..88684c52657173a7b2f321351c169ca0e08972a4 100644 --- a/core/vendor/composer/ClassLoader.php +++ b/core/vendor/composer/ClassLoader.php @@ -202,10 +202,11 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories */ - public function setPsr4($prefix, $paths) { + public function setPsr4($prefix, $paths) + { if (!$prefix) { $this->fallbackDirsPsr4 = (array) $paths; } else { diff --git a/core/vendor/composer/autoload_real.php b/core/vendor/composer/autoload_real.php index 0ecdb36774e7d47ab993702dd89f365e3dad9ddd..f41b172e74af44e066c6f057fae6c77749670fc4 100644 --- a/core/vendor/composer/autoload_real.php +++ b/core/vendor/composer/autoload_real.php @@ -23,9 +23,6 @@ public static function getLoader() self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInitDrupal8', 'loadClassLoader')); - $vendorDir = dirname(__DIR__); - $baseDir = dirname(dirname($vendorDir)); - $includePaths = require __DIR__ . '/include_paths.php'; array_push($includePaths, get_include_path()); set_include_path(join(PATH_SEPARATOR, $includePaths)); diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json index c49881ac4b81043ead8f57ada5bae0ba97bae12f..788f50c6614bee55cfb208c399c3ab2ab27c8666 100644 --- a/core/vendor/composer/installed.json +++ b/core/vendor/composer/installed.json @@ -1623,61 +1623,6 @@ "description": "Symfony Yaml Component", "homepage": "http://symfony.com" }, - { - "name": "guzzlehttp/streams", - "version": "1.0.0", - "version_normalized": "1.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/streams.git", - "reference": "d249beffe5fa5e0da3855974bcc2dd9082069ccf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/streams/zipball/d249beffe5fa5e0da3855974bcc2dd9082069ccf", - "reference": "d249beffe5fa5e0da3855974bcc2dd9082069ccf", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "time": "2014-03-25 18:31:28", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Stream\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Provides a simple abstraction over streams of data (Guzzle 4+)", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "Guzzle", - "stream" - ] - }, { "name": "symfony/css-selector", "version": "v2.4.4", @@ -1733,73 +1678,6 @@ "description": "Symfony CssSelector Component", "homepage": "http://symfony.com" }, - { - "name": "guzzlehttp/guzzle", - "version": "4.1.0", - "version_normalized": "4.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "85a0ba7de064493c928a8bcdc5eef01e0bde9953" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/85a0ba7de064493c928a8bcdc5eef01e0bde9953", - "reference": "85a0ba7de064493c928a8bcdc5eef01e0bde9953", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/streams": "~1.0", - "php": ">=5.4.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0", - "psr/log": "~1.0" - }, - "suggest": { - "ext-curl": "Guzzle will use specific adapters if cURL is present" - }, - "time": "2014-05-28 05:13:19", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ] - }, { "name": "sebastian/version", "version": "1.0.3", @@ -2470,5 +2348,127 @@ "mock", "xunit" ] + }, + { + "name": "guzzlehttp/streams", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "d6aaa91cfdbae86355dd2a168a3ca536755898a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/d6aaa91cfdbae86355dd2a168a3ca536755898a2", + "reference": "d6aaa91cfdbae86355dd2a168a3ca536755898a2", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2014-07-15 22:02:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data (Guzzle 4+)", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ] + }, + { + "name": "guzzlehttp/guzzle", + "version": "4.1.3", + "version_normalized": "4.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "012b2aecbda4e38f119c19580898685851015fa7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/012b2aecbda4e38f119c19580898685851015fa7", + "reference": "012b2aecbda4e38f119c19580898685851015fa7", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/streams": "~1.3", + "php": ">=5.4.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0", + "psr/log": "~1.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "time": "2014-07-16 03:01:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ] } ] diff --git a/core/vendor/guzzlehttp/guzzle/CHANGELOG.md b/core/vendor/guzzlehttp/guzzle/CHANGELOG.md index c75b518dd458c5ae7ba309d9de397e2f5100e6f3..127335c043bf5eb25d4bb33fe682694ba41f80f9 100644 --- a/core/vendor/guzzlehttp/guzzle/CHANGELOG.md +++ b/core/vendor/guzzlehttp/guzzle/CHANGELOG.md @@ -1,6 +1,33 @@ CHANGELOG ========= +4.1.3 (2014-07-15) +------------------ + +* Various fixes to multipart/form-data POST uploads +* Wrapping function.php in an if-statement to ensure Guzzle can be used + globally and in a Composer install +* Fixed an issue with generating and merging in events to an event array +* POST headers are only applied before sending a request to allow you to change + the query aggregator used before uploading +* Added much more robust query string parsing +* Fixed various parsing and normalization issues with URLs +* Fixing an issue where multi-valued headers were not being utilized correctly + in the StreamAdapter + +4.1.2 (2014-06-18) +------------------ + +* Added support for sending payloads with GET requests + +4.1.1 (2014-06-08) +------------------ + +* Fixed an issue related to using custom message factory options in subclasses +* Fixed an issue with nested form fields in a multi-part POST +* Fixed an issue with using the `json` request option for POST requests +* Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar` + 4.1.0 (2014-05-27) ------------------ diff --git a/core/vendor/guzzlehttp/guzzle/composer.json b/core/vendor/guzzlehttp/guzzle/composer.json index 1059a8237ae7b445dd5d40a010b8b544a18f1e61..fc37c050a381dfcf20b3b50286d53d776f880237 100644 --- a/core/vendor/guzzlehttp/guzzle/composer.json +++ b/core/vendor/guzzlehttp/guzzle/composer.json @@ -17,7 +17,7 @@ "require": { "php": ">=5.4.0", "ext-json": "*", - "guzzlehttp/streams": "~1.0" + "guzzlehttp/streams": "~1.3" }, "suggest": { @@ -30,7 +30,11 @@ }, "files": ["src/functions.php"] }, - + "autoload-dev": { + "psr-4": { + "GuzzleHttp\\Tests\\": "tests/" + } + }, "require-dev": { "ext-curl": "*", "psr/log": "~1.0", @@ -39,7 +43,7 @@ "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "4.1.x-dev" } } } diff --git a/core/vendor/guzzlehttp/guzzle/docs/_static/logo.png b/core/vendor/guzzlehttp/guzzle/docs/_static/logo.png index ecc40ac76040183ec01ef3d7c0546a82a4324589..965a4ef4139180ea7d33594feba2394dfce6774a 100644 --- a/core/vendor/guzzlehttp/guzzle/docs/_static/logo.png +++ b/core/vendor/guzzlehttp/guzzle/docs/_static/logo.png @@ -1,9 +1,6 @@ ‰PNG -��� IHDR��_��»���d`–��$iCCPICC Profile��8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH<! b{ÙöÀ´IS‡*ªIH{èÄ!&íUá»vb'SÄ\õúË9ß9ç;ç^ÛD=_iµšUˆ–«®Ï$•“§”žMŠÒ³ÔKÔ«éN-‘ËÍ.Á÷ÎëáŠËí‘îþNö#¿z‹Üщ"OÀn}øQÌÔk¶K¿ûøi·ÜóðÓ6«—}œxÑÇ'=N!? ŽÐ*ë¼<¼Øf/·a_È“áUnº"f‘³’arÏá/q·1ÿ.›uôì]ƒXûœ¥¹c¸‰Þ+öT¾‰?×µôðK°_¯¹IaøúÒ|xQô©’}tÞçG__ÞÞ{Ñp§Mûju1{±Ñõ%ë˜È#8×ug³¤€ïVø´Øc葨ÈSiàaàÁJ}ª™_šqVæ„Ý˳Z™Ì#d¿§Í䀀?´¼¨ÍÒ:73¢òKWkn®©AÚ®šYQý2™;^È)m»•Â”˺v¡ËJÆÑé&fzgÚØ»žÚŸÝÒìtyØ?¼:/æÛ]ÔRb¶£ÀGèDD#N-bÕ©J;¤Pž2”ĽF6<%2È„…ÃËa1"OÒlÝy9ãÇ„Œ²½-¢Q¥;ǯp¿É±X?SÙüb³ì0g¤°7Ø›ìKÁ:Á -rm:*Ó}(õó¼OuT:NPòü@}(ˆQÎÙïúÍþ†š°K+ô#OÐ14[í hu7Ò>§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nƶÂøد±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍý½t -³jMµ{-ñ4%×ÆTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô -t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝmî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Y�qxl+��� pHYs����gŸÒR��@�IDATxì½€]Uµ7¾÷>íö2s§Ï$“ɤM +��� IHDR��_��»���d`–��� pHYs����gŸÒR��@�IDATxì½€]Uµ7¾÷>íö2s§Ï$“ɤM „@Ê„ÞÅ’ ¢O,iÖ‡íð=}ŸÑÇC‘' úP$**¡’F™´Éô™;õÎí÷ôýÿIf˜ðó#$AïÑpï{Î.뜻öÚkýÖoQÎ9Éy ä%—@^§Wìôv—ï-/¼òÈKÀ‘@^ù柃¼òÈKàH ¯|Ï€Ðó]æ%—@^yå›òÈK /3 ¼ò=BÏw™—@^y ä•oþÈK /¼Î€òÊ÷=ße^y ä%W¾ùg /¼ò8È+ß3 ô|—y ä%—@^ù柼òÈKàH ¯|Ï€Ðó]æ%—@^yå›òÈK /3 ¼ò=BÏw™—@^y ä•ïßñlêìtoß¾]ú;.ÉŸš—@^y œTïJå»*õ`6‚3#G®<òž½Òž¯Šªãhì,¸ï¾ûNÉÜžo"JC¿okiÆt_®UL›½²±Q>©4OÁÄÍM±ÀóMMÊ)hîm5áÈuCthÜöæ¡àÉrÆy²¿ÿ¿îíõ:rý[çå¿ÏKàYôÝÆçûLSlzÌЯñ‰•¥ÁB5IåK$šÛÉu¦š„\dR«¿WãSÊûãkSJÚVbŸìnϪGîSW¬X1ò½£¬í=PಠN”9aðrÕÌz¼Š`Sª„ãº6U Bgˆþ4«„dNÖîßó7G‰«ü!ÉY„‹”2cU–NW¹*Ûçbü=mžìÜ5mñ9œ™½—UE¢øþ¤ÎŸÆ"¶,\㪠§—ŒÇ†öØt&‰UÜÃ¥ÔÔ8—Çj³‚Ë’·¤jz†û¼„‘åq¡aAÅr"S.*õ@¸%o:Ê™ÈffM:×6×¥ ‘çê;ç³óïòøÇ–€ønšÞʦž"ŸìZNmºœH…›M‰ôˆ¦ye µ™¾‹bj#¥óê¬M6‘ÒAê(ß•+W diff --git a/core/vendor/guzzlehttp/guzzle/docs/clients.rst b/core/vendor/guzzlehttp/guzzle/docs/clients.rst index bd5f9168d7ad100a576ee2f84f8df821079bc721..9790af04f1884300339cd0f5300e28dc992b2580 100644 --- a/core/vendor/guzzlehttp/guzzle/docs/clients.rst +++ b/core/vendor/guzzlehttp/guzzle/docs/clients.rst @@ -70,7 +70,7 @@ base URL that is a URI template with parameters. use GuzzleHttp\Client; $client = new Client([ - 'base_url' => ['https://api.twitter.com/{version}', ['version' => 'v1.1']], + 'base_url' => ['https://api.twitter.com/{version}/', ['version' => 'v1.1']], 'defaults' => [ 'headers' => ['Foo' => 'Bar'], 'query' => ['testing' => '123'], @@ -203,7 +203,7 @@ The ``sendAll()`` method accepts the following associative array of options: The "before", "complete", and "error" event options accept a callable or an array of associative arrays where each associative array contains a "fn" key with a callable value, an optional "priority" key representing the event -priority (with a default value is 0), and an optional "once" key that can be +priority (with a default value of 0), and an optional "once" key that can be set to true so that the event listener will be removed from the request after it is first triggered. @@ -289,7 +289,7 @@ Throwing Errors Immediately ~~~~~~~~~~~~~~~~~~~~~~~~~~~ It sometimes is useful to throw exceptions immediately when the occur. The -following exmaple shows how to use an event listener to throw exceptions +following example shows how to use an event listener to throw exceptions immeditaley and prevent subsequent requests from being sent. .. code-block:: php @@ -308,7 +308,7 @@ Batching Requests ----------------- Sometimes you just want to send a few requests in parallel and then process -the results all at once after they've sent. Guzzle provides a convenience +the results all at once after they've been sent. Guzzle provides a convenience function ``GuzzleHttp\batch()`` that makes this very simple: .. code-block:: php @@ -339,7 +339,7 @@ function ``GuzzleHttp\batch()`` that makes this very simple: ``GuzzleHttp\batch()`` accepts an optional associative array of options in the third argument that allows you to specify the 'before', 'complete' and 'error' -events as well as specify the maximum number of request to send in parallel +events as well as specify the maximum number of requests to send in parallel using the 'parallel' option key. This options array is the exact same format as the options array exposed in ``GuzzleHttp\ClientInterface::sendAll()``. @@ -699,7 +699,7 @@ to an open Guzzle stream: events ------ -:Summary: Associative array mapping event names to a callable. or an +:Summary: An associative array mapping event names to a callable. Or an associative array containing the 'fn' key that maps to a callable, an optional 'priority' key used to specify the event priority, and an optional 'once' key used to specify if the event should remove itself the first time @@ -896,7 +896,7 @@ Pass a string to specify a proxy for all protocols. .. code-block:: php - $client->get('/', ['proxy' => 'tcp://localhost:8124']); + $client->get('/', ['proxy' => 'tcp://localhost:8125']); Pass an associative array to specify HTTP proxies for specific URI schemes (i.e., "http", "https"). @@ -905,7 +905,7 @@ Pass an associative array to specify HTTP proxies for specific URI schemes $client->get('/', [ 'proxy' => [ - 'http' => 'tcp://localhost:8124', // Use this proxy with "http" + 'http' => 'tcp://localhost:8125', // Use this proxy with "http" 'https' => 'tcp://localhost:9124' // Use this proxy with "https" ] ]); @@ -1103,7 +1103,7 @@ behavior of the library. ``HTTP_PROXY`` Defines the proxy to use when sending requests using the "http" protocol. ``HTTPS_PROXY`` - Defines the proxy to use when sending requests using the "https": protocol. + Defines the proxy to use when sending requests using the "https" protocol. Relevant ini Settings --------------------- diff --git a/core/vendor/guzzlehttp/guzzle/docs/quickstart.rst b/core/vendor/guzzlehttp/guzzle/docs/quickstart.rst index b32d050ed64ecc7dc6c4da6b40a8060d51c394b1..41f2c7bacf3bf6ebb633a75a4ef743f73d9fb377 100644 --- a/core/vendor/guzzlehttp/guzzle/docs/quickstart.rst +++ b/core/vendor/guzzlehttp/guzzle/docs/quickstart.rst @@ -18,7 +18,7 @@ easily test the client. Procedural API -------------- -Here's an example of sending a ``GET`` request using the procedural API. +Here's an example of sending a ``POST`` request using the procedural API. .. code-block:: php @@ -377,7 +377,7 @@ Guzzle can maintain a cookie session for you if instructed using the - Set to ``true`` to use a shared cookie session associated with the client. - Pass an associative array containing cookies to send in the request and start a new cookie session. -- Set to a ``GuzzleHttp\Subscriber\CookieJar\CookieJarInterface`` object to uss +- Set to a ``GuzzleHttp\Subscriber\CookieJar\CookieJarInterface`` object to use an existing cookie jar. Redirects @@ -437,7 +437,7 @@ Guzzle throws exceptions for errors that occur during a transfer. } } -- A ``GuzzleHttp\Exception\ClientErrorResponseException`` is thrown for 400 +- A ``GuzzleHttp\Exception\ClientException`` is thrown for 400 level errors if the ``exceptions`` request option is set to true. This exception extends from ``GuzzleHttp\Exception\BadResponseException`` and ``GuzzleHttp\Exception\BadResponseException`` extends from @@ -445,16 +445,16 @@ Guzzle throws exceptions for errors that occur during a transfer. .. code-block:: php - use GuzzleHttp\Exception\ClientErrorResponseException; + use GuzzleHttp\Exception\ClientException; try { $client->get('https://github.com/_abc_123_404'); - } catch (ClientErrorResponseException $e) { + } catch (ClientException $e) { echo $e->getRequest(); echo $e->getResponse(); } -- A ``GuzzleHttp\Exception\ServerErrorResponse`` is thrown for 500 level +- A ``GuzzleHttp\Exception\ServerException`` is thrown for 500 level errors if the ``exceptions`` request option is set to true. This exception extends from ``GuzzleHttp\Exception\BadResponseException``. - A ``GuzzleHttp\Exception\TooManyRedirectsException`` is thrown when too diff --git a/core/vendor/guzzlehttp/guzzle/docs/testing.rst b/core/vendor/guzzlehttp/guzzle/docs/testing.rst index b65f066a89f152be49aa8ab9dbe22912a0933174..55015ab5b30b93c1b48287470d8a3d78ebacd53d 100644 --- a/core/vendor/guzzlehttp/guzzle/docs/testing.rst +++ b/core/vendor/guzzlehttp/guzzle/docs/testing.rst @@ -173,16 +173,12 @@ Guzzle ships with a node.js test server that receives requests and returns responses from a queue. The test server exposes a simple API that is used to enqueue responses and inspect the requests that it has received. -In order to use the web server, you'll need to manually require -``tests/Server.php``. Any operation on the ``Server`` object will ensure that +Any operation on the ``Server`` object will ensure that the server is running and wait until it is able to receive requests before returning. .. code-block:: php - // Require the test server (using something like this). - require __DIR__ . '/../vendor/guzzlehttp/guzzle/tests/Server.php'; - use GuzzleHttp\Client; use GuzzleHttp\Tests\Server; diff --git a/core/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlFactory.php b/core/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlFactory.php index 0af3d7566e581abd21a6a887148c775c33ab518e..f1cb393a770a88238137ee1b19ccadb0ffc34970 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlFactory.php +++ b/core/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlFactory.php @@ -97,10 +97,7 @@ protected function getDefaultOptions( private function applyMethod(RequestInterface $request, array &$options) { $method = $request->getMethod(); - if ($method == 'GET') { - $options[CURLOPT_HTTPGET] = true; - unset($options[CURLOPT_READFUNCTION]); - } elseif ($method == 'HEAD') { + if ($method == 'HEAD') { $options[CURLOPT_NOBODY] = true; unset($options[CURLOPT_WRITEFUNCTION], $options[CURLOPT_READFUNCTION]); } else { diff --git a/core/vendor/guzzlehttp/guzzle/src/Adapter/StreamAdapter.php b/core/vendor/guzzlehttp/guzzle/src/Adapter/StreamAdapter.php index a40f587b06b448cafc6ae94c511708fecc2bbff6..79aa0b99ac789457c7b22eaee13dee9fe304bb9b 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Adapter/StreamAdapter.php +++ b/core/vendor/guzzlehttp/guzzle/src/Adapter/StreamAdapter.php @@ -100,18 +100,9 @@ private function createResponseObject( $options['reason_phrase'] = $parts[2]; } - // Set the size on the stream if it was returned in the response - $responseHeaders = []; - foreach ($headers as $header) { - $headerParts = explode(':', $header, 2); - $responseHeaders[$headerParts[0]] = isset($headerParts[1]) - ? $headerParts[1] - : ''; - } - $response = $this->messageFactory->createResponse( $parts[1], - $responseHeaders, + $this->headersFromLines($headers), $stream, $options ); @@ -122,6 +113,20 @@ private function createResponseObject( return $response; } + private function headersFromLines(array $lines) + { + $responseHeaders = []; + + foreach ($lines as $line) { + $headerParts = explode(':', $line, 2); + $responseHeaders[$headerParts[0]][] = isset($headerParts[1]) + ? trim($headerParts[1]) + : ''; + } + + return $responseHeaders; + } + /** * Create a resource and check to ensure it was created successfully * diff --git a/core/vendor/guzzlehttp/guzzle/src/ClientInterface.php b/core/vendor/guzzlehttp/guzzle/src/ClientInterface.php index c6e54994631e90dadaddbba7b35683eec5de3991..a10d67f175c44dcbfbb4810b100ef465d2e198e2 100644 --- a/core/vendor/guzzlehttp/guzzle/src/ClientInterface.php +++ b/core/vendor/guzzlehttp/guzzle/src/ClientInterface.php @@ -13,7 +13,7 @@ */ interface ClientInterface extends HasEmitterInterface { - const VERSION = '4.1.0'; + const VERSION = '4.1.3'; /** * Create and return a new {@see RequestInterface} object. diff --git a/core/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/core/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php index 1b526fb9c542d32c19fb9b29b33db168c16586e0..4134857827c5f00aff84f7136b1e5129feaf4cc8 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ b/core/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -4,11 +4,12 @@ use GuzzleHttp\Message\RequestInterface; use GuzzleHttp\Message\ResponseInterface; +use GuzzleHttp\ToArrayInterface; /** * Cookie jar that stores cookies an an array */ -class CookieJar implements CookieJarInterface +class CookieJar implements CookieJarInterface, ToArrayInterface { /** @var SetCookie[] Loaded cookie data */ private $cookies = []; @@ -17,12 +18,21 @@ class CookieJar implements CookieJarInterface private $strictMode; /** - * @param bool $strictMode Set to true to throw exceptions when invalid - * cookies are added to the cookie jar. + * @param bool $strictMode Set to true to throw exceptions when invalid + * cookies are added to the cookie jar. + * @param array $cookieArray Array of SetCookie objects or a hash of arrays + * that can be used with the SetCookie constructor */ - public function __construct($strictMode = false) + public function __construct($strictMode = false, $cookieArray = []) { $this->strictMode = $strictMode; + + foreach ($cookieArray as $cookie) { + if (!($cookieArray instanceof SetCookie)) { + $cookie = new SetCookie($cookie); + } + $this->setCookie($cookie); + } } /** @@ -68,6 +78,13 @@ public static function getCookieValue($value) return $value; } + public function toArray() + { + return array_map(function (SetCookie $cookie) { + return $cookie->toArray(); + }, $this->getIterator()->getArrayCopy()); + } + public function clear($domain = null, $path = null, $name = null) { if (!$domain) { diff --git a/core/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php b/core/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php index 252c0af9b430cd84ebd8c1b7e0271bd943590a49..12e6ba28e6660b21117024cc1187d23065fbf204 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php +++ b/core/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php @@ -127,4 +127,40 @@ public static function emitError( throw $e; } } + + /** + * Converts an array of event options into a formatted array of valid event + * configuration. + * + * @param array $options Event array to convert + * @param array $events Event names to convert in the options array. + * @param mixed $handler Event handler to utilize + * + * @return array + * @throws \InvalidArgumentException if the event config is invalid + * @internal + */ + public static function convertEventArray( + array $options, + array $events, + $handler + ) { + foreach ($events as $name) { + if (!isset($options[$name])) { + $options[$name] = [$handler]; + } elseif (is_callable($options[$name])) { + $options[$name] = [$options[$name], $handler]; + } elseif (is_array($options[$name])) { + if (isset($options[$name]['fn'])) { + $options[$name] = [$options[$name], $handler]; + } else { + $options[$name][] = $handler; + } + } else { + throw new \InvalidArgumentException('Invalid event format'); + } + } + + return $options; + } } diff --git a/core/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php b/core/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php index e024fd3a039ec166be2d3d8b273e21ae03bbcb38..280053b8bdc17e42e7ec5319d6cbc18a89c2751f 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php +++ b/core/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php @@ -28,6 +28,9 @@ class MessageFactory implements MessageFactoryInterface /** @var Redirect */ private $redirectPlugin; + /** @var array */ + protected static $classMethods = []; + public function __construct() { $this->errorPlugin = new HttpError(); @@ -62,7 +65,10 @@ public function createRequest($method, $url, array $options = []) unset($options['config']); // Use a POST body by default - if ($method == 'POST' && !isset($options['body'])) { + if ($method == 'POST' && + !isset($options['body']) && + !isset($options['json']) + ) { $options['body'] = []; } @@ -141,7 +147,6 @@ protected function addPostData(RequestInterface $request, array $body) } $request->setBody($post); - $post->applyRequestHeaders($request); } protected function applyOptions( @@ -152,11 +157,18 @@ protected function applyOptions( static $configMap = ['connect_timeout' => 1, 'timeout' => 1, 'verify' => 1, 'ssl_key' => 1, 'cert' => 1, 'proxy' => 1, 'debug' => 1, 'save_to' => 1, 'stream' => 1, 'expect' => 1]; - static $methods; - if (!$methods) { - $methods = array_flip(get_class_methods($this)); + + // Take the class of the instance, not the parent + $selfClass = get_class($this); + + // Check if we already took it's class methods and had them saved + if (!isset(self::$classMethods[$selfClass])) { + self::$classMethods[$selfClass] = array_flip(get_class_methods($this)); } + // Take class methods of this particular instance + $methods = self::$classMethods[$selfClass]; + // Iterate over each key value pair and attempt to apply a config using // double dispatch. $config = $request->getConfig(); diff --git a/core/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php b/core/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php index 72ce6e12c0fbede445105dc8d3353182a19803b1..7ffead9d6871ded434ec761284f736b02f0111c6 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php +++ b/core/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php @@ -10,15 +10,7 @@ class MultipartBody implements Stream\StreamInterface { /** @var Stream\StreamInterface */ - private $files; - private $fields; - private $size; - private $buffer; - private $bufferedHeaders = []; - private $pos = 0; - private $currentFile = 0; - private $currentField = 0; - private $sentLast; + private $stream; private $boundary; /** @@ -34,43 +26,17 @@ public function __construct( $boundary = null ) { $this->boundary = $boundary ?: uniqid(); - $this->fields = $fields; - $this->files = $files; - - // Ensure each file is a PostFileInterface - foreach ($this->files as $file) { - if (!$file instanceof PostFileInterface) { - throw new \InvalidArgumentException('All POST fields must ' - . 'implement PostFieldInterface'); - } - } + $this->createStream($fields, $files); } public function __toString() { - $this->seek(0); - - return $this->getContents(); + return (string) $this->stream; } public function getContents($maxLength = -1) { - $buffer = ''; - - while (!$this->eof()) { - if ($maxLength === -1) { - $read = 1048576; - } else { - $len = strlen($buffer); - if ($len == $maxLength) { - break; - } - $read = min(1048576, $maxLength - $len); - } - $buffer .= $this->read($read); - } - - return $buffer; + return $this->stream->getContents($maxLength); } /** @@ -85,28 +51,24 @@ public function getBoundary() public function close() { + $this->stream->close(); $this->detach(); } public function detach() { - $this->fields = $this->files = []; + $this->stream->detach(); + $this->size = 0; } - /** - * The stream has reached an EOF when all of the fields and files have been - * read. - * {@inheritdoc} - */ public function eof() { - return $this->currentField == count($this->fields) && - $this->currentFile == count($this->files); + return $this->stream->eof(); } public function tell() { - return $this->pos; + return $this->stream->tell(); } public function isReadable() @@ -119,77 +81,24 @@ public function isWritable() return false; } - /** - * The steam is seekable by default, but all attached files must be - * seekable too. - * {@inheritdoc} - */ public function isSeekable() { - foreach ($this->files as $file) { - if (!$file->getContent()->isSeekable()) { - return false; - } - } - - return true; + return $this->stream->isSeekable(); } public function getSize() { - if ($this->size === null) { - foreach ($this->files as $file) { - // We must be able to ascertain the size of each attached file - if (null === ($size = $file->getContent()->getSize())) { - return null; - } - $this->size += strlen($this->getFileHeaders($file)) + $size; - } - foreach (array_keys($this->fields) as $key) { - $this->size += strlen($this->getFieldString($key)); - } - $this->size += strlen("\r\n--{$this->boundary}--"); - } - - return $this->size; + return $this->stream->getSize(); } public function read($length) { - $content = ''; - if ($this->buffer && !$this->buffer->eof()) { - $content .= $this->buffer->read($length); - } - if ($delta = $length - strlen($content)) { - $content .= $this->readData($delta); - } - - if ($content === '' && !$this->sentLast) { - $this->sentLast = true; - $content = "\r\n--{$this->boundary}--"; - } - - return $content; + return $this->stream->read($length); } public function seek($offset, $whence = SEEK_SET) { - if ($offset != 0 || $whence != SEEK_SET || !$this->isSeekable()) { - return false; - } - - foreach ($this->files as $file) { - if (!$file->getContent()->seek(0)) { - throw new \RuntimeException('Rewind on multipart file failed ' - . 'even though it shouldn\'t have'); - } - } - - $this->buffer = $this->sentLast = null; - $this->pos = $this->currentField = $this->currentFile = 0; - $this->bufferedHeaders = []; - - return true; + return $this->stream->seek($offset, $whence); } public function write($string) @@ -198,95 +107,59 @@ public function write($string) } /** - * No data is in the read buffer, so more needs to be pulled in from fields - * and files. - * - * @param int $length Amount of data to read - * - * @return string + * Get the string needed to transfer a POST field */ - private function readData($length) + private function getFieldString($name, $value) { - $result = ''; - - if ($this->currentField < count($this->fields)) { - $result = $this->readField($length); - } - - if ($result === '' && $this->currentFile < count($this->files)) { - $result = $this->readFile($length); - } - - return $result; + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", + $this->boundary, + $name, + $value + ); } /** - * Create a new stream buffer and inject form-data - * - * @param int $length Amount of data to read from the stream buffer - * - * @return string + * Get the headers needed before transferring the content of a POST file */ - private function readField($length) + private function getFileHeaders(PostFileInterface $file) { - $name = array_keys($this->fields)[++$this->currentField - 1]; - $this->buffer = Stream\create($this->getFieldString($name)); + $headers = ''; + foreach ($file->getHeaders() as $key => $value) { + $headers .= "{$key}: {$value}\r\n"; + } - return $this->buffer->read($length); + return "--{$this->boundary}\r\n" . trim($headers) . "\r\n\r\n"; } /** - * Read data from a POST file, fill the read buffer with any overflow - * - * @param int $length Amount of data to read from the file - * - * @return string + * Create the aggregate stream that will be used to upload the POST data */ - private function readFile($length) + private function createStream(array $fields, array $files) { - $current = $this->files[$this->currentFile]; - - // Got to the next file and recursively return the read value, or bail - // if no more data can be read. - if ($current->getContent()->eof()) { - return ++$this->currentFile == count($this->files) - ? '' - : $this->readFile($length); - } + $this->stream = new Stream\AppendStream(); - // If this is the start of a file, then send the headers to the read - // buffer. - if (!isset($this->bufferedHeaders[$this->currentFile])) { - $this->buffer = Stream\create($this->getFileHeaders($current)); - $this->bufferedHeaders[$this->currentFile] = true; + foreach ($fields as $name => $field) { + $this->stream->addStream( + Stream\create($this->getFieldString($name, $field)) + ); } - // More data needs to be read to meet the limit, so pull from the file - $content = $this->buffer ? $this->buffer->read($length) : ''; - if (($remaining = $length - strlen($content)) > 0) { - $content .= $current->getContent()->read($remaining); - } + foreach ($files as $file) { - return $content; - } - - private function getFieldString($key) - { - return sprintf( - "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", - $this->boundary, - $key, - $this->fields[$key] - ); - } + if (!$file instanceof PostFileInterface) { + throw new \InvalidArgumentException('All POST fields must ' + . 'implement PostFieldInterface'); + } - private function getFileHeaders(PostFileInterface $file) - { - $headers = ''; - foreach ($file->getHeaders() as $key => $value) { - $headers .= "{$key}: {$value}\r\n"; + $this->stream->addStream( + Stream\create($this->getFileHeaders($file)) + ); + $this->stream->addStream($file->getContent()); + $this->stream->addStream(Stream\create("\r\n")); } - return "--{$this->boundary}\r\n" . trim($headers) . "\r\n\r\n"; + // Add the trailing boundary + $this->stream->addStream(Stream\create("--{$this->boundary}--")); } } diff --git a/core/vendor/guzzlehttp/guzzle/src/Post/PostBody.php b/core/vendor/guzzlehttp/guzzle/src/Post/PostBody.php index d6a2f3046f331fd2db13e0e9826db364601db703..78ed9e041f8111f9ba640f4bfb1e7280bce3d624 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Post/PostBody.php +++ b/core/vendor/guzzlehttp/guzzle/src/Post/PostBody.php @@ -252,15 +252,19 @@ final protected function getAggregator() */ private function createMultipart() { - $fields = $this->fields; - $query = (new Query()) - ->setEncodingType(false) - ->setAggregator($this->getAggregator()); - - // Account for fields with an array value - foreach ($fields as $name => &$field) { - if (is_array($field)) { - $field = (string) $query->replace([$name => $field]); + // Flatten the nested query string values using the correct aggregator + if (!$this->fields) { + $fields = []; + } else { + $query = (string) (new Query($this->fields)) + ->setEncodingType(false) + ->setAggregator($this->getAggregator()); + + // Convert the flattened query string back into an array + $fields = []; + foreach (explode('&', $query, 2) as $kvp) { + $parts = explode('=', $kvp, 2); + $fields[$parts[0]] = isset($parts[1]) ? $parts[1] : null; } } diff --git a/core/vendor/guzzlehttp/guzzle/src/Query.php b/core/vendor/guzzlehttp/guzzle/src/Query.php index 1cb7dcd0859e37ea37e6f0e2dbe44abd006e351e..72d81ee2af136c6138c2fef0f031fa646b773b7a 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Query.php +++ b/core/vendor/guzzlehttp/guzzle/src/Query.php @@ -19,46 +19,36 @@ class Query extends Collection /** * Parse a query string into a Query object * - * @param string $query Query string to parse + * $urlEncoding is used to control how the query string is parsed and how + * it is ultimately serialized. The value can be set to one of the + * following: * + * - true: (default) Parse query strings using RFC 3986 while still + * converting "+" to " ". + * - false: Disables URL decoding of the input string and URL encoding when + * the query string is serialized. + * - 'RFC3986': Use RFC 3986 URL encoding/decoding + * - 'RFC1738': Use RFC 1738 URL encoding/decoding + * + * @param string $query Query string to parse + * @param bool|string $urlEncoding Controls how the input string is decoded + * and encoded. * @return self */ - public static function fromString($query) + public static function fromString($query, $urlEncoding = true) { - $q = new static(); - if ($query === '') { - return $q; + static $qp; + if (!$qp) { + $qp = new QueryParser(); } - $foundDuplicates = $foundPhpStyle = false; + $q = new static(); - foreach (explode('&', $query) as $kvp) { - $parts = explode('=', $kvp, 2); - $key = rawurldecode($parts[0]); - if ($paramIsPhpStyleArray = substr($key, -2) == '[]') { - $foundPhpStyle = true; - $key = substr($key, 0, -2); - } - if (isset($parts[1])) { - $value = rawurldecode(str_replace('+', '%20', $parts[1])); - if (isset($q[$key])) { - $q->add($key, $value); - $foundDuplicates = true; - } elseif ($paramIsPhpStyleArray) { - $q[$key] = array($value); - } else { - $q[$key] = $value; - } - } else { - $q->add($key, null); - } + if ($urlEncoding !== true) { + $q->setEncodingType($urlEncoding); } - // Use the duplicate aggregator if duplicates were found and not using - // PHP style arrays. - if ($foundDuplicates && !$foundPhpStyle) { - $q->setAggregator(self::duplicateAggregator()); - } + $qp->parseInto($q, $query, $urlEncoding); return $q; } diff --git a/core/vendor/guzzlehttp/guzzle/src/QueryParser.php b/core/vendor/guzzlehttp/guzzle/src/QueryParser.php new file mode 100644 index 0000000000000000000000000000000000000000..90727cc6cf0ef93e99b5c4f935d18812845ffae0 --- /dev/null +++ b/core/vendor/guzzlehttp/guzzle/src/QueryParser.php @@ -0,0 +1,163 @@ +<?php +namespace GuzzleHttp; + +/** + * Parses query strings into a Query object. + * + * While parsing, the parser will attempt to determine the most appropriate + * query string aggregator to use when serializing the parsed query string + * object back into a string. The hope is that parsing then serializing a + * query string should be a lossless operation. + * + * @internal Use Query::fromString() + */ +class QueryParser +{ + private $duplicates; + private $numericIndices; + + /** + * Parse a query string into a Query object. + * + * @param Query $query Query object to populate + * @param string $str Query string to parse + * @param bool|string $urlEncoding How the query string is encoded + */ + public function parseInto(Query $query, $str, $urlEncoding = true) + { + if ($str === '') { + return; + } + + $result = []; + $this->duplicates = false; + $this->numericIndices = true; + $decoder = self::getDecoder($urlEncoding); + + foreach (explode('&', $str) as $kvp) { + + $parts = explode('=', $kvp, 2); + $key = $decoder($parts[0]); + $value = isset($parts[1]) ? $decoder($parts[1]) : null; + + // Special handling needs to be taken for PHP nested array syntax + if (strpos($key, '[') !== false) { + $this->parsePhpValue($key, $value, $result); + continue; + } + + if (!isset($result[$key])) { + $result[$key] = $value; + } else { + $this->duplicates = true; + if (!is_array($result[$key])) { + $result[$key] = [$result[$key]]; + } + $result[$key][] = $value; + } + } + + $query->replace($result); + + if (!$this->numericIndices) { + $query->setAggregator(Query::phpAggregator(false)); + } elseif ($this->duplicates) { + $query->setAggregator(Query::duplicateAggregator()); + } + } + + /** + * Returns a callable that is used to URL decode query keys and values. + * + * @param string|bool $type One of true, false, RFC3986, and RFC1738 + * + * @return callable|string + */ + private static function getDecoder($type) + { + if ($type === true) { + return function ($value) { + return rawurldecode(str_replace('+', ' ', $value)); + }; + } elseif ($type == Query::RFC3986) { + return 'rawurldecode'; + } elseif ($type == Query::RFC1738) { + return 'urldecode'; + } else { + return function ($str) { return $str; }; + } + } + + /** + * Parses a PHP style key value pair. + * + * @param string $key Key to parse (e.g., "foo[a][b]") + * @param string|null $value Value to set + * @param array $result Result to modify by reference + */ + private function parsePhpValue($key, $value, array &$result) + { + $node =& $result; + $keyBuffer = ''; + + for ($i = 0, $t = strlen($key); $i < $t; $i++) { + switch ($key[$i]) { + case '[': + if ($keyBuffer) { + $this->prepareNode($node, $keyBuffer); + $node =& $node[$keyBuffer]; + $keyBuffer = ''; + } + break; + case ']': + $k = $this->cleanKey($node, $keyBuffer); + $this->prepareNode($node, $k); + $node =& $node[$k]; + $keyBuffer = ''; + break; + default: + $keyBuffer .= $key[$i]; + break; + } + } + + if (isset($node)) { + $this->duplicates = true; + $node[] = $value; + } else { + $node = $value; + } + } + + /** + * Prepares a value in the array at the given key. + * + * If the key already exists, the key value is converted into an array. + * + * @param array $node Result node to modify + * @param string $key Key to add or modify in the node + */ + private function prepareNode(&$node, $key) + { + if (!isset($node[$key])) { + $node[$key] = null; + } elseif (!is_array($node[$key])) { + $node[$key] = [$node[$key]]; + } + } + + /** + * Returns the appropriate key based on the node and key. + */ + private function cleanKey($node, $key) + { + if ($key === '') { + $key = $node ? (string) count($node) : 0; + // Found a [] key, so track this to ensure that we disable numeric + // indexing of keys in the resolved query aggregator. + $this->numericIndices = false; + } + + return $key; + } +} diff --git a/core/vendor/guzzlehttp/guzzle/src/Url.php b/core/vendor/guzzlehttp/guzzle/src/Url.php index a305a768c5bf87ee1118ee045775be1d8f7156ac..23b765e7e22f49192d601eb9fda55da79b1ead1b 100644 --- a/core/vendor/guzzlehttp/guzzle/src/Url.php +++ b/core/vendor/guzzlehttp/guzzle/src/Url.php @@ -92,7 +92,7 @@ public static function buildUrl(array $parts) if (isset($parts['path']) && strlen($parts['path'])) { // Always ensure that the path begins with '/' if set and something // is before the path - if (isset($parts['host']) && $parts['path'][0] != '/') { + if (!empty($parts['host']) && $parts['path'][0] != '/') { $url .= '/'; } $url .= $parts['path']; @@ -306,7 +306,7 @@ public function setPath($path) public function removeDotSegments() { static $noopPaths = ['' => true, '/' => true, '*' => true]; - static $ignoreSegments = ['' => true, '.' => true, '..' => true]; + static $ignoreSegments = ['.' => true, '..' => true]; if (isset($noopPaths[$this->path])) { return $this; @@ -322,18 +322,22 @@ public function removeDotSegments() } } - // Combine the normalized parts and add the leading slash if needed - if ($this->path[0] == '/') { - $this->path = '/' . implode('/', $results); - } else { - $this->path = implode('/', $results); + $newPath = implode('/', $results); + + // Add the leading slash if necessary + if (substr($this->path, 0, 1) === '/' && + substr($newPath, 0, 1) !== '/' + ) { + $newPath = '/' . $newPath; } // Add the trailing slash if necessary - if ($this->path != '/' && isset($ignoreSegments[end($segments)])) { - $this->path .= '/'; + if ($newPath != '/' && isset($ignoreSegments[end($segments)])) { + $newPath .= '/'; } + $this->path = $newPath; + return $this; } @@ -351,10 +355,13 @@ public function addPath($relativePath) strlen($relativePath) > 0 ) { // Add a leading slash if needed - if ($relativePath[0] != '/') { + if ($relativePath[0] !== '/' && + substr($this->path, -1, 1) !== '/' + ) { $relativePath = '/' . $relativePath; } - $this->setPath(str_replace('//', '/', $this->path . $relativePath)); + + $this->setPath($this->path . $relativePath); } return $this; diff --git a/core/vendor/guzzlehttp/guzzle/src/functions.php b/core/vendor/guzzlehttp/guzzle/src/functions.php index c57619a24918aa128ecd4e99fa5727ada5d95768..46d4c4d39f383719ae1381380019dde4e8be4d2a 100644 --- a/core/vendor/guzzlehttp/guzzle/src/functions.php +++ b/core/vendor/guzzlehttp/guzzle/src/functions.php @@ -8,326 +8,331 @@ use GuzzleHttp\Message\ResponseInterface; use GuzzleHttp\UriTemplate; -/** - * Send a custom request - * - * @param string $method HTTP request method - * @param string $url URL of the request - * @param array $options Options to use with the request. - * - * @return ResponseInterface - */ -function request($method, $url, array $options = []) -{ - static $client; - if (!$client) { - $client = new Client(); - } - - return $client->send($client->createRequest($method, $url, $options)); -} +if (!defined('GUZZLE_FUNCTIONS_VERSION')) { + + define('GUZZLE_FUNCTIONS_VERSION', ClientInterface::VERSION); + + /** + * Send a custom request + * + * @param string $method HTTP request method + * @param string $url URL of the request + * @param array $options Options to use with the request. + * + * @return ResponseInterface + */ + function request($method, $url, array $options = []) + { + static $client; + if (!$client) { + $client = new Client(); + } -/** - * Send a GET request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function get($url, array $options = []) -{ - return request('GET', $url, $options); -} + return $client->send($client->createRequest($method, $url, $options)); + } -/** - * Send a HEAD request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function head($url, array $options = []) -{ - return request('HEAD', $url, $options); -} + /** + * Send a GET request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function get($url, array $options = []) + { + return request('GET', $url, $options); + } -/** - * Send a DELETE request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function delete($url, array $options = []) -{ - return request('DELETE', $url, $options); -} + /** + * Send a HEAD request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function head($url, array $options = []) + { + return request('HEAD', $url, $options); + } -/** - * Send a POST request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function post($url, array $options = []) -{ - return request('POST', $url, $options); -} + /** + * Send a DELETE request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function delete($url, array $options = []) + { + return request('DELETE', $url, $options); + } -/** - * Send a PUT request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function put($url, array $options = []) -{ - return request('PUT', $url, $options); -} + /** + * Send a POST request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function post($url, array $options = []) + { + return request('POST', $url, $options); + } -/** - * Send a PATCH request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function patch($url, array $options = []) -{ - return request('PATCH', $url, $options); -} + /** + * Send a PUT request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function put($url, array $options = []) + { + return request('PUT', $url, $options); + } -/** - * Send an OPTIONS request - * - * @param string $url URL of the request - * @param array $options Array of request options - * - * @return ResponseInterface - */ -function options($url, array $options = []) -{ - return request('OPTIONS', $url, $options); -} + /** + * Send a PATCH request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function patch($url, array $options = []) + { + return request('PATCH', $url, $options); + } -/** - * Convenience method for sending multiple requests in parallel and retrieving - * a hash map of requests to response objects or RequestException objects. - * - * Note: This method keeps every request and response in memory, and as such is - * NOT recommended when sending a large number or an indeterminable number of - * requests in parallel. - * - * @param ClientInterface $client Client used to send the requests - * @param array|\Iterator $requests Requests to send in parallel - * @param array $options Passes through the options available in - * {@see GuzzleHttp\ClientInterface::sendAll()} - * @return \SplObjectStorage Requests are the key and each value is a - * {@see GuzzleHttp\Message\ResponseInterface} if the request succeeded or - * a {@see GuzzleHttp\Exception\RequestException} if it failed. - * @throws \InvalidArgumentException if the event format is incorrect. - */ -function batch(ClientInterface $client, $requests, array $options = []) -{ - $hash = new \SplObjectStorage(); - foreach ($requests as $request) { - $hash->attach($request); + /** + * Send an OPTIONS request + * + * @param string $url URL of the request + * @param array $options Array of request options + * + * @return ResponseInterface + */ + function options($url, array $options = []) + { + return request('OPTIONS', $url, $options); } - $handler = [ - 'priority' => RequestEvents::EARLY, - 'once' => true, - 'fn' => function ($e) use ($hash) { $hash[$e->getRequest()] = $e; } - ]; - - // Merge the necessary complete and error events to the event listeners so - // that as each request succeeds or fails, it is added to the result hash. - foreach (['complete', 'error'] as $name) { - if (!isset($options[$name])) { - $options[$name] = $handler; - } elseif (is_callable($options[$name])) { - $options[$name] = [['fn' => $options[$name]], $handler]; - } elseif (is_array($options[$name])) { - $options[$name][] = $handler; - } else { - throw new \InvalidArgumentException('Invalid event format'); + /** + * Convenience method for sending multiple requests in parallel and + * retrieving a hash map of requests to response objects or + * RequestException objects. + * + * Note: This method keeps every request and response in memory, and as + * such is NOT recommended when sending a large number or an indeterminable + * number of requests in parallel. + * + * @param ClientInterface $client Client used to send the requests + * @param array|\Iterator $requests Requests to send in parallel + * @param array $options Passes through the options available in + * {@see GuzzleHttp\ClientInterface::sendAll()} + * + * @return \SplObjectStorage Requests are the key and each value is a + * {@see GuzzleHttp\Message\ResponseInterface} if the request succeeded + * or a {@see GuzzleHttp\Exception\RequestException} if it failed. + * @throws \InvalidArgumentException if the event format is incorrect. + */ + function batch(ClientInterface $client, $requests, array $options = []) + { + $hash = new \SplObjectStorage(); + foreach ($requests as $request) { + $hash->attach($request); } - } - // Send the requests in parallel and aggregate the results. - $client->sendAll($requests, $options); + // Merge the necessary complete and error events to the event listeners + // so that as each request succeeds or fails, it is added to the result + // hash. + $options = RequestEvents::convertEventArray( + $options, + ['complete', 'error'], + [ + 'priority' => RequestEvents::EARLY, + 'once' => true, + 'fn' => function ($e) use ($hash) { + $hash[$e->getRequest()] = $e; + } + ] + ); - // Update the received value for any of the intercepted requests. - foreach ($hash as $request) { - if ($hash[$request] instanceof CompleteEvent) { - $hash[$request] = $hash[$request]->getResponse(); - } elseif ($hash[$request] instanceof ErrorEvent) { - $hash[$request] = $hash[$request]->getException(); + // Send the requests in parallel and aggregate the results. + $client->sendAll($requests, $options); + + // Update the received value for any of the intercepted requests. + foreach ($hash as $request) { + if ($hash[$request] instanceof CompleteEvent) { + $hash[$request] = $hash[$request]->getResponse(); + } elseif ($hash[$request] instanceof ErrorEvent) { + $hash[$request] = $hash[$request]->getException(); + } } - } - return $hash; -} + return $hash; + } -/** - * Gets a value from an array using a path syntax to retrieve nested data. - * - * This method does not allow for keys that contain "/". You must traverse - * the array manually or using something more advanced like JMESPath to - * work with keys that contain "/". - * - * // Get the bar key of a set of nested arrays. - * // This is equivalent to $collection['foo']['baz']['bar'] but won't - * // throw warnings for missing keys. - * GuzzleHttp\get_path($data, 'foo/baz/bar'); - * - * @param array $data Data to retrieve values from - * @param string $path Path to traverse and retrieve a value from - * - * @return mixed|null - */ -function get_path($data, $path) -{ - $path = explode('/', $path); - - while (null !== ($part = array_shift($path))) { - if (!is_array($data) || !isset($data[$part])) { - return null; + /** + * Gets a value from an array using a path syntax to retrieve nested data. + * + * This method does not allow for keys that contain "/". You must traverse + * the array manually or using something more advanced like JMESPath to + * work with keys that contain "/". + * + * // Get the bar key of a set of nested arrays. + * // This is equivalent to $collection['foo']['baz']['bar'] but won't + * // throw warnings for missing keys. + * GuzzleHttp\get_path($data, 'foo/baz/bar'); + * + * @param array $data Data to retrieve values from + * @param string $path Path to traverse and retrieve a value from + * + * @return mixed|null + */ + function get_path($data, $path) + { + $path = explode('/', $path); + + while (null !== ($part = array_shift($path))) { + if (!is_array($data) || !isset($data[$part])) { + return null; + } + $data = $data[$part]; } - $data = $data[$part]; - } - return $data; -} + return $data; + } -/** - * Set a value in a nested array key. Keys will be created as needed to set the - * value. - * - * This function does not support keys that contain "/" or "[]" characters - * because these are special tokens used when traversing the data structure. - * A value may be prepended to an existing array by using "[]" as the final - * key of a path. - * - * GuzzleHttp\get_path($data, 'foo/baz'); // null - * GuzzleHttp\set_path($data, 'foo/baz/[]', 'a'); - * GuzzleHttp\set_path($data, 'foo/baz/[]', 'b'); - * GuzzleHttp\get_path($data, 'foo/baz'); - * // Returns ['a', 'b'] - * - * @param array $data Data to modify by reference - * @param string $path Path to set - * @param mixed $value Value to set at the key - * @throws \RuntimeException when trying to setPath using a nested path that - * travels through a scalar value. - */ -function set_path(&$data, $path, $value) -{ - $current =& $data; - $queue = explode('/', $path); - while (null !== ($key = array_shift($queue))) { - if (!is_array($current)) { - throw new \RuntimeException("Trying to setPath {$path}, but " - . "{$key} is set and is not an array"); - } elseif (!$queue) { - if ($key == '[]') { - $current[] = $value; + /** + * Set a value in a nested array key. Keys will be created as needed to set + * the value. + * + * This function does not support keys that contain "/" or "[]" characters + * because these are special tokens used when traversing the data structure. + * A value may be prepended to an existing array by using "[]" as the final + * key of a path. + * + * GuzzleHttp\get_path($data, 'foo/baz'); // null + * GuzzleHttp\set_path($data, 'foo/baz/[]', 'a'); + * GuzzleHttp\set_path($data, 'foo/baz/[]', 'b'); + * GuzzleHttp\get_path($data, 'foo/baz'); + * // Returns ['a', 'b'] + * + * @param array $data Data to modify by reference + * @param string $path Path to set + * @param mixed $value Value to set at the key + * + * @throws \RuntimeException when trying to setPath using a nested path + * that travels through a scalar value. + */ + function set_path(&$data, $path, $value) + { + $current =& $data; + $queue = explode('/', $path); + while (null !== ($key = array_shift($queue))) { + if (!is_array($current)) { + throw new \RuntimeException("Trying to setPath {$path}, but " + . "{$key} is set and is not an array"); + } elseif (!$queue) { + if ($key == '[]') { + $current[] = $value; + } else { + $current[$key] = $value; + } + } elseif (isset($current[$key])) { + $current =& $current[$key]; } else { - $current[$key] = $value; + $current[$key] = []; + $current =& $current[$key]; } - } elseif (isset($current[$key])) { - $current =& $current[$key]; - } else { - $current[$key] = []; - $current =& $current[$key]; } } -} -/** - * Expands a URI template - * - * @param string $template URI template - * @param array $variables Template variables - * - * @return string - */ -function uri_template($template, array $variables) -{ - if (function_exists('\\uri_template')) { - return \uri_template($template, $variables); - } - - static $uriTemplate; - if (!$uriTemplate) { - $uriTemplate = new UriTemplate(); - } + /** + * Expands a URI template + * + * @param string $template URI template + * @param array $variables Template variables + * + * @return string + */ + function uri_template($template, array $variables) + { + if (function_exists('\\uri_template')) { + return \uri_template($template, $variables); + } - return $uriTemplate->expand($template, $variables); -} + static $uriTemplate; + if (!$uriTemplate) { + $uriTemplate = new UriTemplate(); + } -/** - * Wrapper for JSON decode that implements error detection with helpful error - * messages. - * - * @param string $json JSON data to parse - * @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 - * @throws \InvalidArgumentException if the JSON cannot be parsed. - * @link http://www.php.net/manual/en/function.json-decode.php - */ -function json_decode($json, $assoc = false, $depth = 512, $options = 0) -{ - static $jsonErrors = [ - JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', - JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', - JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', - JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', - JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' - ]; - - $data = \json_decode($json, $assoc, $depth, $options); - - if (JSON_ERROR_NONE !== json_last_error()) { - $last = json_last_error(); - throw new \InvalidArgumentException( - 'Unable to parse JSON data: ' - . (isset($jsonErrors[$last]) ? $jsonErrors[$last] : 'Unknown error') - ); + return $uriTemplate->expand($template, $variables); } - return $data; -} + /** + * Wrapper for JSON decode that implements error detection with helpful + * error messages. + * + * @param string $json JSON data to parse + * @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 + * @throws \InvalidArgumentException if the JSON cannot be parsed. + * @link http://www.php.net/manual/en/function.json-decode.php + */ + function json_decode($json, $assoc = false, $depth = 512, $options = 0) + { + static $jsonErrors = [ + JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', + JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', + JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', + JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', + JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' + ]; + + $data = \json_decode($json, $assoc, $depth, $options); + + if (JSON_ERROR_NONE !== json_last_error()) { + $last = json_last_error(); + throw new \InvalidArgumentException( + 'Unable to parse JSON data: ' + . (isset($jsonErrors[$last]) + ? $jsonErrors[$last] + : 'Unknown error') + ); + } -/** - * @internal - */ -function deprecation_proxy($object, $name, $arguments, $map) -{ - if (!isset($map[$name])) { - throw new \BadMethodCallException('Unknown method, ' . $name); + return $data; } - $message = sprintf('%s is deprecated and will be removed in a future ' - . 'version. Update your code to use the equivalent %s method ' - . 'instead to avoid breaking changes when this shim is removed.', - get_class($object) . '::' . $name . '()', - get_class($object) . '::' . $map[$name] . '()' - ); + /** + * @internal + */ + function deprecation_proxy($object, $name, $arguments, $map) + { + if (!isset($map[$name])) { + throw new \BadMethodCallException('Unknown method, ' . $name); + } - trigger_error($message, E_USER_DEPRECATED); + $message = sprintf('%s is deprecated and will be removed in a future ' + . 'version. Update your code to use the equivalent %s method ' + . 'instead to avoid breaking changes when this shim is removed.', + get_class($object) . '::' . $name . '()', + get_class($object) . '::' . $map[$name] . '()' + ); - return call_user_func_array([$object, $map[$name]], $arguments); + trigger_error($message, E_USER_DEPRECATED); + + return call_user_func_array([$object, $map[$name]], $arguments); + } } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Adapter/Curl/CurlFactoryTest.php b/core/vendor/guzzlehttp/guzzle/tests/Adapter/Curl/CurlFactoryTest.php index 9bf8fc70675e690927341fd9dc3654a0808a62de..23b76e6e41a72a571ef0ee310751b4a270a0d0f8 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Adapter/Curl/CurlFactoryTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Adapter/Curl/CurlFactoryTest.php @@ -282,6 +282,27 @@ public function testDoesNotSendSizeTwice() $this->assertNotContains('Content-Length', implode(' ', $_SERVER['last_curl'][CURLOPT_HTTPHEADER])); } + public function testCanSendPayloadWithGet() + { + Server::flush(); + Server::enqueue(["HTTP/1.1 200 OK\r\n\r\n"]); + $request = new Request( + 'GET', + Server::$url, + [], + Stream::factory('foo') + ); + $this->emit($request); + $t = new Transaction(new Client(), $request); + $f = new CurlFactory(); + $h = $f($t, new MessageFactory()); + curl_exec($h); + curl_close($h); + $sent = Server::received(true)[0]; + $this->assertEquals('foo', (string) $sent->getBody()); + $this->assertEquals(3, (string) $sent->getHeader('Content-Length')); + } + private function emit(RequestInterface $request) { $event = new BeforeEvent(new Transaction(new Client(), $request)); diff --git a/core/vendor/guzzlehttp/guzzle/tests/Adapter/StreamAdapterTest.php b/core/vendor/guzzlehttp/guzzle/tests/Adapter/StreamAdapterTest.php index 9e9e13a65a3757eabe57f44110c7d294ce14b042..7349dc720ef252d286493a020cddbe55c6fbce49 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Adapter/StreamAdapterTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Adapter/StreamAdapterTest.php @@ -34,7 +34,7 @@ public function testReturnsResponseForSuccessfulRequest() $sent = Server::received(true)[0]; $this->assertEquals('GET', $sent->getMethod()); $this->assertEquals('/', $sent->getResource()); - $this->assertEquals('127.0.0.1:8124', $sent->getHeader('host')); + $this->assertEquals('127.0.0.1:8125', $sent->getHeader('host')); $this->assertEquals('Bar', $sent->getHeader('foo')); $this->assertTrue($sent->hasHeader('user-agent')); } @@ -134,7 +134,7 @@ public function testStreamAttributeKeepsStreamOpen() $sent = Server::received(true)[0]; $this->assertEquals('PUT', $sent->getMethod()); $this->assertEquals('/foo', $sent->getResource()); - $this->assertEquals('127.0.0.1:8124', $sent->getHeader('host')); + $this->assertEquals('127.0.0.1:8125', $sent->getHeader('host')); $this->assertEquals('Bar', $sent->getHeader('foo')); $this->assertTrue($sent->hasHeader('user-agent')); } @@ -201,7 +201,7 @@ public function testAddsGzipFilterIfAcceptHeaderIsPresent() 'stream' => true ]); $body = $response->getBody(); - $this->assertEquals('compress.zlib://http://127.0.0.1:8124/', $body->getMetadata()['uri']); + $this->assertEquals('compress.zlib://http://127.0.0.1:8125/', $body->getMetadata()['uri']); } protected function getStreamFromBody(Stream $body) @@ -222,9 +222,9 @@ protected function getSendResult(array $opts) public function testAddsProxy() { - $body = $this->getSendResult(['stream' => true, 'proxy' => '127.0.0.1:8124'])->getBody(); + $body = $this->getSendResult(['stream' => true, 'proxy' => '127.0.0.1:8125'])->getBody(); $opts = stream_context_get_options($this->getStreamFromBody($body)); - $this->assertEquals('127.0.0.1:8124', $opts['http']['proxy']); + $this->assertEquals('127.0.0.1:8125', $opts['http']['proxy']); $this->assertTrue($opts['http']['request_fulluri']); } @@ -307,9 +307,9 @@ public function testDebugAttributeWritesStreamInfoToTempBufferByDefault() ob_start(); $client->get('/', ['debug' => true]); $contents = ob_get_clean(); - $this->assertContains('<http://127.0.0.1:8124/> [CONNECT]', $contents); - $this->assertContains('<http://127.0.0.1:8124/> [FILE_SIZE_IS]', $contents); - $this->assertContains('<http://127.0.0.1:8124/> [PROGRESS]', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [CONNECT]', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [FILE_SIZE_IS]', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [PROGRESS]', $contents); } public function testDebugAttributeWritesStreamInfoToBuffer() @@ -329,10 +329,10 @@ public function testDebugAttributeWritesStreamInfoToBuffer() $client->get('/', ['debug' => $buffer]); fseek($buffer, 0); $contents = stream_get_contents($buffer); - $this->assertContains('<http://127.0.0.1:8124/> [CONNECT]', $contents); - $this->assertContains('<http://127.0.0.1:8124/> [FILE_SIZE_IS] message: "Content-Length: 8"', $contents); - $this->assertContains('<http://127.0.0.1:8124/> [PROGRESS] bytes_max: "8"', $contents); - $this->assertContains('<http://127.0.0.1:8124/> [MIME_TYPE_IS] message: "text/plain"', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [CONNECT]', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [FILE_SIZE_IS] message: "Content-Length: 8"', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [PROGRESS] bytes_max: "8"', $contents); + $this->assertContains('<http://127.0.0.1:8125/> [MIME_TYPE_IS] message: "text/plain"', $contents); } public function testAddsProxyByProtocol() @@ -381,4 +381,22 @@ public function testEnsuresThatStreamContextIsAnArray() 'config' => ['stream_context' => 'foo'] ]); } + + /** + * @ticket https://github.com/guzzle/guzzle/issues/725 + */ + public function testHandlesMultipleHeadersOfSameName() + { + $a = new StreamAdapter(new MessageFactory()); + $ref = new \ReflectionMethod($a, 'headersFromLines'); + $ref->setAccessible(true); + $this->assertEquals([ + 'foo' => ['bar', 'bam'], + 'abc' => ['123'] + ], $ref->invoke($a, [ + 'foo: bar', + 'foo: bam', + 'abc: 123' + ])); + } } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Cookie/CookieJarTest.php b/core/vendor/guzzlehttp/guzzle/tests/Cookie/CookieJarTest.php index 795194636bb7354024976c081920c999c6046084..eaa2a5fdaa25a1266b4a73a20182048f3f03e815 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Cookie/CookieJarTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Cookie/CookieJarTest.php @@ -322,4 +322,18 @@ public function testDeletesCookiesByName() }, $jar->getIterator()->getArrayCopy()); $this->assertEquals(['foo', 'test', 'you'], $names); } + + public function testCanConvertToAndLoadFromArray() + { + $jar = new CookieJar(true); + foreach ($this->getTestCookies() as $cookie) { + $jar->setCookie($cookie); + } + $this->assertCount(3, $jar); + $arr = $jar->toArray(); + $this->assertCount(3, $arr); + $newCookieJar = new CookieJar(false, $arr); + $this->assertCount(3, $newCookieJar); + $this->assertSame($jar->toArray(), $newCookieJar->toArray()); + } } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Event/RequestEventsTest.php b/core/vendor/guzzlehttp/guzzle/tests/Event/RequestEventsTest.php index 64c52dc92cf5ad0bc1afe550b70e303e58ce0945..a63b3aaa199322ae236074465b0875904783f297 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Event/RequestEventsTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Event/RequestEventsTest.php @@ -153,4 +153,60 @@ public function testEmitsErrorEventForRequestExceptionsThrownDuringBeforeThatHav $this->assertTrue($called); } } + + public function prepareEventProvider() + { + $cb = function () {}; + + return [ + [[], ['complete'], $cb, ['complete' => [$cb]]], + [ + ['complete' => $cb], + ['complete'], + $cb, + ['complete' => [$cb, $cb]] + ], + [ + ['prepare' => []], + ['error', 'foo'], + $cb, + [ + 'prepare' => [], + 'error' => [$cb], + 'foo' => [$cb] + ] + ], + [ + ['prepare' => []], + ['prepare'], + $cb, + [ + 'prepare' => [$cb] + ] + ], + [ + ['prepare' => ['fn' => $cb]], + ['prepare'], $cb, + [ + 'prepare' => [ + ['fn' => $cb], + $cb + ] + ] + ], + ]; + } + + /** + * @dataProvider prepareEventProvider + */ + public function testConvertsEventArrays( + array $in, + array $events, + $add, + array $out + ) { + $result = RequestEvents::convertEventArray($in, $events, $add); + $this->assertEquals($out, $result); + } } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Message/MessageFactoryTest.php b/core/vendor/guzzlehttp/guzzle/tests/Message/MessageFactoryTest.php index 8a8b97adfc27afaf55fc09c6f8fa3fd7f631ed7d..9f9b20c89fbc2af8eea1307b5807419933a13f7f 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Message/MessageFactoryTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Message/MessageFactoryTest.php @@ -488,6 +488,18 @@ public function testCanAddJsonData() $this->assertEquals('{"foo":"bar"}', (string) $request->getBody()); } + public function testCanAddJsonDataToAPostRequest() + { + $request = (new MessageFactory)->createRequest('POST', 'http://f.com', [ + 'json' => ['foo' => 'bar'] + ]); + $this->assertEquals( + 'application/json', + $request->getHeader('Content-Type') + ); + $this->assertEquals('{"foo":"bar"}', (string) $request->getBody()); + } + public function testCanAddJsonDataAndNotOverwriteContentType() { $request = (new MessageFactory)->createRequest('PUT', 'http://f.com', [ @@ -497,4 +509,41 @@ public function testCanAddJsonDataAndNotOverwriteContentType() $this->assertEquals('foo', $request->getHeader('Content-Type')); $this->assertEquals('null', (string) $request->getBody()); } + + public function testCanUseCustomSubclassesWithMethods() + { + (new ExtendedFactory)->createRequest('PUT', 'http://f.com', [ + 'headers' => ['Content-Type' => 'foo'], + 'foo' => 'bar' + ]); + try { + $f = new MessageFactory; + $f->createRequest('PUT', 'http://f.com', [ + 'headers' => ['Content-Type' => 'foo'], + 'foo' => 'bar' + ]); + } catch (\InvalidArgumentException $e) { + $this->assertContains('foo config', $e->getMessage()); + } + } + + /** + * @ticket https://github.com/guzzle/guzzle/issues/706 + */ + public function testDoesNotApplyPostBodyRightAway() + { + $request = (new MessageFactory)->createRequest('POST', 'http://f.cn', [ + 'body' => ['foo' => ['bar', 'baz']] + ]); + $this->assertEquals('', $request->getHeader('Content-Type')); + $this->assertEquals('', $request->getHeader('Content-Length')); + $request->getBody()->setAggregator(Query::duplicateAggregator()); + $request->getBody()->applyRequestHeaders($request); + $this->assertEquals('foo=bar&foo=baz', $request->getBody()); + } +} + +class ExtendedFactory extends MessageFactory +{ + protected function add_foo() {} } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Post/MultipartBodyTest.php b/core/vendor/guzzlehttp/guzzle/tests/Post/MultipartBodyTest.php index 32ce7d18e14a4db27b2f29ffa4ce07461277ba6e..1853e8d852fc2a5dce892381b5fd4ecf52ce2665 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Post/MultipartBodyTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Post/MultipartBodyTest.php @@ -27,6 +27,17 @@ public function testConstructorAddsFieldsAndFiles() . "Content-Type: text/plain\r\n\r\nabc\r\n--abcdef--", $c); } + public function testDoesNotModifyFieldFormat() + { + $m = new MultipartBody(['foo+baz' => 'bar+bam %20 boo'], [ + new PostFile('foo+bar', 'abc %20 123', 'foo.txt') + ], 'abcdef'); + $this->assertContains('name="foo+baz"', (string) $m); + $this->assertContains('name="foo+bar"', (string) $m); + $this->assertContains('bar+bam %20 boo', (string) $m); + $this->assertContains('abc %20 123', (string) $m); + } + /** * @expectedException \InvalidArgumentException */ @@ -59,44 +70,23 @@ public function testCanDetachFieldsAndFiles() $this->assertEquals('', (string) $b); } - public function testCanOnlySeekTo0() - { - $b = new MultipartBody(); - $this->assertFalse($b->seek(10)); - } - public function testIsSeekableReturnsTrueIfAllAreSeekable() { $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') - ->setMethods(['isSeekable']) + ->setMethods(['isSeekable', 'isReadable']) ->getMockForAbstractClass(); $s->expects($this->once()) ->method('isSeekable') ->will($this->returnValue(false)); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); $p = new PostFile('foo', $s, 'foo.php'); $b = new MultipartBody([], [$p]); $this->assertFalse($b->isSeekable()); $this->assertFalse($b->seek(10)); } - /** - * @expectedException \RuntimeException - */ - public function testThrowsExceptionWhenStreamFailsToRewind() - { - $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') - ->setMethods(['seek', 'isSeekable']) - ->getMockForAbstractClass(); - $s->expects($this->once()) - ->method('isSeekable') - ->will($this->returnValue(true)); - $s->expects($this->once()) - ->method('seek') - ->will($this->returnValue(false)); - $b = new MultipartBody([], [new PostFile('foo', $s, 'foo.php')]); - $b->seek(0); - } - public function testGetContentsCanCap() { $b = $this->getTestBody(); @@ -125,11 +115,14 @@ public function testCalculatesSize() public function testCalculatesSizeAndReturnsNullForUnknown() { $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') - ->setMethods(['getSize']) + ->setMethods(['getSize', 'isReadable']) ->getMockForAbstractClass(); $s->expects($this->once()) ->method('getSize') ->will($this->returnValue(null)); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); $b = new MultipartBody([], [new PostFile('foo', $s, 'foo.php')]); $this->assertNull($b->getSize()); } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Post/PostBodyTest.php b/core/vendor/guzzlehttp/guzzle/tests/Post/PostBodyTest.php index bbbd6d0196f7f1f154fee17f72c78ac092e0285c..18729b351c5389532383d651584028098a51d12c 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Post/PostBodyTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Post/PostBodyTest.php @@ -64,6 +64,21 @@ public function testApplyingWithFieldsAddsMultipartUpload() $this->assertTrue($m->hasHeader('Content-Length')); } + public function testMultipartWithNestedFields() + { + $b = new PostBody(); + $b->setField('foo', ['bar' => 'baz']); + $b->forceMultipartUpload(true); + $this->assertEquals(['foo' => ['bar' => 'baz']], $b->getFields()); + $m = new Request('POST', '/'); + $b->applyRequestHeaders($m); + $this->assertContains('multipart/form-data', (string) $m->getHeader('Content-Type')); + $this->assertTrue($m->hasHeader('Content-Length')); + $contents = $b->getContents(); + $this->assertContains('name="foo[bar]"', $contents); + $this->assertNotContains('name="foo"', $contents); + } + public function testCountProvidesFieldsAndFiles() { $b = new PostBody(); @@ -137,4 +152,19 @@ public function testCreatesMultipartUploadWithMultiFields() $this->assertContains(file_get_contents(__FILE__), $s); $this->assertContains('testing=bar', $s); } + + public function testMultipartWithBase64Fields() + { + $b = new PostBody(); + $b->setField('foo64', '/xA2JhWEqPcgyLRDdir9WSRi/khpb2Lh3ooqv+5VYoc='); + $b->forceMultipartUpload(true); + $this->assertEquals(['foo64' => '/xA2JhWEqPcgyLRDdir9WSRi/khpb2Lh3ooqv+5VYoc='], $b->getFields()); + $m = new Request('POST', '/'); + $b->applyRequestHeaders($m); + $this->assertContains('multipart/form-data', (string) $m->getHeader('Content-Type')); + $this->assertTrue($m->hasHeader('Content-Length')); + $contents = $b->getContents(); + $this->assertContains('name="foo64"', $contents); + $this->assertContains('/xA2JhWEqPcgyLRDdir9WSRi/khpb2Lh3ooqv+5VYoc=', $contents); + } } diff --git a/core/vendor/guzzlehttp/guzzle/tests/QueryParserTest.php b/core/vendor/guzzlehttp/guzzle/tests/QueryParserTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e9075a80d0d088b1f6bfc45286fa0d4dded49411 --- /dev/null +++ b/core/vendor/guzzlehttp/guzzle/tests/QueryParserTest.php @@ -0,0 +1,80 @@ +<?php + +namespace GuzzleHttp\Tests; + +use GuzzleHttp\Query; +use GuzzleHttp\QueryParser; + +class QueryParserTest extends \PHPUnit_Framework_TestCase +{ + public function parseQueryProvider() + { + return [ + // Does not need to parse when the string is empty + ['', []], + // Can parse mult-values items + ['q=a&q=b', ['q' => ['a', 'b']]], + // Can parse multi-valued items that use numeric indices + ['q[0]=a&q[1]=b', ['q' => ['a', 'b']]], + // Can parse duplicates and does not include numeric indices + ['q[]=a&q[]=b', ['q' => ['a', 'b']]], + // Ensures that the value of "q" is an array even though one value + ['q[]=a', ['q' => ['a']]], + // Does not modify "." to "_" like PHP's parse_str() + ['q.a=a&q.b=b', ['q.a' => 'a', 'q.b' => 'b']], + // Can decode %20 to " " + ['q%20a=a%20b', ['q a' => 'a b']], + // Can parse funky strings with no values by assigning each to null + ['q&a', ['q' => null, 'a' => null]], + // Does not strip trailing equal signs + ['data=abc=', ['data' => 'abc=']], + // Can store duplicates without affecting other values + ['foo=a&foo=b&?µ=c', ['foo' => ['a', 'b'], '?µ' => 'c']], + // Sets value to null when no "=" is present + ['foo', ['foo' => null]], + // Preserves "0" keys. + ['0', ['0' => null]], + // Sets the value to an empty string when "=" is present + ['0=', ['0' => '']], + // Preserves falsey keys + ['var=0', ['var' => '0']], + // Can deeply nest and store duplicate PHP values + ['a[b][c]=1&a[b][c]=2', [ + 'a' => ['b' => ['c' => ['1', '2']]] + ]], + // Can parse PHP style arrays + ['a[b]=c&a[d]=e', ['a' => ['b' => 'c', 'd' => 'e']]], + // Ensure it doesn't leave things behind with repeated values + // Can parse mult-values items + ['q=a&q=b&q=c', ['q' => ['a', 'b', 'c']]], + ]; + } + + /** + * @dataProvider parseQueryProvider + */ + public function testParsesQueries($input, $output) + { + $query = Query::fromString($input); + $this->assertEquals($output, $query->toArray()); + // Normalize the input and output + $query->setEncodingType(false); + $this->assertEquals(rawurldecode($input), (string) $query); + } + + public function testConvertsPlusSymbolsToSpacesByDefault() + { + $query = Query::fromString('var=foo+bar', true); + $this->assertEquals('foo bar', $query->get('var')); + } + + public function testCanControlDecodingType() + { + $qp = new QueryParser(); + $q = new Query(); + $qp->parseInto($q, 'var=foo+bar', Query::RFC3986); + $this->assertEquals('foo+bar', $q->get('var')); + $qp->parseInto($q, 'var=foo+bar', Query::RFC1738); + $this->assertEquals('foo bar', $q->get('var')); + } +} diff --git a/core/vendor/guzzlehttp/guzzle/tests/QueryTest.php b/core/vendor/guzzlehttp/guzzle/tests/QueryTest.php index 6d0dde948d262d4d485b5e9517077404864efb37..3d2fcbb54f2a6ee7c4118c75e9948f4ff266fca1 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/QueryTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/QueryTest.php @@ -67,71 +67,6 @@ public function testAllowsMultipleValuesPerKey() $this->assertEquals('facet=size&facet=width&facet.field=foo', (string) $q); } - public function parseQueryProvider() - { - return array( - // Ensure that multiple query string values are allowed per value - array('q=a&q=b', array('q' => array('a', 'b'))), - // Ensure that PHP array style query string values are parsed - array('q[]=a&q[]=b', array('q' => array('a', 'b'))), - // Ensure that a single PHP array style query string value is parsed into an array - array('q[]=a', array('q' => array('a'))), - // Ensure that decimals are allowed in query strings - array('q.a=a&q.b=b', array( - 'q.a' => 'a', - 'q.b' => 'b' - )), - // Ensure that query string values are percent decoded - array('q%20a=a%20b', array('q a' => 'a b')), - // Ensure null values can be added - array('q&a', array('q' => null, 'a' => null)), - ); - } - - /** - * @dataProvider parseQueryProvider - */ - public function testParsesQueries($query, $data) - { - $query = Query::fromString($query); - $this->assertEquals($data, $query->toArray()); - } - - public function testProperlyDealsWithDuplicateQueryValues() - { - $query = Query::fromString('foo=a&foo=b&?µ=c'); - $this->assertEquals(array('a', 'b'), $query->get('foo')); - $this->assertEquals('c', $query->get('?µ')); - } - - public function testAllowsNullQueryValues() - { - $query = Query::fromString('foo'); - $this->assertEquals('foo', (string) $query); - $query->set('foo', null); - $this->assertEquals('foo', (string) $query); - } - - public function testAllowsFalsyQueryValues() - { - $query = Query::fromString('0'); - $this->assertEquals('0', (string) $query); - $query->set('0', ''); - $this->assertSame('0=', (string) $query); - } - - public function testConvertsPlusSymbolsToSpaces() - { - $query = Query::fromString('var=foo+bar'); - $this->assertEquals('foo bar', $query->get('var')); - } - - public function testFromStringDoesntMangleZeroes() - { - $query = Query::fromString('var=0'); - $this->assertSame('0', $query->get('var')); - } - public function testAllowsZeroValues() { $query = new Query(array( @@ -143,29 +78,6 @@ public function testAllowsZeroValues() $this->assertEquals('foo=0&baz=0&bar&boo=', (string) $query); } - public function testFromStringDoesntStripTrailingEquals() - { - $query = Query::fromString('data=mF0b3IiLCJUZWFtIERldiJdfX0='); - $this->assertEquals('mF0b3IiLCJUZWFtIERldiJdfX0=', $query->get('data')); - } - - public function testGuessesIfDuplicateAggregatorShouldBeUsed() - { - $query = Query::fromString('test=a&test=b'); - $this->assertEquals('test=a&test=b', (string) $query); - } - - public function testGuessesIfDuplicateAggregatorShouldBeUsedAndChecksForPhpStyle() - { - $query = Query::fromString('test[]=a&test[]=b'); - $this->assertEquals('test%5B0%5D=a&test%5B1%5D=b', (string) $query); - } - - public function testCastingToAndCreatingFromStringWithEmptyValuesIsFast() - { - $this->assertEquals('', (string) Query::fromString('')); - } - private $encodeData = [ 't' => [ 'v1' => ['a', '1'], @@ -222,4 +134,25 @@ public function testPhpEncodesNoNumericIndices() 't[v3][v5]' => ['d'], ), $result); } + + public function testCanDisableUrlEncodingDecoding() + { + $q = Query::fromString('foo=bar+baz boo%20', false); + $this->assertEquals('bar+baz boo%20', $q['foo']); + $this->assertEquals('foo=bar+baz boo%20', (string) $q); + } + + public function testCanChangeUrlEncodingDecodingToRfc1738() + { + $q = Query::fromString('foo=bar+baz', Query::RFC1738); + $this->assertEquals('bar baz', $q['foo']); + $this->assertEquals('foo=bar+baz', (string) $q); + } + + public function testCanChangeUrlEncodingDecodingToRfc3986() + { + $q = Query::fromString('foo=bar%20baz', Query::RFC3986); + $this->assertEquals('bar baz', $q['foo']); + $this->assertEquals('foo=bar%20baz', (string) $q); + } } diff --git a/core/vendor/guzzlehttp/guzzle/tests/Server.php b/core/vendor/guzzlehttp/guzzle/tests/Server.php index 2d04456185c4e2939758fd7c9c04b1b7ffe02b34..273c852b1e198bc3b75e117c2a6858d098c9064a 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/Server.php +++ b/core/vendor/guzzlehttp/guzzle/tests/Server.php @@ -28,8 +28,8 @@ class Server private static $client; public static $started; - public static $url = 'http://127.0.0.1:8124/'; - public static $port = 8124; + public static $url = 'http://127.0.0.1:8125/'; + public static $port = 8125; /** * Flush the received requests from the server diff --git a/core/vendor/guzzlehttp/guzzle/tests/UrlTest.php b/core/vendor/guzzlehttp/guzzle/tests/UrlTest.php index ce2543d44f25aa10947a0e10422dd7a308e9c9a0..668855dc48addc96003094a88ab31254c4c682f7 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/UrlTest.php +++ b/core/vendor/guzzlehttp/guzzle/tests/UrlTest.php @@ -78,6 +78,9 @@ public function testBuildsRelativeUrlsWithFalsyParts() $url = Url::buildUrl(['path' => '0']); $this->assertSame('0', $url); + + $url = Url::buildUrl(['host' => '', 'path' => '0']); + $this->assertSame('0', $url); } public function testUrlStoresParts() @@ -193,6 +196,7 @@ public function urlCombineDataProvider() [self::RFC3986_BASE, 'g..', 'http://a/b/c/g..'], [self::RFC3986_BASE, '..g', 'http://a/b/c/..g'], [self::RFC3986_BASE, './../g', 'http://a/b/g'], + [self::RFC3986_BASE, 'foo////g', 'http://a/b/c/foo////g'], [self::RFC3986_BASE, './g/.', 'http://a/b/c/g/'], [self::RFC3986_BASE, 'g/./h', 'http://a/b/c/g/h'], [self::RFC3986_BASE, 'g/../h', 'http://a/b/c/h'], @@ -248,7 +252,8 @@ public function urlProvider() { return array( array('/foo/..', '/'), - array('//foo//..', '/'), + array('//foo//..', '//foo/'), + array('/foo//', '/foo//'), array('/foo/../..', '/'), array('/foo/../.', '/'), array('/./foo/..', '/'), diff --git a/core/vendor/guzzlehttp/guzzle/tests/server.js b/core/vendor/guzzlehttp/guzzle/tests/server.js index 4156f1aad787c066990d99367dd855468947f902..d11d28a50c34d71afd3d15e6c5bb80ba8fe04d3f 100644 --- a/core/vendor/guzzlehttp/guzzle/tests/server.js +++ b/core/vendor/guzzlehttp/guzzle/tests/server.js @@ -5,21 +5,21 @@ * * - Delete all requests that have been received: * DELETE /guzzle-server/requests - * Host: 127.0.0.1:8124 + * Host: 127.0.0.1:8125 * * - Enqueue responses * PUT /guzzle-server/responses - * Host: 127.0.0.1:8124 + * Host: 127.0.0.1:8125 * * [{ "statusCode": 200, "reasonPhrase": "OK", "headers": {}, "body": "" }] * * - Get the received requests * GET /guzzle-server/requests - * Host: 127.0.0.1:8124 + * Host: 127.0.0.1:8125 * * - Shutdown the server * DELETE /guzzle-server - * Host: 127.0.0.1:8124 + * Host: 127.0.0.1:8125 * * @package Guzzle PHP <http://www.guzzlephp.org> * @license See the LICENSE file that was distributed with this source code. @@ -132,13 +132,13 @@ var GuzzleServer = function(port, log) { that.server.listen(port, "127.0.0.1"); if (this.log) { - console.log("Server running at http://127.0.0.1:8124/"); + console.log("Server running at http://127.0.0.1:8125/"); } }; }; // Get the port from the arguments -port = process.argv.length >= 3 ? process.argv[2] : 8124; +port = process.argv.length >= 3 ? process.argv[2] : 8125; log = process.argv.length >= 4 ? process.argv[3] : false; // Start the server diff --git a/core/vendor/guzzlehttp/streams/CHANGELOG.rst b/core/vendor/guzzlehttp/streams/CHANGELOG.rst new file mode 100644 index 0000000000000000000000000000000000000000..cdc18f4bc449b6439784306293a5128c2f76597e --- /dev/null +++ b/core/vendor/guzzlehttp/streams/CHANGELOG.rst @@ -0,0 +1,19 @@ +========= +Changelog +========= + +1.3.0 (2014-07-15) +------------------ + +* Added an AppendStream to stream over multiple stream one after the other. + +1.2.0 (2014-07-15) +------------------ + +* Updated the ``detach()`` method to return the underlying stream resource or + ``null`` if it does not wrap a resource. +* Multiple fixes for how streams behave when the underlying resource is + detached +* Do not clear statcache when a stream does not have a 'uri' +* Added a fix to LimitStream +* Added a condition to ensure that functions.php can be required multiple times diff --git a/core/vendor/guzzlehttp/streams/composer.json b/core/vendor/guzzlehttp/streams/composer.json index 6cae568f603f639617274b66d6708a5a5d215c92..d1fc4f57270d0211513e7251696a6c07938eef43 100644 --- a/core/vendor/guzzlehttp/streams/composer.json +++ b/core/vendor/guzzlehttp/streams/composer.json @@ -15,7 +15,7 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "4.*" + "phpunit/phpunit": "~4.0" }, "autoload": { "psr-4": { "GuzzleHttp\\Stream\\": "src/" }, @@ -23,7 +23,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } } } diff --git a/core/vendor/guzzlehttp/streams/src/AppendStream.php b/core/vendor/guzzlehttp/streams/src/AppendStream.php new file mode 100644 index 0000000000000000000000000000000000000000..ffa73962479d4969f0a0375035db321b5e6571ce --- /dev/null +++ b/core/vendor/guzzlehttp/streams/src/AppendStream.php @@ -0,0 +1,212 @@ +<?php + +namespace GuzzleHttp\Stream; + +/** + * Reads from multiple streams, one after the other. + * + * This is a read-only stream decorator. + */ +class AppendStream implements StreamInterface +{ + /** @var StreamInterface[] Streams being decorated */ + private $streams = []; + + private $seekable = true; + private $current = 0; + private $pos = 0; + + /** + * @param StreamInterface[] $streams Streams to decorate. Each stream must + * be readable. + */ + public function __construct(array $streams = []) + { + foreach ($streams as $stream) { + $this->addStream($stream); + } + } + + public function __toString() + { + try { + $this->seek(0); + return $this->getContents(); + } catch (\Exception $e) { + return ''; + } + } + + /** + * Add a stream to the AppendStream + * + * @param StreamInterface $stream Stream to append. Must be readable. + * + * @throws \InvalidArgumentException if the stream is not readable + */ + public function addStream(StreamInterface $stream) + { + if (!$stream->isReadable()) { + throw new \InvalidArgumentException('Each stream must be readable'); + } + + // The stream is only seekable if all streams are seekable + if (!$stream->isSeekable()) { + $this->seekable = false; + } + + $this->streams[] = $stream; + } + + public function getContents($maxLength = -1) + { + return copy_to_string($this, $maxLength); + } + + /** + * Closes each attached stream. + * + * {@inheritdoc} + */ + public function close() + { + $this->pos = $this->current = 0; + + foreach ($this->streams as $stream) { + $stream->close(); + } + + $this->streams = []; + } + + /** + * Detaches each attached stream + * + * {@inheritdoc} + */ + public function detach() + { + $this->streams = []; + $this->close(); + } + + public function tell() + { + return $this->pos; + } + + /** + * Tries to calculate the size by adding the size of each stream. + * + * If any of the streams do not return a valid number, then the size of the + * append stream cannot be determined and null is returned. + * + * {@inheritdoc} + */ + public function getSize() + { + $size = 0; + + foreach ($this->streams as $stream) { + $s = $stream->getSize(); + if ($s === null) { + return null; + } + $size += $s; + } + + return $size; + } + + public function eof() + { + return !$this->streams || + ($this->current >= count($this->streams) - 1 && + $this->streams[$this->current]->eof()); + } + + /** + * Attempts to seek to the given position. Only supports SEEK_SET. + * + * {@inheritdoc} + */ + public function seek($offset, $whence = SEEK_SET) + { + if (!$this->seekable) { + return false; + } elseif ($whence !== SEEK_SET) { + throw new \InvalidArgumentException( + 'AppendStream only supports SEEK_SET' + ); + } + + $success = true; + $this->pos = $this->current = 0; + + // Rewind each stream + foreach ($this->streams as $stream) { + if (!$stream->seek(0)) { + $success = false; + } + } + + if (!$success) { + return false; + } + + // Seek to the actual position by reading from each stream + while ($this->pos < $offset && !$this->eof()) { + $this->read(min(8096, $offset - $this->pos)); + } + + return $this->pos == $offset; + } + + /** + * Reads from all of the appended streams until the length is met or EOF. + * + * {@inheritdoc} + */ + public function read($length) + { + $buffer = ''; + $total = count($this->streams) - 1; + $remaining = $length; + + while ($remaining > 0) { + // Progress to the next stream if needed. + if ($this->streams[$this->current]->eof()) { + if ($this->current == $total) { + break; + } + $this->current++; + } + $buffer .= $this->streams[$this->current]->read($remaining); + $remaining = $length - strlen($buffer); + } + + $this->pos += strlen($buffer); + + return $buffer; + } + + public function isReadable() + { + return true; + } + + public function isWritable() + { + return false; + } + + public function isSeekable() + { + return $this->seekable; + } + + public function write($string) + { + return 0; + } +} diff --git a/core/vendor/guzzlehttp/streams/src/GuzzleStreamWrapper.php b/core/vendor/guzzlehttp/streams/src/GuzzleStreamWrapper.php new file mode 100644 index 0000000000000000000000000000000000000000..9f5a826e67f517b65c0cc79495a1f150a8c97080 --- /dev/null +++ b/core/vendor/guzzlehttp/streams/src/GuzzleStreamWrapper.php @@ -0,0 +1,110 @@ +<?php + +namespace GuzzleHttp\Stream; + +/** + * Converts Guzzle streams into PHP stream resources. + */ +class GuzzleStreamWrapper +{ + /** @var resource */ + public $context; + + /** @var StreamInterface */ + private $stream; + + /** @var string r, r+, or w */ + private $mode; + + /** + * Returns a resource representing the stream. + * + * @param StreamInterface $stream The stream to get a resource for + * + * @return resource + * @throws \InvalidArgumentException if stream is not readable or writable + */ + public static function getResource(StreamInterface $stream) + { + if (!in_array('guzzle', stream_get_wrappers())) { + stream_wrapper_register('guzzle', __CLASS__); + } + + if ($stream->isReadable()) { + $mode = $stream->isWritable() ? 'r+' : 'r'; + } elseif ($stream->isWritable()) { + $mode = 'w'; + } else { + throw new \InvalidArgumentException('The stream must be readable, ' + . 'writable, or both.'); + } + + return fopen('guzzle://stream', $mode, null, stream_context_create([ + 'guzzle' => ['stream' => $stream] + ])); + } + + public function stream_open($path, $mode, $options, &$opened_path) + { + $options = stream_context_get_options($this->context); + + if (!isset($options['guzzle']['stream'])) { + return false; + } + + $this->mode = $mode; + $this->stream = $options['guzzle']['stream']; + + return true; + } + + public function stream_read($count) + { + return $this->stream->read($count); + } + + public function stream_write($data) + { + return (int) $this->stream->write($data); + } + + public function stream_tell() + { + return $this->stream->tell(); + } + + public function stream_eof() + { + return $this->stream->eof(); + } + + public function stream_seek($offset, $whence) + { + return $this->stream->seek($offset, $whence); + } + + public function stream_stat() + { + static $modeMap = [ + 'r' => 33060, + 'r+' => 33206, + 'w' => 33188 + ]; + + return [ + 'dev' => 0, + 'ino' => 0, + 'mode' => $modeMap[$this->mode], + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => $this->stream->getSize() ?: 0, + 'atime' => 0, + 'mtime' => 0, + 'ctime' => 0, + 'blksize' => 0, + 'blocks' => 0 + ]; + } +} diff --git a/core/vendor/guzzlehttp/streams/src/LimitStream.php b/core/vendor/guzzlehttp/streams/src/LimitStream.php index 8c481a42cd65b2a7af440963832e9971020cd65b..63345ba35e3e299eabf4fa72dc188194817eb413 100644 --- a/core/vendor/guzzlehttp/streams/src/LimitStream.php +++ b/core/vendor/guzzlehttp/streams/src/LimitStream.php @@ -40,7 +40,9 @@ public function eof() $tell = $this->stream->tell(); - return $tell === false || (($this->offset + $this->limit) - $tell) <= 0; + return $tell === false || + ($tell >= $this->offset + $this->limit) || + $this->stream->eof(); } /** diff --git a/core/vendor/guzzlehttp/streams/src/Stream.php b/core/vendor/guzzlehttp/streams/src/Stream.php index cc0d6b3b5905b873eb1ea256589e25dbab4c9c07..73eb445f94b1d1df01769ba093b1c6653e067dac 100644 --- a/core/vendor/guzzlehttp/streams/src/Stream.php +++ b/core/vendor/guzzlehttp/streams/src/Stream.php @@ -82,6 +82,10 @@ public function __destruct() public function __toString() { + if (!$this->stream) { + return ''; + } + $this->seek(0); return (string) stream_get_contents($this->stream); @@ -89,7 +93,9 @@ public function __toString() public function getContents($maxLength = -1) { - return stream_get_contents($this->stream, $maxLength); + return $this->stream + ? stream_get_contents($this->stream, $maxLength) + : ''; } public function close() @@ -97,23 +103,33 @@ public function close() if (is_resource($this->stream)) { fclose($this->stream); } + $this->meta = []; $this->stream = null; } public function detach() { - $this->stream = null; + $result = $this->stream; + $this->stream = $this->size = null; + $this->readable = $this->writable = $this->seekable = false; + + return $result; } public function getSize() { if ($this->size !== null) { return $this->size; + } elseif (!$this->stream) { + return null; } // If the stream is a file based stream and local, then use fstat - clearstatcache(true, $this->meta['uri']); + if (isset($this->meta['uri'])) { + clearstatcache(true, $this->meta['uri']); + } + $stats = fstat($this->stream); if (isset($stats['size'])) { $this->size = $stats['size']; @@ -125,27 +141,27 @@ public function getSize() public function isReadable() { - return $this->stream && $this->readable; + return $this->readable; } public function isWritable() { - return $this->stream && $this->writable; + return $this->writable; } public function isSeekable() { - return $this->stream && $this->seekable; + return $this->seekable; } public function eof() { - return feof($this->stream); + return $this->stream && feof($this->stream); } public function tell() { - return ftell($this->stream); + return $this->stream ? ftell($this->stream) : false; } public function setSize($size) @@ -164,7 +180,7 @@ public function seek($offset, $whence = SEEK_SET) public function read($length) { - return fread($this->stream, $length); + return $this->readable ? fread($this->stream, $length) : ''; } public function write($string) @@ -172,7 +188,7 @@ public function write($string) // We can't know the size after writing anything $this->size = null; - return fwrite($this->stream, $string); + return $this->writable ? fwrite($this->stream, $string) : false; } /** diff --git a/core/vendor/guzzlehttp/streams/src/StreamInterface.php b/core/vendor/guzzlehttp/streams/src/StreamInterface.php index 7e07cf73cdbe5921bcf75f4fdb3c084de60272e9..b6b04251cccf578f4d7684f05dd39c8e1bf417c8 100644 --- a/core/vendor/guzzlehttp/streams/src/StreamInterface.php +++ b/core/vendor/guzzlehttp/streams/src/StreamInterface.php @@ -25,7 +25,14 @@ public function close(); /** * Separates any underlying resources from the stream. * - * After the stream has been detached, the stream is in an unusable state. + * After the underlying resource has been detached, the stream object is in + * an unusable state. If you wish to use a Stream object as a PHP stream + * but keep the Stream object in a consistent state, use + * {@see GuzzleHttp\Stream\GuzzleStreamWrapper::getResource}. + * + * @return resource|null Returns the underlying PHP stream resource or null + * if the Stream object did not utilize an underlying + * stream resource. */ public function detach(); @@ -68,7 +75,7 @@ public function isSeekable(); * SEEK_CUR: Set position to current location plus offset * SEEK_END: Set position to end-of-stream plus offset * - * @return bool Returns TRUE on success or FALSE on failure + * @return bool Returns true on success or false on failure * @link http://www.php.net/manual/en/function.fseek.php */ public function seek($offset, $whence = SEEK_SET); @@ -86,7 +93,7 @@ public function isWritable(); * @param string $string The string that is to be written. * * @return int|bool Returns the number of bytes written to the stream on - * success or FALSE on failure. + * success or false on failure. */ public function write($string); diff --git a/core/vendor/guzzlehttp/streams/src/functions.php b/core/vendor/guzzlehttp/streams/src/functions.php index 3e9d99924a59f3b00f8a27a3125f20ef9d46c7c1..057d1db1fe23bb0b71bf7bb6d79feb67b900ed90 100644 --- a/core/vendor/guzzlehttp/streams/src/functions.php +++ b/core/vendor/guzzlehttp/streams/src/functions.php @@ -1,170 +1,174 @@ <?php - namespace GuzzleHttp\Stream; -/** - * Create a new stream based on the input type - * - * @param resource|string|StreamInterface $resource Entity body data - * @param int $size Size of the data contained in the resource - * - * @return StreamInterface - * @throws \InvalidArgumentException if the $resource arg is not valid. - */ -function create($resource = '', $size = null) -{ - $type = gettype($resource); - - if ($type == 'string') { - $stream = fopen('php://temp', 'r+'); - if ($resource !== '') { - fwrite($stream, $resource); - fseek($stream, 0); +if (!defined('GUZZLE_STREAMS_FUNCTIONS')) { + + define('GUZZLE_STREAMS_FUNCTIONS', true); + + /** + * Create a new stream based on the input type + * + * @param resource|string|StreamInterface $resource Entity body data + * @param int $size Size of the data contained in the resource + * + * @return StreamInterface + * @throws \InvalidArgumentException if the $resource arg is not valid. + */ + function create($resource = '', $size = null) + { + $type = gettype($resource); + + if ($type == 'string') { + $stream = fopen('php://temp', 'r+'); + if ($resource !== '') { + fwrite($stream, $resource); + fseek($stream, 0); + } + return new Stream($stream); } - return new Stream($stream); - } - if ($type == 'resource') { - return new Stream($resource, $size); - } + if ($type == 'resource') { + return new Stream($resource, $size); + } - if ($resource instanceof StreamInterface) { - return $resource; - } + if ($resource instanceof StreamInterface) { + return $resource; + } - if ($type == 'object' && method_exists($resource, '__toString')) { - return create((string) $resource, $size); - } + if ($type == 'object' && method_exists($resource, '__toString')) { + return create((string) $resource, $size); + } - throw new \InvalidArgumentException('Invalid resource type: ' . $type); -} + throw new \InvalidArgumentException('Invalid resource type: ' . $type); + } -/** - * Copy the contents of a stream into a string until the given number of bytes - * have been read. - * - * @param StreamInterface $stream Stream to read - * @param int $maxLen Maximum number of bytes to read. Pass -1 to - * read the entire stream. - * @return string - */ -function copy_to_string(StreamInterface $stream, $maxLen = -1) -{ - $buffer = ''; - - if ($maxLen === -1) { - while (!$stream->eof()) { - $buf = $stream->read(1048576); - if ($buf === '' || $buf === false) { - break; + /** + * Copy the contents of a stream into a string until the given number of + * bytes have been read. + * + * @param StreamInterface $stream Stream to read + * @param int $maxLen Maximum number of bytes to read. Pass -1 + * to read the entire stream. + * @return string + */ + function copy_to_string(StreamInterface $stream, $maxLen = -1) + { + $buffer = ''; + + if ($maxLen === -1) { + while (!$stream->eof()) { + $buf = $stream->read(1048576); + if ($buf === '' || $buf === false) { + break; + } + $buffer .= $buf; } - $buffer .= $buf; - } - } else { - $len = 0; - while (!$stream->eof() && $len < $maxLen) { - $buf = $stream->read($maxLen - $len); - if ($buf === '' || $buf === false) { - break; + } else { + $len = 0; + while (!$stream->eof() && $len < $maxLen) { + $buf = $stream->read($maxLen - $len); + if ($buf === '' || $buf === false) { + break; + } + $buffer .= $buf; + $len = strlen($buffer); } - $buffer .= $buf; - $len = strlen($buffer); } + + return $buffer; } - return $buffer; -} + /** + * Copy the contents of a stream into another stream until the given number + * of bytes have been read. + * + * @param StreamInterface $source Stream to read from + * @param StreamInterface $dest Stream to write to + * @param int $maxLen Maximum number of bytes to read. Pass -1 + * to read the entire stream. + */ + function copy_to_stream( + StreamInterface $source, + StreamInterface $dest, + $maxLen = -1 + ) { + if ($maxLen === -1) { + while (!$source->eof()) { + if (!$dest->write($source->read(1048576))) { + break; + } + } + return; + } -/** - * Copy the contents of a stream into another stream until the given number of - * bytes have been read. - * - * @param StreamInterface $source Stream to read from - * @param StreamInterface $dest Stream to write to - * @param int $maxLen Maximum number of bytes to read. Pass -1 to - * read the entire stream. - */ -function copy_to_stream( - StreamInterface $source, - StreamInterface $dest, - $maxLen = -1 -) { - if ($maxLen === -1) { + $bytes = 0; while (!$source->eof()) { - if (!$dest->write($source->read(1048576))) { + $buf = $source->read($maxLen - $bytes); + if (!($len = strlen($buf))) { + break; + } + $bytes += $len; + $dest->write($buf); + if ($bytes == $maxLen) { break; } } - return; } - $bytes = 0; - while (!$source->eof()) { - $buf = $source->read($maxLen - $bytes); - if (!($len = strlen($buf))) { - break; + /** + * Calculate a hash of a Stream + * + * @param StreamInterface $stream Stream to calculate the hash for + * @param string $algo Hash algorithm (e.g. md5, crc32, etc) + * @param bool $rawOutput Whether or not to use raw output + * + * @return bool|string Returns false on failure or a hash string on success + */ + function hash( + StreamInterface $stream, + $algo, + $rawOutput = false + ) { + $pos = $stream->tell(); + if (!$stream->seek(0)) { + return false; } - $bytes += $len; - $dest->write($buf); - if ($bytes == $maxLen) { - break; + + $ctx = hash_init($algo); + while (!$stream->eof()) { + hash_update($ctx, $stream->read(1048576)); } - } -} -/** - * Calculate a hash of a Stream - * - * @param StreamInterface $stream Stream to calculate the hash for - * @param string $algo Hash algorithm (e.g. md5, crc32, etc) - * @param bool $rawOutput Whether or not to use raw output - * - * @return bool|string Returns false on failure or a hash string on success - */ -function hash( - StreamInterface $stream, - $algo, - $rawOutput = false -) { - $pos = $stream->tell(); - if (!$stream->seek(0)) { - return false; - } + $out = hash_final($ctx, (bool) $rawOutput); + $stream->seek($pos); - $ctx = hash_init($algo); - while ($data = $stream->read(1048576)) { - hash_update($ctx, $data); + return $out; } - $out = hash_final($ctx, (bool) $rawOutput); - $stream->seek($pos); + /** + * Read a line from the stream up to the maximum allowed buffer length + * + * @param StreamInterface $stream Stream to read from + * @param int $maxLength Maximum buffer length + * + * @return string|bool + */ + function read_line(StreamInterface $stream, $maxLength = null) + { + $buffer = ''; + $size = 0; - return $out; -} - -/** - * Read a line from the stream up to the maximum allowed buffer length - * - * @param StreamInterface $stream Stream to read from - * @param int $maxLength Maximum buffer length - * - * @return string|bool - */ -function read_line(StreamInterface $stream, $maxLength = null) -{ - $buffer = ''; - $size = 0; - - while (!$stream->eof()) { - if (false === ($byte = $stream->read(1))) { - return $buffer; - } - $buffer .= $byte; - // Break when a new line is found or the max length - 1 is reached - if ($byte == PHP_EOL || ++$size == $maxLength - 1) { - break; + while (!$stream->eof()) { + if (false === ($byte = $stream->read(1))) { + return $buffer; + } + $buffer .= $byte; + // Break when a new line is found or the max length - 1 is reached + if ($byte == PHP_EOL || ++$size == $maxLength - 1) { + break; + } } - } - return $buffer; + return $buffer; + } } diff --git a/core/vendor/guzzlehttp/streams/tests/AppendStreamTest.php b/core/vendor/guzzlehttp/streams/tests/AppendStreamTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b35990d56755bfaeb5a08477c97552b27bc8f04f --- /dev/null +++ b/core/vendor/guzzlehttp/streams/tests/AppendStreamTest.php @@ -0,0 +1,160 @@ +<?php +namespace GuzzleHttp\Tests\Stream; + +use GuzzleHttp\Stream\AppendStream; +use GuzzleHttp\Stream\Stream; + +class AppendStreamTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Each stream must be readable + */ + public function testValidatesStreamsAreReadable() + { + $a = new AppendStream(); + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(false)); + $a->addStream($s); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage only supports SEEK_SET + */ + public function testValidatesSeekType() + { + $a = new AppendStream(); + $a->seek(100, SEEK_CUR); + } + + public function testTriesToRewindOnSeek() + { + $a = new AppendStream(); + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable', 'seek', 'isSeekable']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); + $s->expects($this->once()) + ->method('isSeekable') + ->will($this->returnValue(true)); + $s->expects($this->once()) + ->method('seek') + ->will($this->returnValue(false)); + $a->addStream($s); + $this->assertFalse($a->seek(10)); + } + + public function testSeeksToPositionByReading() + { + $a = new AppendStream([ + Stream::factory('foo'), + Stream::factory('bar'), + Stream::factory('baz'), + ]); + + $this->assertTrue($a->seek(3)); + $this->assertEquals(3, $a->tell()); + $this->assertEquals('bar', $a->read(3)); + $a->seek(6); + $this->assertEquals(6, $a->tell()); + $this->assertEquals('baz', $a->read(3)); + } + + public function testDetachesEachStream() + { + $s1 = Stream::factory('foo'); + $s2 = Stream::factory('foo'); + $a = new AppendStream([$s1, $s2]); + $this->assertSame('foofoo', (string) $a); + $a->detach(); + $this->assertSame('', (string) $a); + $this->assertSame(0, $a->getSize()); + } + + public function testClosesEachStream() + { + $s1 = Stream::factory('foo'); + $a = new AppendStream([$s1]); + $a->close(); + $this->assertSame('', (string) $a); + } + + public function testIsNotWritable() + { + $a = new AppendStream([Stream::factory('foo')]); + $this->assertFalse($a->isWritable()); + $this->assertTrue($a->isSeekable()); + $this->assertTrue($a->isReadable()); + $this->assertSame(0, $a->write('foo')); + } + + public function testDoesNotNeedStreams() + { + $a = new AppendStream(); + $this->assertEquals('', (string) $a); + } + + public function testCanReadFromMultipleStreams() + { + $a = new AppendStream([ + Stream::factory('foo'), + Stream::factory('bar'), + Stream::factory('baz'), + ]); + $this->assertFalse($a->eof()); + $this->assertSame(0, $a->tell()); + $this->assertEquals('foo', $a->read(3)); + $this->assertEquals('bar', $a->read(3)); + $this->assertEquals('baz', $a->read(3)); + $this->assertTrue($a->eof()); + $this->assertSame(9, $a->tell()); + $this->assertEquals('foobarbaz', (string) $a); + } + + public function testCanDetermineSizeFromMultipleStreams() + { + $a = new AppendStream([ + Stream::factory('foo'), + Stream::factory('bar') + ]); + $this->assertEquals(6, $a->getSize()); + + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isSeekable', 'isReadable']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('isSeekable') + ->will($this->returnValue(null)); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); + $a->addStream($s); + $this->assertNull($a->getSize()); + } + + public function testCatchesExceptionsWhenCastingToString() + { + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['read', 'isReadable', 'eof']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('read') + ->will($this->throwException(new \RuntimeException('foo'))); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); + $s->expects($this->any()) + ->method('eof') + ->will($this->returnValue(false)); + $a = new AppendStream([$s]); + $this->assertFalse($a->eof()); + $this->assertSame('', (string) $a); + } +} diff --git a/core/vendor/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php b/core/vendor/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2a4c4db66ae1c5a5ffb9b6309891000af9719741 --- /dev/null +++ b/core/vendor/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php @@ -0,0 +1,100 @@ +<?php + +namespace GuzzleHttp\Tests\Stream; + +use GuzzleHttp\Stream\GuzzleStreamWrapper; +use GuzzleHttp\Stream\Stream; + +/** + * @covers GuzzleHttp\Stream\GuzzleStreamWrapper + */ +class GuzzleStreamWrapperTest extends \PHPUnit_Framework_TestCase +{ + public function testResource() + { + $stream = Stream::factory('foo'); + $handle = GuzzleStreamWrapper::getResource($stream); + $this->assertSame('foo', fread($handle, 3)); + $this->assertSame(3, ftell($handle)); + $this->assertSame(3, fwrite($handle, 'bar')); + $this->assertSame(0, fseek($handle, 0)); + $this->assertSame('foobar', fread($handle, 6)); + $this->assertTrue(feof($handle)); + + // This fails on HHVM for some reason + if (!defined('HHVM_VERSION')) { + $this->assertEquals([ + 'dev' => 0, + 'ino' => 0, + 'mode' => 33206, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => 6, + 'atime' => 0, + 'mtime' => 0, + 'ctime' => 0, + 'blksize' => 0, + 'blocks' => 0, + 0 => 0, + 1 => 0, + 2 => 33206, + 3 => 0, + 4 => 0, + 5 => 0, + 6 => 0, + 7 => 6, + 8 => 0, + 9 => 0, + 10 => 0, + 11 => 0, + 12 => 0, + ], fstat($handle)); + } + + $this->assertTrue(fclose($handle)); + $this->assertSame('foobar', (string) $stream); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testValidatesStream() + { + $stream = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable', 'isWritable']) + ->getMockForAbstractClass(); + $stream->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(false)); + $stream->expects($this->once()) + ->method('isWritable') + ->will($this->returnValue(false)); + GuzzleStreamWrapper::getResource($stream); + } + + /** + * @expectedException \PHPUnit_Framework_Error_Warning + */ + public function testReturnsFalseWhenStreamDoesNotExist() + { + fopen('guzzle://foo', 'r'); + } + + public function testCanOpenReadonlyStream() + { + $stream = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable', 'isWritable']) + ->getMockForAbstractClass(); + $stream->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(false)); + $stream->expects($this->once()) + ->method('isWritable') + ->will($this->returnValue(true)); + $r = GuzzleStreamWrapper::getResource($stream); + $this->assertInternalType('resource', $r); + fclose($r); + } +} diff --git a/core/vendor/guzzlehttp/streams/tests/StreamTest.php b/core/vendor/guzzlehttp/streams/tests/StreamTest.php index d1460aa8a0eb6ed4f50f4ae35c4ee5fc4e4bece0..d8a4d7e2356168a70842205f60b1f22ada5f6acf 100644 --- a/core/vendor/guzzlehttp/streams/tests/StreamTest.php +++ b/core/vendor/guzzlehttp/streams/tests/StreamTest.php @@ -135,8 +135,19 @@ public function testCanDetachStream() $r = fopen('php://temp', 'w+'); $stream = new Stream($r); $this->assertTrue($stream->isReadable()); - $stream->detach(); + $this->assertSame($r, $stream->detach()); + $this->assertNull($stream->detach()); $this->assertFalse($stream->isReadable()); + $this->assertSame('', $stream->read(10)); + $this->assertFalse($stream->isWritable()); + $this->assertFalse($stream->write('foo')); + $this->assertFalse($stream->isSeekable()); + $this->assertFalse($stream->seek(10)); + $this->assertFalse($stream->tell()); + $this->assertFalse($stream->eof()); + $this->assertNull($stream->getSize()); + $this->assertSame('', (string) $stream); + $this->assertSame('', $stream->getContents()); $stream->close(); }