Issue #2276119 by damiankloip: Upgrade Guzzle to version 4.1.0.
parent
c8faf220f0
commit
116b4f7cee
|
@ -19,7 +19,7 @@
|
|||
"twig/twig": "1.15.*",
|
||||
"doctrine/common": "dev-master#a45d110f71c323e29f41eb0696fa230e3fa1b1b5",
|
||||
"doctrine/annotations": "dev-master#463d926a8dcc49271cb7db5a08364a70ed6e3cd3",
|
||||
"guzzlehttp/guzzle": "4.0.*",
|
||||
"guzzlehttp/guzzle": "4.1.*",
|
||||
"kriswallsmith/assetic": "1.1.*@alpha",
|
||||
"symfony-cmf/routing": "1.1.*@alpha",
|
||||
"easyrdf/easyrdf": "0.8.*",
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "cc429f39777a4435a2d1415648978f97",
|
||||
"hash": "15b33bcba2392fb947bc320f35fcc14e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
@ -458,26 +459,30 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "4063f08ca434efac12bf7a3db0d370b1c451345b"
|
||||
"reference": "85a0ba7de064493c928a8bcdc5eef01e0bde9953"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/4063f08ca434efac12bf7a3db0d370b1c451345b",
|
||||
"reference": "4063f08ca434efac12bf7a3db0d370b1c451345b",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/85a0ba7de064493c928a8bcdc5eef01e0bde9953",
|
||||
"reference": "85a0ba7de064493c928a8bcdc5eef01e0bde9953",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/streams": "1.*",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/streams": "~1.0",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "4.*",
|
||||
"psr/log": "~1"
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "Guzzle will use specific adapters if cURL is present"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -515,7 +520,7 @@
|
|||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2014-03-29 23:11:36"
|
||||
"time": "2014-05-28 05:13:19"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/streams",
|
||||
|
@ -2098,12 +2103,8 @@
|
|||
"time": "2013-06-12 19:46:58"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
],
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"symfony/yaml": 20,
|
||||
|
@ -2115,7 +2116,5 @@
|
|||
"platform": {
|
||||
"php": ">=5.4.2"
|
||||
},
|
||||
"platform-dev": [
|
||||
|
||||
]
|
||||
"platform-dev": []
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ class ClassLoader
|
|||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
include $file;
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -291,8 +291,25 @@ class ClassLoader
|
|||
return $this->classMap[$class];
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if ($file === null && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if ($file === null) {
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
|
@ -321,7 +338,7 @@ class ClassLoader
|
|||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . '.php';
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
|
@ -347,8 +364,15 @@ class ClassLoader
|
|||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname(dirname($vendorDir));
|
||||
|
||||
return array(
|
||||
$vendorDir . '/kriswallsmith/assetic/src/functions.php',
|
||||
$vendorDir . '/guzzlehttp/streams/src/functions.php',
|
||||
$vendorDir . '/kriswallsmith/assetic/src/functions.php',
|
||||
$vendorDir . '/guzzlehttp/guzzle/src/functions.php',
|
||||
$baseDir . '/core/lib/Drupal.php',
|
||||
);
|
||||
|
|
|
@ -49,9 +49,14 @@ class ComposerAutoloaderInitDrupal8
|
|||
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
foreach ($includeFiles as $file) {
|
||||
require $file;
|
||||
composerRequireDrupal8($file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequireDrupal8($file)
|
||||
{
|
||||
require $file;
|
||||
}
|
||||
|
|
|
@ -2049,69 +2049,6 @@
|
|||
"stream"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "4.0.0",
|
||||
"version_normalized": "4.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "4063f08ca434efac12bf7a3db0d370b1c451345b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/4063f08ca434efac12bf7a3db0d370b1c451345b",
|
||||
"reference": "4063f08ca434efac12bf7a3db0d370b1c451345b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/streams": "1.*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "4.*",
|
||||
"psr/log": "~1"
|
||||
},
|
||||
"time": "2014-03-29 23:11:36",
|
||||
"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": "symfony/css-selector",
|
||||
"version": "v2.4.4",
|
||||
|
@ -2166,5 +2103,72 @@
|
|||
],
|
||||
"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"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,6 +1,36 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
4.1.0 (2014-05-27)
|
||||
------------------
|
||||
|
||||
* Added a `json` request option to easily serialize JSON payloads.
|
||||
* Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON.
|
||||
* Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`.
|
||||
* Added the ability to provide an emitter to a client in the client constructor.
|
||||
* Added the ability to persist a cookie session using $_SESSION.
|
||||
* Added a trait that can be used to add event listeners to an iterator.
|
||||
* Removed request method constants from RequestInterface.
|
||||
* Fixed warning when invalid request start-lines are received.
|
||||
* Updated MessageFactory to work with custom request option methods.
|
||||
* Updated cacert bundle to latest build.
|
||||
|
||||
4.0.2 (2014-04-16)
|
||||
------------------
|
||||
|
||||
* Proxy requests using the StreamAdapter now properly use request_fulluri (#632)
|
||||
* Added the ability to set scalars as POST fields (#628)
|
||||
|
||||
4.0.1 (2014-04-04)
|
||||
------------------
|
||||
|
||||
* The HTTP status code of a response is now set as the exception code of
|
||||
RequestException objects.
|
||||
* 303 redirects will now correctly switch from POST to GET requests.
|
||||
* The default parallel adapter of a client now correctly uses the MultiAdapter.
|
||||
* HasDataTrait now initializes the internal data array as an empty array so
|
||||
that the toArray() method always returns an array.
|
||||
|
||||
4.0.0 (2014-03-29)
|
||||
------------------
|
||||
|
||||
|
@ -18,7 +48,7 @@ CHANGELOG
|
|||
-----------------------
|
||||
|
||||
* Removed `getConfig()` and `setConfig()` from clients to avoid confusion
|
||||
around whether things like base_url, message_factory, etc should be able to
|
||||
around whether things like base_url, message_factory, etc. should be able to
|
||||
be retrieved or modified.
|
||||
* Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface
|
||||
* functions.php functions were renamed using snake_case to match PHP idioms
|
||||
|
@ -150,11 +180,11 @@ CHANGELOG
|
|||
* See UPGRADING.md for more information on how to upgrade.
|
||||
* Requests now support the ability to specify an array of $options when creating a request to more easily modify a
|
||||
request. You can pass a 'request.options' configuration setting to a client to apply default request options to
|
||||
every request created by a client (e.g. default query string variables, headers, curl options, etc).
|
||||
every request created by a client (e.g. default query string variables, headers, curl options, etc.).
|
||||
* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
|
||||
See `Guzzle\Http\StaticClient::mount`.
|
||||
* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
|
||||
created by a command (e.g. custom headers, query string variables, timeout settings, etc).
|
||||
created by a command (e.g. custom headers, query string variables, timeout settings, etc.).
|
||||
* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
|
||||
headers of a response
|
||||
* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
|
||||
|
@ -251,7 +281,7 @@ CHANGELOG
|
|||
* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
|
||||
* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
|
||||
* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
|
||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
|
||||
directly via interfaces
|
||||
* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
||||
but are a no-op until removed.
|
||||
|
@ -508,7 +538,7 @@ CHANGELOG
|
|||
3.0.1 (2012-10-22)
|
||||
------------------
|
||||
|
||||
* Models can now be used like regular collection objects by calling filter, map, etc
|
||||
* Models can now be used like regular collection objects by calling filter, map, etc.
|
||||
* Models no longer require a Parameter structure or initial data in the constructor
|
||||
* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
|
||||
|
||||
|
@ -800,6 +830,6 @@ CHANGELOG
|
|||
* Emitting an event each time a client is generated by a ServiceBuilder
|
||||
* Using an ApiParams object instead of a Collection for parameters of an ApiCommand
|
||||
* cache.* request parameters should be renamed to params.cache.*
|
||||
* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc). See CurlHandle.
|
||||
* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle.
|
||||
* Added the ability to disable type validation of service descriptions
|
||||
* ServiceDescriptions and ServiceBuilders are now Serializable
|
||||
|
|
|
@ -24,7 +24,7 @@ var_export($res->json());
|
|||
- Doesn't require cURL, but uses cURL by default
|
||||
- Streams data for both uploads and downloads
|
||||
- Provides event hooks & plugins for cookies, caching, logging, OAuth, mocks,
|
||||
etc...
|
||||
etc.
|
||||
- Keep-Alive & connection pooling
|
||||
- SSL Verification
|
||||
- Automatic decompression of response bodies
|
||||
|
|
|
@ -59,7 +59,7 @@ Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses
|
|||
`GuzzleHttp\Event\EventInterface`.
|
||||
- `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and
|
||||
`HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the
|
||||
event emitter of a request, client, etc now uses the `getEmitter` method
|
||||
event emitter of a request, client, etc. now uses the `getEmitter` method
|
||||
rather than the `getDispatcher` method.
|
||||
|
||||
#### Emitter
|
||||
|
@ -152,7 +152,7 @@ $response = $client->send($request);
|
|||
- The client no longer emits a `client.create_request` event.
|
||||
- Creating requests with a client no longer automatically utilize a URI
|
||||
template. You must pass an array into a creational method (e.g.,
|
||||
`createRequest`, `get`, `put`, etc...) in order to expand a URI template.
|
||||
`createRequest`, `get`, `put`, etc.) in order to expand a URI template.
|
||||
|
||||
### Messages
|
||||
|
||||
|
@ -444,7 +444,7 @@ that contain additonal metadata accessible via `getMetadata()`.
|
|||
`GuzzleHttp\Stream\StreamInterface::getMetadata` and
|
||||
`GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed.
|
||||
|
||||
## SteamRequestFactory
|
||||
## StreamRequestFactory
|
||||
|
||||
The entire concept of the StreamRequestFactory has been removed. The way this
|
||||
was used in Guzzle 3 broke the actual interface of sending streaming requests
|
||||
|
@ -563,7 +563,7 @@ that implement them, but you should update your code to use alternative methods:
|
|||
* Moved getLinks() from Response to just be used on a Link header object.
|
||||
|
||||
If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
|
||||
HeaderInterface (e.g. toArray(), getAll(), etc).
|
||||
HeaderInterface (e.g. toArray(), getAll(), etc.).
|
||||
|
||||
### Interface changes
|
||||
|
||||
|
@ -591,7 +591,7 @@ HeaderInterface (e.g. toArray(), getAll(), etc).
|
|||
### Other changes
|
||||
|
||||
* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
|
||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
|
||||
directly via interfaces
|
||||
* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
||||
but are a no-op until removed.
|
||||
|
@ -619,7 +619,7 @@ The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
|
|||
|
||||
### Stream wrapper and type
|
||||
|
||||
`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to lowercase.
|
||||
`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase.
|
||||
|
||||
### curl.emit_io became emit_io
|
||||
|
||||
|
|
|
@ -16,7 +16,12 @@
|
|||
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"guzzlehttp/streams": "1.*"
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/streams": "~1.0"
|
||||
},
|
||||
|
||||
"suggest": {
|
||||
"ext-curl": "Guzzle will use specific adapters if cURL is present"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
|
@ -28,8 +33,8 @@
|
|||
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"psr/log": "~1",
|
||||
"phpunit/phpunit": "4.*"
|
||||
"psr/log": "~1.0",
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
|
||||
"extra": {
|
||||
|
|
|
@ -18,7 +18,7 @@ If cURL is present, Guzzle will use the following adapters by default:
|
|||
``GuzzleHttp\Adapter\StreamingProxyAdapter`` is added so that streaming
|
||||
requests are sent using the PHP stream wrapper. If this setting is disabled,
|
||||
then streaming requests are sent through a cURL adapter.
|
||||
- If using PHP 5.5 or greater, then a a ``GuzzleHttp\Adapter\Curl\CurlAdapter``
|
||||
- If using PHP 5.5 or greater, then a ``GuzzleHttp\Adapter\Curl\CurlAdapter``
|
||||
is used to send serial requests. Otherwise, the
|
||||
``GuzzleHttp\Adapter\Curl\MultiAdapter`` is used for serial and parallel
|
||||
requests.
|
||||
|
|
|
@ -5,7 +5,7 @@ Clients
|
|||
Clients are used to create requests, create transactions, send requests
|
||||
through an HTTP adapter, and return a response. You can add default request
|
||||
options to a client that are applied to every request (e.g., default headers,
|
||||
default query string parameters, etc), and you can add event listeners and
|
||||
default query string parameters, etc.), and you can add event listeners and
|
||||
subscribers to every request created by a client.
|
||||
|
||||
Creating a client
|
||||
|
@ -56,6 +56,11 @@ defaults
|
|||
default headers (e.g., User-Agent), default query string parameters, SSL
|
||||
configurations, and any other supported request options.
|
||||
|
||||
emitter
|
||||
Specifies an event emitter (``GuzzleHttp\Event\EmitterInterface``) instance
|
||||
to be used by the client to emit request events. This option is useful if
|
||||
you need to inject an emitter with listeners/subscribers already attached.
|
||||
|
||||
Here's an example of creating a client with various options, including using
|
||||
a mock adapter that just returns the result of a callable function and a
|
||||
base URL that is a URI template with parameters.
|
||||
|
@ -245,7 +250,7 @@ request using event callbacks.
|
|||
// Do something with the completion of the request...
|
||||
},
|
||||
'error' => function (ErrorEvent $event) {
|
||||
echo 'Request failed: ' . $event->getRequest()->getUrl() . "\n"
|
||||
echo 'Request failed: ' . $event->getRequest()->getUrl() . "\n";
|
||||
echo $event->getException();
|
||||
// Do something to handle the error...
|
||||
}
|
||||
|
@ -297,7 +302,7 @@ immeditaley and prevent subsequent requests from being sent.
|
|||
}
|
||||
]);
|
||||
|
||||
.. _request-options:
|
||||
.. _batch-requests:
|
||||
|
||||
Batching Requests
|
||||
-----------------
|
||||
|
@ -338,6 +343,8 @@ events as well as specify the maximum number of request 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()``.
|
||||
|
||||
.. _request-options:
|
||||
|
||||
Request Options
|
||||
===============
|
||||
|
||||
|
@ -425,6 +432,33 @@ This setting can be set to any of the following types:
|
|||
$stream = GuzzleHttp\Stream\Stream::factory('contents...');
|
||||
$client->post('/post', ['body' => $stream]);
|
||||
|
||||
json
|
||||
----
|
||||
|
||||
:Summary: The ``json`` option is used to easily upload JSON encoded data as the
|
||||
body of a request. A Content-Type header of ``application/json`` will be
|
||||
added if no Content-Type header is already present on the message.
|
||||
:Types:
|
||||
Any PHP type that can be operated on by PHP's ``json_encode()`` function.
|
||||
:Default: None
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$request = $client->createRequest('/put', ['json' => ['foo' => 'bar']]);
|
||||
echo $request->getHeader('Content-Type');
|
||||
// application/json
|
||||
echo $request->getBody();
|
||||
// {"foo":"bar"}
|
||||
|
||||
.. note::
|
||||
|
||||
This request option does not support customizing the Content-Type header
|
||||
or any of the options from PHP's `json_encode() <http://www.php.net/manual/en/function.json-encode.php>`_
|
||||
function. If you need to customize these settings, then you must pass the
|
||||
JSON encoded data into the request yourself using the ``body`` request
|
||||
option and you must specify the correct Content-Type header using the
|
||||
``headers`` request option.
|
||||
|
||||
query
|
||||
-----
|
||||
|
||||
|
@ -437,7 +471,7 @@ query
|
|||
.. code-block:: php
|
||||
|
||||
// Send a GET request to /get?foo=bar
|
||||
$client->get('/get', ['query' => ['foo' => 'bar']);
|
||||
$client->get('/get', ['query' => ['foo' => 'bar']]);
|
||||
|
||||
Query strings specified in the ``query`` option are combined with any query
|
||||
string values that are parsed from the URL.
|
||||
|
@ -445,7 +479,7 @@ string values that are parsed from the URL.
|
|||
.. code-block:: php
|
||||
|
||||
// Send a GET request to /get?abc=123&foo=bar
|
||||
$client->get('/get?abc=123', ['query' => ['foo' => 'bar']);
|
||||
$client->get('/get?abc=123', ['query' => ['foo' => 'bar']]);
|
||||
|
||||
auth
|
||||
----
|
||||
|
@ -510,7 +544,7 @@ to ensure that they are fired last or near last in the event chain.
|
|||
* Listens to the "before" event of a request and only modifies the request
|
||||
* when the "auth" config setting of the request is "foo".
|
||||
*/
|
||||
class FooAuth implements GuzzleHttp\Common\SubscriberInterface
|
||||
class FooAuth implements GuzzleHttp\Event\SubscriberInterface
|
||||
{
|
||||
private $password;
|
||||
|
||||
|
@ -532,14 +566,14 @@ to ensure that they are fired last or near last in the event chain.
|
|||
}
|
||||
}
|
||||
|
||||
$client->getEmitter->attach(new FooAuth('password'));
|
||||
$client->getEmitter()->attach(new FooAuth('password'));
|
||||
$client->get('/', ['auth' => 'foo']);
|
||||
|
||||
Adapter Specific Authentication Schemes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you need to use authentication methods provided by cURL (e.g., NTLM, GSS,
|
||||
etc...), then you need to specify a curl adapter option in the ``options``
|
||||
etc.), then you need to specify a curl adapter option in the ``options``
|
||||
request option array. See :ref:`config-option` for more information.
|
||||
|
||||
.. _cookies-option:
|
||||
|
|
|
@ -83,7 +83,7 @@ Adding Event Listeners
|
|||
After you have the emitter, you can register event listeners that listen to
|
||||
specific events using the ``on()`` method. When registering an event listener,
|
||||
you must tell the emitter what event to listen to (e.g., "before", "after",
|
||||
"headers", "complete", "error", etc...), what callable to invoke when the
|
||||
"headers", "complete", "error", etc.), what callable to invoke when the
|
||||
event is triggered, and optionally provide a priority.
|
||||
|
||||
.. code-block:: php
|
||||
|
@ -323,7 +323,7 @@ a ``GuzzleHttp\Event\BeforeEvent``.
|
|||
echo $name . "\n";
|
||||
// "before"
|
||||
echo $e->getRequest()->getMethod() . "\n";
|
||||
// "GET" / "POST" / "PUT" / etc...
|
||||
// "GET" / "POST" / "PUT" / etc.
|
||||
echo get_class($e->getClient());
|
||||
// "GuzzleHttp\Client"
|
||||
}
|
||||
|
|
|
@ -2,11 +2,91 @@
|
|||
FAQ
|
||||
===
|
||||
|
||||
Why should I use Guzzle?
|
||||
========================
|
||||
|
||||
Guzzle makes it easy to send HTTP requests and super simple to integrate with
|
||||
web services. Guzzle manages things like persistent connections, represents
|
||||
query strings as collections, makes it simple to send streaming POST requests
|
||||
with fields and files, and abstracts away the underlying HTTP transport layer
|
||||
(cURL, ``fopen()``, etc.). By providing an object oriented interface for HTTP
|
||||
clients, requests, responses, headers, and message bodies, Guzzle makes it so
|
||||
that you no longer need to fool around with cURL options or stream contexts.
|
||||
|
||||
To get a feel for how easy it is to use Guzzle, take a look at the
|
||||
:doc:`quick start guide <quickstart>`.
|
||||
|
||||
Swappable HTTP Adapters
|
||||
-----------------------
|
||||
|
||||
Guzzle will use the most appropriate HTTP adapter to send requests based on the
|
||||
capabilities of your environment and the options applied to a request. When
|
||||
cURL is available on your system, Guzzle will automatically use cURL. When a
|
||||
request is sent with the ``stream=true`` request option, Guzzle will
|
||||
automatically use the PHP stream wrapper HTTP adapter so that bytes are only
|
||||
read from the HTTP stream as needed.
|
||||
|
||||
.. note::
|
||||
|
||||
Guzzle has historically only utilized cURL to send HTTP requests. cURL is
|
||||
an amazing HTTP client (arguably the best), and Guzzle will continue to use
|
||||
it by default when it is available. It is rare, but some developers don't
|
||||
have cURL installed on their systems or run into version specific issues.
|
||||
By allowing swappable HTTP adapters, Guzzle is now much more customizable
|
||||
and able to adapt to fit the needs of more developers.
|
||||
|
||||
HTTP Streams
|
||||
------------
|
||||
|
||||
Request and response message bodies use :doc:`Guzzle Streams <streams>`,
|
||||
allowing you to stream data without needing to load it all into memory.
|
||||
Guzzle's stream layer provides a large suite of functionality:
|
||||
|
||||
- You can modify streams at runtime using custom or a number of
|
||||
pre-made decorators.
|
||||
- You can emit progress events as data is read from a stream.
|
||||
- You can validate the integrity of a stream using a rolling hash as data is
|
||||
read from a stream.
|
||||
|
||||
Event System
|
||||
------------
|
||||
|
||||
Guzzle's flexible event system allows you to completely modify the behavior
|
||||
of a client or request at runtime to cater them for any API. You can send a
|
||||
request with a client, and the client can do things like automatically retry
|
||||
your request if it fails, automatically redirect, log HTTP messages that are
|
||||
sent over the wire, emit progress events as data is uploaded and downloaded,
|
||||
sign requests using OAuth 1.0, verify the integrity of messages before and
|
||||
after they are sent over the wire, and anything else you might need.
|
||||
|
||||
Easy to Test
|
||||
------------
|
||||
|
||||
Another important aspect of Guzzle is that it's really
|
||||
:doc:`easy to test clients <testing>`. You can mock HTTP responses and when
|
||||
testing an adapter implementation, Guzzle provides a mock web server that
|
||||
makes it easy.
|
||||
|
||||
Large Ecosystem
|
||||
---------------
|
||||
|
||||
Guzzle has a large `ecosystem of plugins <http://guzzle.readthedocs.org/en/latest/index.html#http-components>`_,
|
||||
including `service descriptions <https://github.com/guzzle/guzzle-services>`_
|
||||
which allows you to abstract web services using service descriptions. These
|
||||
service descriptions define how to serialize an HTTP request and how to parse
|
||||
an HTTP response into a more meaningful model object.
|
||||
|
||||
- `Guzzle Command <https://github.com/guzzle/command>`_: Provides the building
|
||||
blocks for service description abstraction.
|
||||
- `Guzzle Services <https://github.com/guzzle/guzzle-services>`_: Provides an
|
||||
implementation of "Guzzle Command" that utlizes Guzzle's service description
|
||||
format.
|
||||
|
||||
Is it possible to use Guzzle 3 and 4 in the same project?
|
||||
=========================================================
|
||||
|
||||
Yes, because Guzzle 3 and 4 use different Packagist packages and different
|
||||
namespaced. You simply need to add ``guzzle/guzzle`` (Guzzle 3) and
|
||||
namespaces. You simply need to add ``guzzle/guzzle`` (Guzzle 3) and
|
||||
``guzzlehttp/guzzle`` (Guzzle 4+) to your project's composer.json file.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
|
|
@ -70,7 +70,7 @@ You can check to see if a request or response has a body using the
|
|||
The body used in request and response objects is a
|
||||
``GuzzleHttp\Stream\StreamInterface``. This stream is used for both uploading
|
||||
data and downloading data. Guzzle will, by default, store the body of a message
|
||||
in a stream that uses PHP temp streams. When the size of a the body exceeds
|
||||
in a stream that uses PHP temp streams. When the size of the body exceeds
|
||||
2 MB, the stream will automatically switch to storing data on disk rather than
|
||||
in memory (protecting your application from memory exhaustion).
|
||||
|
||||
|
@ -127,7 +127,7 @@ Request Methods
|
|||
---------------
|
||||
|
||||
When creating a request, you are expected to provide the HTTP method you wish
|
||||
to perform. You can specfiy any method you'd like, including a custom method
|
||||
to perform. You can specify any method you'd like, including a custom method
|
||||
that might not be part of RFC 2616 (like "MOVE").
|
||||
|
||||
.. code-block:: php
|
||||
|
|
|
@ -10,7 +10,7 @@ the pain out of consuming web services.
|
|||
- Pluggable HTTP adapters that can send requests serially or in parallel
|
||||
- Doesn't require cURL, but uses cURL by default
|
||||
- Streams data for both uploads and downloads
|
||||
- Provides event hooks & plugins for cookies, caching, logging, OAuth, mocks, etc...
|
||||
- Provides event hooks & plugins for cookies, caching, logging, OAuth, mocks, etc.
|
||||
- Keep-Alive & connection pooling
|
||||
- SSL Verification
|
||||
- Automatic decompression of response bodies
|
||||
|
@ -20,16 +20,13 @@ the pain out of consuming web services.
|
|||
.. code-block:: php
|
||||
|
||||
$client = new GuzzleHttp\Client();
|
||||
$response = $client->get('http://guzzlephp.org');
|
||||
$res = $client->get('https://api.github.com/user', ['auth' => ['user', 'pass']]);
|
||||
echo $res->statusCode();
|
||||
// 200
|
||||
echo $res->getHeader('content-type');
|
||||
// 'application/json; charset=utf8'
|
||||
echo $res->getBody();
|
||||
// {"type":"User"...'
|
||||
var_export($res->json());
|
||||
// Outputs the JSON decoded data
|
||||
$res = $client->get('https://api.github.com/user', [
|
||||
'auth' => ['user', 'pass']
|
||||
]);
|
||||
echo $res->getStatusCode(); // 200
|
||||
echo $res->getHeader('content-type'); // 'application/json; charset=utf8'
|
||||
echo $res->getBody(); // {"type":"User"...'
|
||||
var_export($res->json()); // Outputs the JSON decoded data
|
||||
|
||||
User guide
|
||||
----------
|
||||
|
@ -68,7 +65,7 @@ layer to add capabilities to the client.
|
|||
|
||||
`Retry Subscriber <https://github.com/guzzle/retry-subscriber>`_
|
||||
Retries failed requests using customizable retry strategies (e.g., retry
|
||||
based on response status code, cURL error codes, etc...)
|
||||
based on response status code, cURL error codes, etc.)
|
||||
|
||||
`Message Integrity Subscriber <https://github.com/guzzle/message-integrity-subscriber>`_
|
||||
Verifies the message integrity of HTTP responses using customizable
|
||||
|
|
|
@ -276,19 +276,33 @@ or response object.
|
|||
echo $request->getHeader('X-Foo');
|
||||
// Echoes an empty string: ''
|
||||
|
||||
POST Requests
|
||||
=============
|
||||
Uploading Data
|
||||
==============
|
||||
|
||||
You can send POST requests that contain a raw POST body by passing a
|
||||
string, resource returned from ``fopen``, or a
|
||||
``GuzzleHttp\Stream\StreamInterface`` object to the ``body`` request option.
|
||||
Guzzle provides several methods of uploading data.
|
||||
|
||||
You can send requests that contain a stream of data by passing a string,
|
||||
resource returned from ``fopen``, or a ``GuzzleHttp\Stream\StreamInterface``
|
||||
object to the ``body`` request option.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$r = $client->post('http://httpbin.org/post', ['body' => 'raw data']);
|
||||
|
||||
You can easily upload JSON data using the ``json`` request option.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$r = $client->put('http://httpbin.org/put', ['json' => ['foo' => 'bar']]);
|
||||
|
||||
POST Requests
|
||||
-------------
|
||||
|
||||
In addition to specifying the raw data of a request using the ``body`` request
|
||||
option, Guzzle provides helpful abstractions over sending POST data.
|
||||
|
||||
Sending POST Fields
|
||||
-------------------
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sending ``application/x-www-form-urlencoded`` POST requests requires that you
|
||||
specify the body of a POST request as an array.
|
||||
|
@ -321,7 +335,7 @@ You can also build up POST requests before sending them.
|
|||
$response = $client->send($request);
|
||||
|
||||
Sending POST Files
|
||||
------------------
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sending ``multipart/form-data`` POST requests (POST requests that contain
|
||||
files) is the same as sending ``application/x-www-form-urlencoded``, except
|
||||
|
@ -404,7 +418,7 @@ Exceptions
|
|||
|
||||
Guzzle throws exceptions for errors that occur during a transfer.
|
||||
|
||||
- In the event of a networking error (connection timeout, DNS errors, etc),
|
||||
- In the event of a networking error (connection timeout, DNS errors, etc.),
|
||||
a ``GuzzleHttp\Exception\RequestException`` is thrown. This exception
|
||||
extends from ``GuzzleHttp\Exception\TransferException``. Catching this
|
||||
exception will catch any exception that can be thrown while transferring
|
||||
|
@ -424,7 +438,7 @@ Guzzle throws exceptions for errors that occur during a transfer.
|
|||
}
|
||||
|
||||
- A ``GuzzleHttp\Exception\ClientErrorResponseException`` is thrown for 400
|
||||
level errors if the ``exceptions`` request option is not set to true. This
|
||||
level errors if the ``exceptions`` request option is set to true. This
|
||||
exception extends from ``GuzzleHttp\Exception\BadResponseException`` and
|
||||
``GuzzleHttp\Exception\BadResponseException`` extends from
|
||||
``GuzzleHttp\Exception\RequestException``.
|
||||
|
@ -441,11 +455,10 @@ Guzzle throws exceptions for errors that occur during a transfer.
|
|||
}
|
||||
|
||||
- A ``GuzzleHttp\Exception\ServerErrorResponse`` is thrown for 500 level
|
||||
errors if the ``exceptions`` request option is not set to true. This
|
||||
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
|
||||
many redirects are followed. This exception extends from extends from
|
||||
``GuzzleHttp\Exception\RequestException``.
|
||||
many redirects are followed. This exception extends from ``GuzzleHttp\Exception\RequestException``.
|
||||
- A ``GuzzleHttp\Exception\AdapterException`` is thrown when an error occurs
|
||||
in an HTTP adapter during a parallel request. This exception is only thrown
|
||||
when using the ``sendAll()`` method of a client.
|
||||
|
|
|
@ -32,16 +32,16 @@ remote API.
|
|||
// Create a mock subscriber and queue two responses.
|
||||
$mock = new Mock([
|
||||
new Response(200, ['X-Foo' => 'Bar']), // Use response object
|
||||
"HTTP/1.1 202 OKr\nContent-Length: 0\r\n\r\n" // Use a response string
|
||||
"HTTP/1.1 202 OK\r\nContent-Length: 0\r\n\r\n" // Use a response string
|
||||
]);
|
||||
|
||||
// Add the mock subscriber to the client.
|
||||
$client->getEmitter()->attach($mock);
|
||||
// The first request is intercepted with the first response.
|
||||
echo $client->get('/')->getStatus();
|
||||
echo $client->get('/')->getStatusCode();
|
||||
//> 200
|
||||
// The second request is intercepted with the second response.
|
||||
echo $client->get('/')->getStatus();
|
||||
echo $client->get('/')->getStatusCode();
|
||||
//> 202
|
||||
|
||||
When no more responses are in the queue and a request is sent, an
|
||||
|
@ -175,7 +175,7 @@ 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
|
||||
the server is running and wait until it is able to receive requets before
|
||||
the server is running and wait until it is able to receive requests before
|
||||
returning.
|
||||
|
||||
.. code-block:: php
|
||||
|
|
|
@ -122,7 +122,7 @@ class BatchContext
|
|||
|
||||
$code = curl_multi_add_handle($this->multi, $handle);
|
||||
if ($code != CURLM_OK) {
|
||||
CurlAdapter::throwMultiError($code);
|
||||
MultiAdapter::throwMultiError($code);
|
||||
}
|
||||
|
||||
$this->handles[$transaction] = $handle;
|
||||
|
@ -146,7 +146,7 @@ class BatchContext
|
|||
|
||||
$code = curl_multi_remove_handle($this->multi, $handle);
|
||||
if ($code != CURLM_OK) {
|
||||
CurlAdapter::throwMultiError($code);
|
||||
MultiAdapter::throwMultiError($code);
|
||||
}
|
||||
|
||||
$info = curl_getinfo($handle);
|
||||
|
|
|
@ -58,7 +58,6 @@ class MultiAdapter implements AdapterInterface, ParallelAdapterInterface
|
|||
MessageFactoryInterface $messageFactory,
|
||||
array $options = []
|
||||
) {
|
||||
$this->handles = new \SplObjectStorage();
|
||||
$this->messageFactory = $messageFactory;
|
||||
$this->curlFactory = isset($options['handle_factory'])
|
||||
? $options['handle_factory']
|
||||
|
|
|
@ -215,10 +215,12 @@ class StreamAdapter implements AdapterInterface
|
|||
{
|
||||
if (!is_array($value)) {
|
||||
$options['http']['proxy'] = $value;
|
||||
$options['http']['request_fulluri'] = true;
|
||||
} else {
|
||||
$scheme = $request->getScheme();
|
||||
if (isset($value[$scheme])) {
|
||||
$options['http']['proxy'] = $value[$scheme];
|
||||
$options['http']['request_fulluri'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace GuzzleHttp\Adapter;
|
||||
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Event\ListenerAttacherTrait;
|
||||
use GuzzleHttp\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
|
@ -11,21 +12,27 @@ use GuzzleHttp\Message\RequestInterface;
|
|||
*/
|
||||
class TransactionIterator implements \Iterator
|
||||
{
|
||||
use ListenerAttacherTrait;
|
||||
|
||||
/** @var \Iterator */
|
||||
private $source;
|
||||
|
||||
/** @var ClientInterface */
|
||||
private $client;
|
||||
|
||||
/** @var array of hashes containing 'name', 'fn', 'priority', and 'once' */
|
||||
private $eventListeners;
|
||||
/** @var array Listeners to attach to each request */
|
||||
private $eventListeners = [];
|
||||
|
||||
public function __construct(
|
||||
$source, ClientInterface $client,
|
||||
$source,
|
||||
ClientInterface $client,
|
||||
array $options
|
||||
) {
|
||||
$this->client = $client;
|
||||
$this->configureEvents($options);
|
||||
$this->eventListeners = $this->prepareListeners(
|
||||
$options,
|
||||
['before', 'complete', 'error']
|
||||
);
|
||||
if ($source instanceof \Iterator) {
|
||||
$this->source = $source;
|
||||
} elseif (is_array($source)) {
|
||||
|
@ -38,21 +45,11 @@ class TransactionIterator implements \Iterator
|
|||
public function current()
|
||||
{
|
||||
$request = $this->source->current();
|
||||
|
||||
if (!$request instanceof RequestInterface) {
|
||||
throw new \RuntimeException('All must implement RequestInterface');
|
||||
}
|
||||
|
||||
if ($this->eventListeners) {
|
||||
$emitter = $request->getEmitter();
|
||||
foreach ($this->eventListeners as $ev) {
|
||||
if ($ev['once']) {
|
||||
$emitter->once($ev['name'], $ev['fn'], $ev['priority']);
|
||||
} else {
|
||||
$emitter->on($ev['name'], $ev['fn'], $ev['priority']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->attachListeners($request, $this->eventListeners);
|
||||
|
||||
return new Transaction($this->client, $request);
|
||||
}
|
||||
|
@ -73,44 +70,4 @@ class TransactionIterator implements \Iterator
|
|||
}
|
||||
|
||||
public function rewind() {}
|
||||
|
||||
private function configureEvents(array $options)
|
||||
{
|
||||
static $namedEvents = ['before', 'complete', 'error'];
|
||||
|
||||
foreach ($namedEvents as $event) {
|
||||
if (isset($options[$event])) {
|
||||
if (is_callable($options[$event])) {
|
||||
$this->eventListeners[] = [
|
||||
'name' => $event,
|
||||
'fn' => $options[$event],
|
||||
'priority' => 0,
|
||||
'once' => false
|
||||
];
|
||||
} else {
|
||||
$this->addEvent($event, $options[$event]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addEvent($eventName, $event)
|
||||
{
|
||||
static $default = ['priority' => 0, 'once' => false];
|
||||
|
||||
if (!is_array($event)) {
|
||||
throw new \InvalidArgumentException('Each event listener must be a'
|
||||
. ' callable or an array of associative arrays where each'
|
||||
. ' associative array contains a "fn" key.');
|
||||
}
|
||||
|
||||
if (isset($event['fn'])) {
|
||||
$event['name'] = $eventName;
|
||||
$this->eventListeners[] = $event + $default;
|
||||
} else {
|
||||
foreach ($event as $e) {
|
||||
$this->addEvent($eventName, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,12 +69,16 @@ class Client implements ClientInterface
|
|||
* - parallel_adapter: Adapter used to transfer requests in parallel
|
||||
* - message_factory: Factory used to create request and response object
|
||||
* - defaults: Default request options to apply to each request
|
||||
* - emitter: Event emitter used for request events
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->configureBaseUrl($config);
|
||||
$this->configureDefaults($config);
|
||||
$this->configureAdapter($config);
|
||||
if (isset($config['emitter'])) {
|
||||
$this->emitter = $config['emitter'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,13 +268,12 @@ class Client implements ClientInterface
|
|||
/**
|
||||
* Get a default parallel adapter to use based on the environment
|
||||
*
|
||||
* @return ParallelAdapterInterface|null
|
||||
* @throws \RuntimeException
|
||||
* @return ParallelAdapterInterface
|
||||
*/
|
||||
private function getDefaultParallelAdapter()
|
||||
{
|
||||
return extension_loaded('curl')
|
||||
? new CurlAdapter($this->messageFactory)
|
||||
? new MultiAdapter($this->messageFactory)
|
||||
: new FakeParallelAdapter($this->adapter);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use GuzzleHttp\Exception\AdapterException;
|
|||
*/
|
||||
interface ClientInterface extends HasEmitterInterface
|
||||
{
|
||||
const VERSION = '4.0.0';
|
||||
const VERSION = '4.1.0';
|
||||
|
||||
/**
|
||||
* Create and return a new {@see RequestInterface} object.
|
||||
|
|
|
@ -11,7 +11,7 @@ use GuzzleHttp\Message\ResponseInterface;
|
|||
* It extracts cookies from HTTP requests, and returns them in HTTP responses.
|
||||
* CookieJarInterface instances automatically expire contained cookies when
|
||||
* necessary. Subclasses are also responsible for storing and retrieving
|
||||
* cookies from a file, database, etc...
|
||||
* cookies from a file, database, etc.
|
||||
*
|
||||
* @link http://docs.python.org/2/library/cookielib.html Inspiration
|
||||
*/
|
||||
|
|
|
@ -73,9 +73,9 @@ class FileCookieJar extends CookieJar
|
|||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$data = json_decode($json, true);
|
||||
$data = \GuzzleHttp\json_decode($json, true);
|
||||
if (is_array($data)) {
|
||||
foreach (json_decode($json, true) as $cookie) {
|
||||
foreach (\GuzzleHttp\json_decode($json, true) as $cookie) {
|
||||
$this->setCookie(new SetCookie($cookie));
|
||||
}
|
||||
} elseif (strlen($data)) {
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Cookie;
|
||||
|
||||
/**
|
||||
* Persists cookies in the client session
|
||||
*/
|
||||
class SessionCookieJar extends CookieJar
|
||||
{
|
||||
/** @var string session key */
|
||||
private $sessionKey;
|
||||
|
||||
/**
|
||||
* Create a new SessionCookieJar object
|
||||
*
|
||||
* @param string $sessionKey Session key name to store the cookie data in session
|
||||
*/
|
||||
public function __construct($sessionKey)
|
||||
{
|
||||
$this->sessionKey = $sessionKey;
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves cookies to session when shutting down
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save cookies to the client session
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$json = [];
|
||||
foreach ($this as $cookie) {
|
||||
if ($cookie->getExpires() && !$cookie->getDiscard()) {
|
||||
$json[] = $cookie->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION[$this->sessionKey] = json_encode($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the contents of the client session into the data array
|
||||
*/
|
||||
protected function load()
|
||||
{
|
||||
$cookieJar = isset($_SESSION[$this->sessionKey])
|
||||
? $_SESSION[$this->sessionKey]
|
||||
: null;
|
||||
|
||||
$data = \GuzzleHttp\json_decode($cookieJar, true);
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $cookie) {
|
||||
$this->setCookie(new SetCookie($cookie));
|
||||
}
|
||||
} elseif (strlen($data)) {
|
||||
throw new \RuntimeException("Invalid cookie data");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ use GuzzleHttp\Message\ResponseInterface;
|
|||
|
||||
/**
|
||||
* Event that contains transaction statistics (time over the wire, lookup time,
|
||||
* etc).
|
||||
* etc.).
|
||||
*
|
||||
* Adapters that create this event SHOULD add, at a minimum, the 'total_time'
|
||||
* transfer statistic that measures the amount of time, in seconds, taken to
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Event;
|
||||
|
||||
/**
|
||||
* Trait that provides methods for extract event listeners specified in an array
|
||||
* and attaching them to an emitter owned by the object or one of its direct
|
||||
* dependencies.
|
||||
*/
|
||||
trait ListenerAttacherTrait
|
||||
{
|
||||
/**
|
||||
* Attaches event listeners and properly sets their priorities and whether
|
||||
* or not they are are only executed once.
|
||||
*
|
||||
* @param HasEmitterInterface $object Object that has the event emitter.
|
||||
* @param array $listeners Array of hashes representing event
|
||||
* event listeners. Each item contains
|
||||
* "name", "fn", "priority", & "once".
|
||||
*/
|
||||
private function attachListeners(HasEmitterInterface $object, array $listeners)
|
||||
{
|
||||
$emitter = $object->getEmitter();
|
||||
foreach ($listeners as $el) {
|
||||
if ($el['once']) {
|
||||
$emitter->once($el['name'], $el['fn'], $el['priority']);
|
||||
} else {
|
||||
$emitter->on($el['name'], $el['fn'], $el['priority']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the allowed events from the provided array, and ignores anything
|
||||
* else in the array. The event listener must be specified as a callable or
|
||||
* as an array of event listener data ("name", "fn", "priority", "once").
|
||||
*
|
||||
* @param array $source Array containing callables or hashes of data to be
|
||||
* prepared as event listeners.
|
||||
* @param array $events Names of events to look for in the provided $source
|
||||
* array. Other keys are ignored.
|
||||
* @return array
|
||||
*/
|
||||
private function prepareListeners(array $source, array $events)
|
||||
{
|
||||
$listeners = [];
|
||||
foreach ($events as $name) {
|
||||
if (isset($source[$name])) {
|
||||
$this->buildListener($name, $source[$name], $listeners);
|
||||
}
|
||||
}
|
||||
|
||||
return $listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a complete event listener definition from the provided array of
|
||||
* listener data. Also works recursively if more than one listeners are
|
||||
* contained in the provided array.
|
||||
*
|
||||
* @param string $name Name of the event the listener is for.
|
||||
* @param array|callable $data Event listener data to prepare.
|
||||
* @param array $listeners Array of listeners, passed by reference.
|
||||
*
|
||||
* @throws \InvalidArgumentException if the event data is malformed.
|
||||
*/
|
||||
private function buildListener($name, $data, &$listeners)
|
||||
{
|
||||
static $defaults = ['priority' => 0, 'once' => false];
|
||||
|
||||
// If a callable is provided, normalize it to the array format.
|
||||
if (is_callable($data)) {
|
||||
$data = ['fn' => $data];
|
||||
}
|
||||
|
||||
// Prepare the listener and add it to the array, recursively.
|
||||
if (isset($data['fn'])) {
|
||||
$data['name'] = $name;
|
||||
$listeners[] = $data + $defaults;
|
||||
} elseif (is_array($data)) {
|
||||
foreach ($data as $listenerData) {
|
||||
$this->buildListener($name, $listenerData, $listeners);
|
||||
}
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Each event listener must be a '
|
||||
. 'callable or an associative array containing a "fn" key.');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,7 +25,8 @@ class RequestException extends TransferException
|
|||
ResponseInterface $response = null,
|
||||
\Exception $previous = null
|
||||
) {
|
||||
parent::__construct($message, 0, $previous);
|
||||
$code = $response ? $response->getStatusCode() : 0;
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->request = $request;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace GuzzleHttp;
|
|||
trait HasDataTrait
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
protected $data = [];
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace GuzzleHttp\Message;
|
||||
|
||||
use GuzzleHttp\Event\ListenerAttacherTrait;
|
||||
use GuzzleHttp\Post\PostFileInterface;
|
||||
use GuzzleHttp\Subscriber\Cookie;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
|
@ -19,6 +20,8 @@ use GuzzleHttp\Url;
|
|||
*/
|
||||
class MessageFactory implements MessageFactoryInterface
|
||||
{
|
||||
use ListenerAttacherTrait;
|
||||
|
||||
/** @var HttpError */
|
||||
private $errorPlugin;
|
||||
|
||||
|
@ -123,9 +126,12 @@ class MessageFactory implements MessageFactoryInterface
|
|||
*/
|
||||
protected function addPostData(RequestInterface $request, array $body)
|
||||
{
|
||||
static $fields = ['string' => true, 'array' => true, 'NULL' => true,
|
||||
'boolean' => true, 'double' => true, 'integer' => true];
|
||||
|
||||
$post = new PostBody();
|
||||
foreach ($body as $key => $value) {
|
||||
if (is_string($value) || is_array($value)) {
|
||||
if (isset($fields[gettype($value)])) {
|
||||
$post->setField($key, $value);
|
||||
} elseif ($value instanceof PostFileInterface) {
|
||||
$post->addFile($value);
|
||||
|
@ -148,7 +154,7 @@ class MessageFactory implements MessageFactoryInterface
|
|||
'debug' => 1, 'save_to' => 1, 'stream' => 1, 'expect' => 1];
|
||||
static $methods;
|
||||
if (!$methods) {
|
||||
$methods = array_flip(get_class_methods(__CLASS__));
|
||||
$methods = array_flip(get_class_methods($this));
|
||||
}
|
||||
|
||||
// Iterate over each key value pair and attempt to apply a config using
|
||||
|
@ -298,27 +304,9 @@ class MessageFactory implements MessageFactoryInterface
|
|||
throw new \InvalidArgumentException('events value must be an array');
|
||||
}
|
||||
|
||||
$emitter = $request->getEmitter();
|
||||
foreach ($value as $name => $method) {
|
||||
if (is_callable($method)) {
|
||||
$emitter->on($name, $method);
|
||||
} elseif (!is_array($method) || !isset($method['fn'])) {
|
||||
throw new \InvalidArgumentException('Each event must be a '
|
||||
. 'callable or associative array containing a "fn" key');
|
||||
} elseif (isset($method['once']) && $method['once'] === true) {
|
||||
$emitter->once(
|
||||
$name,
|
||||
$method['fn'],
|
||||
isset($method['priority']) ? $method['priority'] : 0
|
||||
);
|
||||
} else {
|
||||
$emitter->on(
|
||||
$name,
|
||||
$method['fn'],
|
||||
isset($method['priority']) ? $method['priority'] : 0
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->attachListeners($request, $this->prepareListeners($value,
|
||||
['before', 'complete', 'error', 'headers']
|
||||
));
|
||||
}
|
||||
|
||||
private function add_subscribers(RequestInterface $request, $value)
|
||||
|
@ -332,4 +320,13 @@ class MessageFactory implements MessageFactoryInterface
|
|||
$emitter->attach($subscribers);
|
||||
}
|
||||
}
|
||||
|
||||
private function add_json(RequestInterface $request, $value)
|
||||
{
|
||||
if (!$request->hasHeader('Content-Type')) {
|
||||
$request->setHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
$request->setBody(Stream\create(json_encode($value)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ interface MessageFactoryInterface
|
|||
*
|
||||
* - headers: Associative array of headers to add to the request
|
||||
* - body: string|resource|array|StreamInterface request body to send
|
||||
* - json: mixed Uploads JSON encoded data using an application/json Content-Type header.
|
||||
* - query: Associative array of query string values to add to the request
|
||||
* - auth: array|string HTTP auth settings (user, pass[, type="basic"])
|
||||
* - version: The HTTP protocol version to use with the request
|
||||
|
@ -59,7 +60,7 @@ interface MessageFactoryInterface
|
|||
* - expect: true/false/integer Controls the "Expect: 100-Continue" header
|
||||
* - config: Associative array of request config collection options
|
||||
*
|
||||
* @param string $method HTTP method (GET, POST, PUT, etc ...)
|
||||
* @param string $method HTTP method (GET, POST, PUT, etc.)
|
||||
* @param string|Url $url HTTP URL to connect to
|
||||
* @param array $options Array of options to apply to the request
|
||||
*
|
||||
|
|
|
@ -38,7 +38,8 @@ class MessageParser
|
|||
'body' => $parts['body']
|
||||
];
|
||||
|
||||
$parsed['request_url'] = $this->getUrlPartsFromMessage($parts['start_line'][1], $parsed);
|
||||
$parsed['request_url'] = $this->getUrlPartsFromMessage(
|
||||
(isset($parts['start_line'][1]) ? $parts['start_line'][1] : ''), $parsed);
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
|
|
@ -115,6 +115,19 @@ class Request extends AbstractMessage implements RequestInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getPort()
|
||||
{
|
||||
return $this->url->getPort();
|
||||
}
|
||||
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->url->setPort($port);
|
||||
$this->updateHostHeaderFromUrl();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHost()
|
||||
{
|
||||
return $this->url->getHost();
|
||||
|
@ -194,9 +207,9 @@ class Request extends AbstractMessage implements RequestInterface
|
|||
if (($port == 80 && $scheme == 'http') ||
|
||||
($port == 443 && $scheme == 'https')
|
||||
) {
|
||||
$this->setHeader('Host', $this->url->getHost());
|
||||
$this->setHeader('Host', $host);
|
||||
} else {
|
||||
$this->setHeader('Host', $this->url->getHost() . ':' . $port);
|
||||
$this->setHeader('Host', "{$host}:{$port}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,6 @@ use GuzzleHttp\Query;
|
|||
*/
|
||||
interface RequestInterface extends MessageInterface, HasEmitterInterface
|
||||
{
|
||||
const GET = 'GET';
|
||||
const PUT = 'PUT';
|
||||
const POST = 'POST';
|
||||
const DELETE = 'DELETE';
|
||||
const HEAD = 'HEAD';
|
||||
const CONNECT = 'CONNECT';
|
||||
const OPTIONS = 'OPTIONS';
|
||||
const TRACE = 'TRACE';
|
||||
const PATCH = 'PATCH';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* Sets the request URL.
|
||||
*
|
||||
|
@ -39,7 +24,7 @@ interface RequestInterface extends MessageInterface, HasEmitterInterface
|
|||
public function setUrl($url);
|
||||
|
||||
/**
|
||||
* Gets the request URL.
|
||||
* Gets the request URL as a string.
|
||||
*
|
||||
* @return string Returns the URL as a string.
|
||||
*/
|
||||
|
@ -71,14 +56,14 @@ interface RequestInterface extends MessageInterface, HasEmitterInterface
|
|||
public function setQuery($query);
|
||||
|
||||
/**
|
||||
* Get the HTTP method of the request
|
||||
* Get the HTTP method of the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod();
|
||||
|
||||
/**
|
||||
* Set the HTTP method of the request
|
||||
* Set the HTTP method of the request.
|
||||
*
|
||||
* @param string $method HTTP method
|
||||
*
|
||||
|
@ -87,14 +72,14 @@ interface RequestInterface extends MessageInterface, HasEmitterInterface
|
|||
public function setMethod($method);
|
||||
|
||||
/**
|
||||
* Get the URI scheme of the request (http, https, etc)
|
||||
* Get the URI scheme of the request (http, https, etc.).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme();
|
||||
|
||||
/**
|
||||
* Set the URI scheme of the request (http, https, etc)
|
||||
* Set the URI scheme of the request (http, https, etc.).
|
||||
*
|
||||
* @param string $scheme Scheme to set
|
||||
*
|
||||
|
@ -103,15 +88,36 @@ interface RequestInterface extends MessageInterface, HasEmitterInterface
|
|||
public function setScheme($scheme);
|
||||
|
||||
/**
|
||||
* Get the host of the request
|
||||
* Get the port scheme of the request (e.g., 80, 443, etc.).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPort();
|
||||
|
||||
/**
|
||||
* Set the port of the request.
|
||||
*
|
||||
* Setting a port modifies the Host header of a request as necessary.
|
||||
*
|
||||
* @param int $port Port to set
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPort($port);
|
||||
|
||||
/**
|
||||
* Get the host of the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost();
|
||||
|
||||
/**
|
||||
* Set the host of the request. Including a port in the host will modify
|
||||
* the port of the request.
|
||||
* Set the host of the request including an optional port.
|
||||
*
|
||||
* Including a port in the host argument will explicitly change the port of
|
||||
* the request. If no port is found, the default port of the current
|
||||
* request scheme will be utilized.
|
||||
*
|
||||
* @param string $host Host to set (e.g. www.yahoo.com, www.yahoo.com:80)
|
||||
*
|
||||
|
@ -120,14 +126,14 @@ interface RequestInterface extends MessageInterface, HasEmitterInterface
|
|||
public function setHost($host);
|
||||
|
||||
/**
|
||||
* Get the path of the request (e.g. '/', '/index.html')
|
||||
* Get the path of the request (e.g. '/', '/index.html').
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath();
|
||||
|
||||
/**
|
||||
* Set the path of the request (e.g. '/', '/index.html')
|
||||
* Set the path of the request (e.g. '/', '/index.html').
|
||||
*
|
||||
* @param string|array $path Path to set or array of segments to implode
|
||||
*
|
||||
|
@ -136,7 +142,7 @@ interface RequestInterface extends MessageInterface, HasEmitterInterface
|
|||
public function setPath($path);
|
||||
|
||||
/**
|
||||
* Get the request's configuration options
|
||||
* Get the request's configuration options.
|
||||
*
|
||||
* @return \GuzzleHttp\Collection
|
||||
*/
|
||||
|
|
|
@ -126,21 +126,19 @@ class Response extends AbstractMessage implements ResponseInterface
|
|||
|
||||
public function json(array $config = [])
|
||||
{
|
||||
$data = json_decode(
|
||||
(string) $this->getBody(),
|
||||
isset($config['object']) ? !$config['object'] : true,
|
||||
512,
|
||||
isset($config['big_int_strings']) ? JSON_BIGINT_AS_STRING : 0
|
||||
);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
try {
|
||||
return \GuzzleHttp\json_decode(
|
||||
(string) $this->getBody(),
|
||||
isset($config['object']) ? !$config['object'] : true,
|
||||
512,
|
||||
isset($config['big_int_strings']) ? JSON_BIGINT_AS_STRING : 0
|
||||
);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new ParseException(
|
||||
'Unable to parse response body into JSON: ' . json_last_error(),
|
||||
$e->getMessage(),
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function xml(array $config = [])
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace GuzzleHttp\Message;
|
|||
interface ResponseInterface extends MessageInterface
|
||||
{
|
||||
/**
|
||||
* Get the response status code (e.g. "200", "404", etc)
|
||||
* Get the response status code (e.g. "200", "404", etc.)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
@ -36,7 +36,6 @@ class MultipartBody implements Stream\StreamInterface
|
|||
$this->boundary = $boundary ?: uniqid();
|
||||
$this->fields = $fields;
|
||||
$this->files = $files;
|
||||
$this->meta['mode'] = 'r';
|
||||
|
||||
// Ensure each file is a PostFileInterface
|
||||
foreach ($this->files as $file) {
|
||||
|
|
|
@ -118,10 +118,11 @@ class Redirect implements SubscriberInterface
|
|||
// would do. Be sure to disable redirects on the clone.
|
||||
$redirectRequest = clone $request;
|
||||
$redirectRequest->getEmitter()->detach($this);
|
||||
$statusCode = $response->getStatusCode();
|
||||
|
||||
if ($request->getBody() &&
|
||||
!$config->getPath('redirect/strict') &&
|
||||
$response->getStatusCode() <= 302
|
||||
if ($statusCode == 303 ||
|
||||
($statusCode <= 302 && $request->getBody() &&
|
||||
!$config->getPath('redirect/strict'))
|
||||
) {
|
||||
$redirectRequest->setMethod('GET');
|
||||
$redirectRequest->setBody(null);
|
||||
|
|
|
@ -218,7 +218,7 @@ class Url
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the scheme part of the URL (http, https, ftp, etc)
|
||||
* Set the scheme part of the URL (http, https, ftp, etc.)
|
||||
*
|
||||
* @param string $scheme Scheme to set
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
##
|
||||
## ca-bundle.crt -- Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla as of: Tue Jan 28 09:38:07 2014
|
||||
## Certificate data from Mozilla as of: Tue Apr 22 08:29:31 2014
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
|
@ -1318,31 +1318,6 @@ CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
|
|||
+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Firmaprofesional Root CA
|
||||
========================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT
|
||||
GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp
|
||||
Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA
|
||||
ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL
|
||||
MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT
|
||||
OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2
|
||||
ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V
|
||||
j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH
|
||||
lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf
|
||||
3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8
|
||||
NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww
|
||||
KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG
|
||||
AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud
|
||||
DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
|
||||
u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf
|
||||
wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm
|
||||
7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG
|
||||
VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Swisscom Root CA 1
|
||||
==================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
|
@ -3783,3 +3758,109 @@ i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
|
|||
EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
|
||||
zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
TeliaSonera Root CA v1
|
||||
======================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
|
||||
CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
|
||||
MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
|
||||
VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
|
||||
6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
|
||||
3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
|
||||
B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
|
||||
Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
|
||||
oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
|
||||
F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
|
||||
oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
|
||||
gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
|
||||
TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
|
||||
AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
|
||||
DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
|
||||
zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
|
||||
0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
|
||||
pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
|
||||
G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
|
||||
c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
|
||||
JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
|
||||
qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
|
||||
Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
|
||||
WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
E-Tugra Certification Authority
|
||||
===============================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
|
||||
DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
|
||||
ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
|
||||
ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
|
||||
NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
|
||||
QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
|
||||
cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
|
||||
DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
|
||||
MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
|
||||
hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
|
||||
CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
|
||||
ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
|
||||
BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
|
||||
E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
|
||||
rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
|
||||
jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
|
||||
rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
|
||||
dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
|
||||
/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
|
||||
MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
|
||||
kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
|
||||
XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
|
||||
VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
|
||||
a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
|
||||
dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
|
||||
KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
|
||||
Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
|
||||
8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
|
||||
C7TbO6Orb1wdtn7os4I07QZcJA==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
T-TeleSec GlobalRoot Class 2
|
||||
============================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
|
||||
IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
|
||||
cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
|
||||
MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
|
||||
dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
|
||||
ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
|
||||
SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
|
||||
vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
|
||||
2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
|
||||
WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
|
||||
YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
|
||||
r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
|
||||
vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
|
||||
3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
|
||||
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Atos TrustedRoot 2011
|
||||
=====================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
|
||||
cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
|
||||
MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
|
||||
A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
|
||||
hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
|
||||
54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
|
||||
DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
|
||||
HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
|
||||
z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
|
||||
l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
|
||||
bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
|
||||
CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
|
||||
k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
|
||||
TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
|
||||
61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
|
||||
3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -274,6 +274,43 @@ function uri_template($template, array $variables)
|
|||
return $uriTemplate->expand($template, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -122,6 +122,9 @@ class StreamAdapterTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('OK', $response->getReasonPhrase());
|
||||
$this->assertEquals('8', $response->getHeader('Content-Length'));
|
||||
$body = $response->getBody();
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestIncomplete('HHVM has not implemented this?');
|
||||
}
|
||||
$this->assertEquals('http', $body->getMetadata()['wrapper_type']);
|
||||
$this->assertEquals(8, $body->getMetadata()['unread_bytes']);
|
||||
$this->assertEquals(Server::$url . 'foo', $body->getMetadata()['uri']);
|
||||
|
@ -222,6 +225,7 @@ class StreamAdapterTest extends \PHPUnit_Framework_TestCase
|
|||
$body = $this->getSendResult(['stream' => true, 'proxy' => '127.0.0.1:8124'])->getBody();
|
||||
$opts = stream_context_get_options($this->getStreamFromBody($body));
|
||||
$this->assertEquals('127.0.0.1:8124', $opts['http']['proxy']);
|
||||
$this->assertTrue($opts['http']['request_fulluri']);
|
||||
}
|
||||
|
||||
public function testAddsTimeout()
|
||||
|
@ -289,6 +293,10 @@ class StreamAdapterTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function testDebugAttributeWritesStreamInfoToTempBufferByDefault()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM has not implemented this?');
|
||||
return;
|
||||
}
|
||||
|
||||
Server::flush();
|
||||
Server::enqueue("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 8\r\n\r\nhi there");
|
||||
|
@ -306,6 +314,11 @@ class StreamAdapterTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function testDebugAttributeWritesStreamInfoToBuffer()
|
||||
{
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$this->markTestSkipped('HHVM has not implemented this?');
|
||||
return;
|
||||
}
|
||||
|
||||
$buffer = fopen('php://temp', 'r+');
|
||||
Server::flush();
|
||||
Server::enqueue("HTTP/1.1 200 OK\r\nContent-Length: 8\r\nContent-Type: text/plain\r\n\r\nhi there");
|
||||
|
|
|
@ -70,103 +70,4 @@ class TransactionIteratorTest extends \PHPUnit_Framework_TestCase
|
|||
$t = new TransactionIterator(new \ArrayIterator($requests), $c, []);
|
||||
iterator_to_array($t);
|
||||
}
|
||||
|
||||
public function testRegistersEvents()
|
||||
{
|
||||
$fn = function() {};
|
||||
$c = new Client();
|
||||
$requests = [$c->createRequest('GET', 'http://test.com')];
|
||||
$trans = new TransactionIterator(new \ArrayIterator($requests), $c, [
|
||||
'before' => $fn,
|
||||
'complete' => $fn,
|
||||
'error' => $fn,
|
||||
]);
|
||||
|
||||
$t = iterator_to_array($trans)[0];
|
||||
$em = $t->getRequest()->getEmitter();
|
||||
$this->assertSame($fn, $em->listeners('before')[0]);
|
||||
$this->assertSame($fn, $em->listeners('complete')[2]);
|
||||
$this->assertSame($fn, $em->listeners('error')[0]);
|
||||
}
|
||||
|
||||
public function testRegistersEventsWithPriorities()
|
||||
{
|
||||
$fn = function() {};
|
||||
$client = new Client();
|
||||
$requests = [$client->createRequest('GET', 'http://test.com')];
|
||||
$trans = new TransactionIterator(
|
||||
new \ArrayIterator($requests),
|
||||
$client,
|
||||
[
|
||||
'before' => [['fn' => $fn, 'priority' => 99]],
|
||||
'complete' => [['fn' => $fn, 'priority' => 99]],
|
||||
'error' => [['fn' => $fn, 'priority' => 99]]
|
||||
]
|
||||
);
|
||||
|
||||
$t = iterator_to_array($trans)[0];
|
||||
$em = $t->getRequest()->getEmitter();
|
||||
$this->assertSame($fn, $em->listeners('before')[0]);
|
||||
$this->assertSame($fn, $em->listeners('complete')[2]);
|
||||
$this->assertSame($fn, $em->listeners('error')[0]);
|
||||
}
|
||||
|
||||
public function testRegistersMultipleEvents()
|
||||
{
|
||||
$fn = function() {};
|
||||
$c = new Client();
|
||||
$eventArray = [['fn' => $fn], ['fn' => $fn]];
|
||||
$requests = [$c->createRequest('GET', 'http://test.com')];
|
||||
$trans = new TransactionIterator(new \ArrayIterator($requests), $c, [
|
||||
'before' => $eventArray,
|
||||
'complete' => $eventArray,
|
||||
'error' => $eventArray,
|
||||
]);
|
||||
|
||||
$t = iterator_to_array($trans)[0];
|
||||
$em = $t->getRequest()->getEmitter();
|
||||
$this->assertSame($fn, $em->listeners('before')[0]);
|
||||
$this->assertSame($fn, $em->listeners('before')[1]);
|
||||
$this->assertSame($fn, $em->listeners('complete')[2]);
|
||||
$this->assertSame($fn, $em->listeners('complete')[3]);
|
||||
$this->assertSame($fn, $em->listeners('error')[0]);
|
||||
$this->assertSame($fn, $em->listeners('error')[1]);
|
||||
}
|
||||
|
||||
public function testRegistersEventsWithOnce()
|
||||
{
|
||||
$called = 0;
|
||||
$fn = function () use (&$called) { $called++; };
|
||||
$client = new Client();
|
||||
$requests = [$client->createRequest('GET', 'http://test.com')];
|
||||
// Remove an default listeners
|
||||
foreach ($requests[0]->getEmitter()->listeners('before') as $l) {
|
||||
$requests[0]->getEmitter()->removeListener('before', $l);
|
||||
}
|
||||
$trans = new TransactionIterator(
|
||||
new \ArrayIterator($requests),
|
||||
$client,
|
||||
['before' => [['fn' => $fn, 'once' => true]]]
|
||||
);
|
||||
// Apply the listeners to the request
|
||||
iterator_to_array($trans)[0];
|
||||
$ev = $this->getMockBuilder('GuzzleHttp\Event\BeforeEvent')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$requests[0]->getEmitter()->emit('before', $ev);
|
||||
$requests[0]->getEmitter()->emit('before', $ev);
|
||||
$this->assertEquals(1, $called);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testValidatesEvents()
|
||||
{
|
||||
$client = new Client();
|
||||
$requests = [$client->createRequest('GET', 'http://test.com')];
|
||||
new TransactionIterator(new \ArrayIterator($requests), $client, [
|
||||
'before' => 'foo'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,6 +103,19 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||
$client->get();
|
||||
}
|
||||
|
||||
public function testCanSpecifyEmitter()
|
||||
{
|
||||
$emitter = $this->getMockBuilder('GuzzleHttp\Event\EmitterInterface')
|
||||
->setMethods(['listeners'])
|
||||
->getMockForAbstractClass();
|
||||
$emitter->expects($this->once())
|
||||
->method('listeners')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$client = new Client(['emitter' => $emitter]);
|
||||
$this->assertEquals('foo', $client->getEmitter()->listeners());
|
||||
}
|
||||
|
||||
public function testAddsDefaultUserAgentHeaderWithDefaultOptions()
|
||||
{
|
||||
$client = new Client(['defaults' => ['allow_redirects' => false]]);
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Tests\CookieJar;
|
||||
|
||||
use GuzzleHttp\Cookie\SessionCookieJar;
|
||||
use GuzzleHttp\Cookie\SetCookie;
|
||||
|
||||
/**
|
||||
* @covers GuzzleHttp\Cookie\SessionCookieJar
|
||||
*/
|
||||
class SessionCookieJarTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $sessionVar;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->sessionVar = 'sessionKey';
|
||||
|
||||
if (!isset($_SESSION)) {
|
||||
$_SESSION = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testValidatesCookieSession()
|
||||
{
|
||||
$_SESSION[$this->sessionVar] = 'true';
|
||||
new SessionCookieJar($this->sessionVar);
|
||||
}
|
||||
|
||||
public function testLoadsFromSession()
|
||||
{
|
||||
$jar = new SessionCookieJar($this->sessionVar);
|
||||
$this->assertEquals([], $jar->getIterator()->getArrayCopy());
|
||||
unset($_SESSION[$this->sessionVar]);
|
||||
}
|
||||
|
||||
public function testPersistsToSession()
|
||||
{
|
||||
$jar = new SessionCookieJar($this->sessionVar);
|
||||
$jar->setCookie(new SetCookie([
|
||||
'Name' => 'foo',
|
||||
'Value' => 'bar',
|
||||
'Domain' => 'foo.com',
|
||||
'Expires' => time() + 1000
|
||||
]));
|
||||
$jar->setCookie(new SetCookie([
|
||||
'Name' => 'baz',
|
||||
'Value' => 'bar',
|
||||
'Domain' => 'foo.com',
|
||||
'Expires' => time() + 1000
|
||||
]));
|
||||
$jar->setCookie(new SetCookie([
|
||||
'Name' => 'boo',
|
||||
'Value' => 'bar',
|
||||
'Domain' => 'foo.com',
|
||||
]));
|
||||
|
||||
$this->assertEquals(3, count($jar));
|
||||
unset($jar);
|
||||
|
||||
// Make sure it wrote to the sessionVar in $_SESSION
|
||||
$contents = $_SESSION[$this->sessionVar];
|
||||
$this->assertNotEmpty($contents);
|
||||
|
||||
// Load the cookieJar from the file
|
||||
$jar = new SessionCookieJar($this->sessionVar);
|
||||
|
||||
// Weeds out temporary and session cookies
|
||||
$this->assertEquals(2, count($jar));
|
||||
unset($jar);
|
||||
unset($_SESSION[$this->sessionVar]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace GuzzleHttp\Tests\Event;
|
||||
|
||||
use GuzzleHttp\Event\HasEmitterInterface;
|
||||
use GuzzleHttp\Event\HasEmitterTrait;
|
||||
use GuzzleHttp\Event\ListenerAttacherTrait;
|
||||
|
||||
class ObjectWithEvents implements HasEmitterInterface
|
||||
{
|
||||
use HasEmitterTrait, ListenerAttacherTrait;
|
||||
|
||||
public $listeners = [];
|
||||
|
||||
public function __construct(array $args = [])
|
||||
{
|
||||
$this->listeners = $this->prepareListeners($args, ['foo', 'bar']);
|
||||
$this->attachListeners($this, $this->listeners);
|
||||
}
|
||||
}
|
||||
|
||||
class ListenerAttacherTraitTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testRegistersEvents()
|
||||
{
|
||||
$fn = function() {};
|
||||
$o = new ObjectWithEvents([
|
||||
'foo' => $fn,
|
||||
'bar' => $fn,
|
||||
]);
|
||||
|
||||
$this->assertEquals([
|
||||
['name' => 'foo', 'fn' => $fn, 'priority' => 0, 'once' => false],
|
||||
['name' => 'bar', 'fn' => $fn, 'priority' => 0, 'once' => false],
|
||||
], $o->listeners);
|
||||
|
||||
$this->assertCount(1, $o->getEmitter()->listeners('foo'));
|
||||
$this->assertCount(1, $o->getEmitter()->listeners('bar'));
|
||||
}
|
||||
|
||||
public function testRegistersEventsWithPriorities()
|
||||
{
|
||||
$fn = function() {};
|
||||
$o = new ObjectWithEvents([
|
||||
'foo' => ['fn' => $fn, 'priority' => 99, 'once' => true],
|
||||
'bar' => ['fn' => $fn, 'priority' => 50],
|
||||
]);
|
||||
|
||||
$this->assertEquals([
|
||||
['name' => 'foo', 'fn' => $fn, 'priority' => 99, 'once' => true],
|
||||
['name' => 'bar', 'fn' => $fn, 'priority' => 50, 'once' => false],
|
||||
], $o->listeners);
|
||||
}
|
||||
|
||||
public function testRegistersMultipleEvents()
|
||||
{
|
||||
$fn = function() {};
|
||||
$eventArray = [['fn' => $fn], ['fn' => $fn]];
|
||||
$o = new ObjectWithEvents([
|
||||
'foo' => $eventArray,
|
||||
'bar' => $eventArray,
|
||||
]);
|
||||
|
||||
$this->assertEquals([
|
||||
['name' => 'foo', 'fn' => $fn, 'priority' => 0, 'once' => false],
|
||||
['name' => 'foo', 'fn' => $fn, 'priority' => 0, 'once' => false],
|
||||
['name' => 'bar', 'fn' => $fn, 'priority' => 0, 'once' => false],
|
||||
['name' => 'bar', 'fn' => $fn, 'priority' => 0, 'once' => false],
|
||||
], $o->listeners);
|
||||
|
||||
$this->assertCount(2, $o->getEmitter()->listeners('foo'));
|
||||
$this->assertCount(2, $o->getEmitter()->listeners('bar'));
|
||||
}
|
||||
|
||||
public function testRegistersEventsWithOnce()
|
||||
{
|
||||
$called = 0;
|
||||
$fn = function () use (&$called) { $called++; };
|
||||
$o = new ObjectWithEvents(['foo' => ['fn' => $fn, 'once' => true]]);
|
||||
$ev = $this->getMock('GuzzleHttp\Event\EventInterface');
|
||||
$o->getEmitter()->emit('foo', $ev);
|
||||
$o->getEmitter()->emit('foo', $ev);
|
||||
$this->assertEquals(1, $called);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testValidatesEvents()
|
||||
{
|
||||
$o = new ObjectWithEvents(['foo' => 'bar']);
|
||||
}
|
||||
}
|
|
@ -76,4 +76,9 @@ class RequestExceptionTest extends \PHPUnit_Framework_TestCase
|
|||
$e->emittedError(true);
|
||||
$e->emittedError(false);
|
||||
}
|
||||
|
||||
public function testHasStatusCodeAsExceptionCode() {
|
||||
$e = RequestException::create(new Request('GET', '/'), new Response(442));
|
||||
$this->assertEquals(442, $e->getCode());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,21 @@ class FunctionsTest extends \PHPUnit_Framework_TestCase
|
|||
$requests = [$client->createRequest('GET', 'http://foo.com/baz')];
|
||||
\GuzzleHttp\batch($client, $requests, ['complete' => 'foo']);
|
||||
}
|
||||
|
||||
public function testJsonDecodes()
|
||||
{
|
||||
$data = \GuzzleHttp\json_decode('true');
|
||||
$this->assertTrue($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Unable to parse JSON data: JSON_ERROR_SYNTAX - Syntax error, malformed JSON
|
||||
*/
|
||||
public function testJsonDecodesWithErrorMessages()
|
||||
{
|
||||
\GuzzleHttp\json_decode('!narf!');
|
||||
}
|
||||
}
|
||||
|
||||
class HasDeprecations
|
||||
|
|
|
@ -51,6 +51,26 @@ class MessageFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('abc=123', $req->getBody());
|
||||
}
|
||||
|
||||
public function testCreatesRequestWithPostBodyScalars()
|
||||
{
|
||||
$req = (new MessageFactory())->createRequest(
|
||||
'GET',
|
||||
'http://www.foo.com',
|
||||
['body' => [
|
||||
'abc' => true,
|
||||
'123' => false,
|
||||
'foo' => null,
|
||||
'baz' => 10,
|
||||
'bam' => 1.5,
|
||||
'boo' => [1]]
|
||||
]
|
||||
);
|
||||
$this->assertEquals(
|
||||
'abc=1&123=&foo&baz=10&bam=1.5&boo%5B0%5D=1',
|
||||
(string) $req->getBody()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreatesRequestWithPostBodyAndPostFiles()
|
||||
{
|
||||
$pf = fopen(__FILE__, 'r');
|
||||
|
@ -452,7 +472,29 @@ class MessageFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function testCanSetProtocolVersion()
|
||||
{
|
||||
$request = (new MessageFactory())->createRequest('GET', 'http://test.com', ['version' => 1.0]);
|
||||
$request = (new MessageFactory())->createRequest('GET', 'http://t.com', ['version' => 1.0]);
|
||||
$this->assertEquals(1.0, $request->getProtocolVersion());
|
||||
}
|
||||
|
||||
public function testCanAddJsonData()
|
||||
{
|
||||
$request = (new MessageFactory)->createRequest('PUT', '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', [
|
||||
'headers' => ['Content-Type' => 'foo'],
|
||||
'json' => null
|
||||
]);
|
||||
$this->assertEquals('foo', $request->getHeader('Content-Type'));
|
||||
$this->assertEquals('null', (string) $request->getBody());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,4 +117,16 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('http://goo', $r->getUrl());
|
||||
$this->assertEquals('goo', $r->getHeader('host'));
|
||||
}
|
||||
|
||||
public function testCanChangePort()
|
||||
{
|
||||
$r = new Request('GET', 'http://www.foo.com:222');
|
||||
$this->assertSame(222, $r->getPort());
|
||||
$this->assertEquals('www.foo.com', $r->getHost());
|
||||
$this->assertEquals('www.foo.com:222', $r->getHeader('host'));
|
||||
$r->setPort(80);
|
||||
$this->assertSame(80, $r->getPort());
|
||||
$this->assertEquals('www.foo.com', $r->getHost());
|
||||
$this->assertEquals('www.foo.com', $r->getHeader('host'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ class ResponseTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage Unable to parse response body into JSON: 4
|
||||
* @expectedException \GuzzleHttp\Exception\ParseException
|
||||
* @expectedExceptionMessage Unable to parse JSON data: JSON_ERROR_SYNTAX - Syntax error, malformed JSON
|
||||
*/
|
||||
public function testThrowsExceptionWhenFailsToParseJsonResponse()
|
||||
{
|
||||
|
|
|
@ -37,7 +37,9 @@ class Server
|
|||
*/
|
||||
public static function flush()
|
||||
{
|
||||
self::$started && self::$client->delete('guzzle-server/requests');
|
||||
self::start();
|
||||
|
||||
return self::$client->delete('guzzle-server/requests');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +128,7 @@ class Server
|
|||
self::$started = false;
|
||||
}
|
||||
|
||||
public static function wait($maxTries = 3)
|
||||
public static function wait($maxTries = 5)
|
||||
{
|
||||
$tries = 0;
|
||||
while (!self::isListening() && ++$tries < $maxTries) {
|
||||
|
|
|
@ -227,4 +227,20 @@ class RedirectTest extends \PHPUnit_Framework_TestCase
|
|||
$reqs = $h->getRequests();
|
||||
$this->assertFalse($reqs[1]->hasHeader('Referer'));
|
||||
}
|
||||
|
||||
public function testRedirectsWithGetOn303()
|
||||
{
|
||||
$h = new History();
|
||||
$mock = new Mock([
|
||||
"HTTP/1.1 303 Moved Permanently\r\nLocation: /redirect\r\nContent-Length: 0\r\n\r\n",
|
||||
"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n",
|
||||
]);
|
||||
$client = new Client();
|
||||
$client->getEmitter()->attach($mock);
|
||||
$client->getEmitter()->attach($h);
|
||||
$client->post('http://test.com/foo', ['body' => 'testing']);
|
||||
$requests = $h->getRequests();
|
||||
$this->assertEquals('POST', $requests[0]->getMethod());
|
||||
$this->assertEquals('GET', $requests[1]->getMethod());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue