Commit 116b4f7c authored by alexpott's avatar alexpott

Issue #2276119 by damiankloip: Upgrade Guzzle to version 4.1.0.

parent c8faf220
{
"_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 @@ public function unregister()
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
include $file;
includeFile($file);
return true;
}
......@@ -291,8 +291,25 @@ public function findFile($class)
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 @@ public function findFile($class)
. 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 @@ public function findFile($class)
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 @@
$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 @@ public static function getLoader()
$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"
]
}
]
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?