Skip to content

Releases: guzzle/guzzle

6.0.2: * Fixed a memory leak in the curl handlers in which references to cal…

04 Jul 20:20
Compare
Choose a tag to compare
…lbacks

  were not being removed by `curl_reset`.
* Cookies are now extracted properly before redirects.
* Cookies now allow more character ranges.
* Decoded Content-Encoding responses are now modified to correctly reflect
  their state if the encoding was automatically removed by a handler. This
  means that the `Content-Encoding` header may be removed an the
  `Content-Length` modified to reflect the message size after removing the
  encoding.
* Added a more explicit error message when trying to use `form_params` and
  `multipart` in the same request.
* Several fixes for HHVM support.
* Functions are now conditionally required using an additional level of
  indirection to help with global Composer installations.

6.0.1: * Fixed a bug with serializing the `query` request option where the `&`

27 May 17:05
Compare
Choose a tag to compare
  separator was missing.
* Added a better error message for when `body` is provided as an array. Please
  use `form_params` or `multipart` instead.
* Various doc fixes.

6.0.0

26 May 18:31
Compare
Choose a tag to compare

Guzzle now uses PSR-7 for HTTP messages.
Due to the fact that these messages are immutable, this prompted a refactoring
of Guzzle to use a middleware based system rather than an event system. Any
HTTP message interaction (e.g., GuzzleHttp\Message\Request) need to be
updated to work with the new immutable PSR-7 request and response objects. Any
event listeners or subscribers need to be updated to become middleware
functions that wrap handlers (or are injected into a
GuzzleHttp\HandlerStack).

  • Removed GuzzleHttp\BatchResults
  • Removed GuzzleHttp\Collection
  • Removed GuzzleHttp\HasDataTrait
  • Removed GuzzleHttp\ToArrayInterface
  • The guzzlehttp/streams dependency has been removed. Stream functionality
    is now present in the GuzzleHttp\Psr7 namespace provided by the
    guzzlehttp/psr7 package.
  • Guzzle no longer uses ReactPHP promises and now uses the
    guzzlehttp/promises library. We use a custom promise library for three
    significant reasons:
    1. React promises (at the time of writing this) are recursive. Promise
      chaining and promise resolution will eventually blow the stack. Guzzle
      promises are not recursive as they use a sort of trampolining technique.
      Note: there has been movement in the React project to modify promises to
      no longer utilize recursion.
    2. Guzzle needs to have the ability to synchronously block on a promise to
      wait for a result. Guzzle promises allows this functionality (and does
      not require the use of recursion).
    3. Because we need to be able to wait on a result, doing so using React
      promises requires wrapping react promises with RingPHP futures. This
      overhead is no longer needed, reducing stack sizes, reducing complexity,
      and improving performance.
  • GuzzleHttp\Mimetypes has been moved to a function in
    GuzzleHttp\Psr7\mimetype_from_extension and
    GuzzleHttp\Psr7\mimetype_from_filename.
  • GuzzleHttp\Query and GuzzleHttp\QueryParser have been removed. Query
    strings must now be passed into request objects as strings, or provided to
    the query request option when creating requests with clients. The query
    option uses PHP's http_build_query to convert an array to a string. If you
    need a different serialization technique, you will need to pass the query
    string in as a string. There are a couple helper functions that will make
    working with query strings easier: GuzzleHttp\Psr7\parse_query and
    GuzzleHttp\Psr7\build_query.
  • Guzzle no longer has a dependency on RingPHP. Due to the use of a middleware
    system based on PSR-7, using RingPHP and it's middleware system as well adds
    more complexity than the benefits it provides. All HTTP handlers that were
    present in RingPHP have been modified to work directly with PSR-7 messages
    and placed in the GuzzleHttp\Handler namespace. This significantly reduces
    complexity in Guzzle, removes a dependency, and improves performance. RingPHP
    will be maintained for Guzzle 5 support, but will no longer be a part of
    Guzzle 6.
  • As Guzzle now uses a middleware based systems the event system and RingPHP
    integration has been removed. Note: while the event system has been removed,
    it is possible to add your own type of event system that is powered by the
    middleware system.
    • Removed the Event namespace.
    • Removed the Subscriber namespace.
    • Removed Transaction class
    • Removed RequestFsm
    • Removed RingBridge
    • GuzzleHttp\Subscriber\Cookie is now provided by
      GuzzleHttp\Middleware::cookies
    • GuzzleHttp\Subscriber\HttpError is now provided by
      GuzzleHttp\Middleware::httpError
    • GuzzleHttp\Subscriber\History is now provided by
      GuzzleHttp\Middleware::history
    • GuzzleHttp\Subscriber\Mock is now provided by
      GuzzleHttp\Middleware::mock
    • GuzzleHttp\Subscriber\Prepare is now provided by
      GuzzleHttp\PrepareBodyMiddleware
    • GuzzleHttp\Subscriber\Redirect is now provided by
      GuzzleHttp\RedirectMiddleware
  • Guzzle now uses Psr\Http\Message\UriInterface (implements in
    GuzzleHttp\Psr7\Uri) for URI support. GuzzleHttp\Url is now gone.
  • Static functions in GuzzleHttp\Utils have been moved to namespaced
    functions under the GuzzleHttp namespace. This requires either a Composer
    based autoloader or you to include functions.php.
  • GuzzleHttp\ClientInterface::getDefaultOption has been renamed to
    GuzzleHttp\ClientInterface::getConfig.
  • GuzzleHttp\ClientInterface::setDefaultOption has been removed.

Migrating to middleware

The change to PSR-7 unfortunately required significant refactoring to Guzzle
due to the fact that PSR-7 messages are immutable. Guzzle 5 relied on an event
system from plugins. The event system relied on mutability of HTTP messages and
side effects in order to work. With immutable messages, you have to change your
workflow to become more about either returning a value (e.g., functional
middlewares) or setting a value on an object. Guzzle v6 has chosen the
functional middleware approach.

Instead of using the event system to listen for things like the before event,
you now create a stack based middleware function that intercepts a request on
the way in and the promise of the response on the way out. This is a much
simpler and more predictable approach than the event system and works nicely
with PSR-7 middleware. Due to the use of promises, the middleware system is
also asynchronous.

v5:

use GuzzleHttp\Event\BeforeEvent;
$client = new GuzzleHttp\Client();
// Get the emitter and listen to the before event.
$client->getEmitter()->on('before', function (BeforeEvent $e) {
    // Guzzle v5 events relied on mutation
    $e->getRequest()->setHeader('X-Foo', 'Bar');
});

v6:

In v6, you can modify the request before it is sent using the mapRequest
middleware. The idiomatic way in v6 to modify the request/response lifecycle is
to setup a handler middleware stack up front and inject the handler into a
client.

use GuzzleHttp\Middleware;
// Create a handler stack that has all of the default middlewares attached
$handler = GuzzleHttp\HandlerStack::create();
// Push the handler onto the handler stack
$handler->push(Middleware::mapRequest(function (RequestInterface $request) {
    // Notice that we have to return a request object
    return $request->withHeader('X-Foo', 'Bar');
});
// Inject the handler into the client
$client = new GuzzleHttp\Client(['handler' => $handler]);

5.3.0: * Mock now supports `save_to`

20 May 04:38
Compare
Choose a tag to compare
* Marked `AbstractRequestEvent::getTransaction()` as public.
* Fixed a bug in which multiple headers using different casing would overwrite
  previous headers in the associative array.
* Added `Utils::getDefaultHandler()`
* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated.
* URL scheme is now always lowercased.

5.2.0: * Added `AppliesHeadersInterface` to make applying headers to a reque…

28 Jan 01:06
Compare
Choose a tag to compare
…st based

  on the body more generic and not specific to `PostBodyInterface`.
* Reduced the number of stack frames needed to send requests.
* Nested futures are now resolved in the client rather than the RequestFsm
* Finishing state transitions is now handled in the RequestFsm rather than the
  RingBridge.
* Added a guard in the Pool class to not use recursion for request retries.

5.1.0

19 Dec 20:28
Compare
Choose a tag to compare
  • Pool class no longer uses recursion when a request is intercepted.
  • The size of a Pool can now be dynamically adjusted using a callback.
    See #943.
  • Setting a request option to null when creating a request with a client will
    ensure that the option is not set. This allows you to overwrite default
    request options on a per-request basis.
    See #937.
  • Added the ability to limit which protocols are allowed for redirects by
    specifying a protocols array in the allow_redirects request option.
  • Nested futures due to retries are now resolved when waiting for synchronous
    responses. See #947.
  • "0" is now an allowed URI path. See
    #935.
  • Query no longer typehints on the $query argument in the constructor,
    allowing for strings and arrays.
  • Exceptions thrown in the end event are now correctly wrapped with Guzzle
    specific exceptions if necessary.

5.0.3

04 Nov 07:11
Compare
Choose a tag to compare

This change updates query strings so that they are treated as un-encoded values
by default where the value represents an un-encoded value to send over the
wire. A Query object then encodes the value before sending over the wire. This
means that even value query string values (e.g., ":") are url encoded. This
makes the Query class match PHP's http_build_query function. However, if you
want to send requests over the wire using valid query string characters that do
not need to be encoded, then you can provide a string to Url::setQuery() and
pass true as the second argument to specify that the query string is a raw
string that should not be parsed or encoded (unless a call to getQuery() is
subsequently made, forcing the query-string to be converted into a Query
object).

5.0.2

31 Oct 03:29
Compare
Choose a tag to compare
  • Added a trailing \r\n to multipart/form-data payloads. See
    #871
  • Added a GuzzleHttp\Pool::send() convenience method to match the docs.
  • Status codes are now returned as integers. See
    #881
  • No longer overwriting an existing application/x-www-form-urlencoded header
    when sending POST requests, allowing for customized headers. See
    #877
  • Improved query string and path URL serialization.
    • No longer double percent-encoding characters in the path or query string if
      they are already encoded.
    • Now properly encoding the supplied path to a URL object, instead of only
      encoding ' ' and '?'.
    • Now allowing many more characters to be present in the query string without
      being percent encoded. See http:https://tools.ietf.org/html/rfc3986#appendix-A

5.0.1

16 Oct 18:47
Compare
Choose a tag to compare

Bugfix release.

  • Fixed an issue where connection errors still returned response object in
    error and end events event though the response is unusable. This has been
    corrected so that a response is not returned in the getResponse method of
    these events if the response did not complete. #867
  • Fixed an issue where transfer statistics were not being populated in the
    RingBridge. #866

5.0.0 release

13 Oct 03:22
Compare
Choose a tag to compare

Adding support for non-blocking responses and some minor API cleanup.

New Features

  • Added support for non-blocking responses based on guzzlehttp/guzzle-ring.
  • Added a public API for creating a default HTTP adapter.
  • Updated the redirect plugin to be non-blocking so that redirects are sent
    concurrently. Other plugins like this can now be updated to be non-blocking.
  • Added a "progress" event so that you can get upload and download progress
    events.
  • Added GuzzleHttp\Pool which implements FutureInterface and transfers
    requests concurrently using a capped pool size as efficiently as possible.
  • Added hasListeners() to EmitterInterface.
  • Removed GuzzleHttp\ClientInterface::sendAll and marked
    GuzzleHttp\Client::sendAll as deprecated (it's still there, just not the
    recommended way).

Breaking changes

The breaking changes in this release are relatively minor. The biggest thing to
look out for is that request and response objects no longer implement fluent
interfaces.

  • Removed the fluent interfaces (i.e., return $this) from requests,
    responses, GuzzleHttp\Collection, GuzzleHttp\Url,
    GuzzleHttp\Query, GuzzleHttp\Post\PostBody, and
    GuzzleHttp\Cookie\SetCookie. This blog post provides a good outline of
    why I did this: http:https://ocramius.github.io/blog/fluent-interfaces-are-evil/.
    This also makes the Guzzle message interfaces compatible with the current
    PSR-7 message proposal.
  • Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except
    for the HTTP request functions from function.php, these functions are now
    implemented in GuzzleHttp\Utils using camelCase. GuzzleHttp\json_decode
    moved to GuzzleHttp\Utils::jsonDecode. GuzzleHttp\get_path moved to
    GuzzleHttp\Utils::getPath. GuzzleHttp\set_path moved to
    GuzzleHttp\Utils::setPath. GuzzleHttp\batch should now be
    GuzzleHttp\Pool::batch, which returns an SplObjectStorage. Using functions.php
    caused problems for many users: they aren't PSR-4 compliant, require an
    explicit include, and needed an if-guard to ensure that the functions are not
    declared multiple times.
  • Rewrote adapter layer.
    • Removing all classes from GuzzleHttp\Adapter, these are now
      implemented as callables that are stored in GuzzleHttp\Ring\Client.
    • Removed the concept of "parallel adapters". Sending requests serially or
      concurrently is now handled using a single adapter.
    • Moved GuzzleHttp\Adapter\Transaction to GuzzleHttp\Transaction. The
      Transaction object now exposes the request, response, and client as public
      properties. The getters and setters have been removed.
  • Removed the "headers" event. This event was only useful for changing the
    body a response once the headers of the response were known. You can implement
    a similar behavior in a number of ways. One example might be to use a
    FnStream that has access to the transaction being sent. For example, when the
    first byte is written, you could check if the response headers match your
    expectations, and if so, change the actual stream body that is being
    written to.
  • Removed the asArray parameter from
    GuzzleHttp\Message\MessageInterface::getHeader. If you want to get a header
    value as an array, then use the newly added getHeaderAsArray() method of
    MessageInterface. This change makes the Guzzle interfaces compatible with
    the PSR-7 interfaces.
  • GuzzleHttp\Message\MessageFactory no longer allows subclasses to add
    custom request options using double-dispatch (this was an implementation
    detail). Instead, you should now provide an associative array to the
    constructor which is a mapping of the request option name mapping to a
    function that applies the option value to a request.
  • Removed the concept of "throwImmediately" from exceptions and error events.
    This control mechanism was used to stop a transfer of concurrent requests
    from completing. This can now be handled by throwing the exception or by
    cancelling a pool of requests or each outstanding future request individually.
  • Updated to "GuzzleHttp\Streams" 3.0.
    • GuzzleHttp\Stream\StreamInterface::getContents() no longer accepts a
      maxLen parameter. This update makes the Guzzle streams project
      compatible with the current PSR-7 proposal.
    • GuzzleHttp\Stream\Stream::__construct,
      GuzzleHttp\Stream\Stream::factory, and
      GuzzleHttp\Stream\Utils::create no longer accept a size in the second
      argument. They now accept an associative array of options, including the
      "size" key and "metadata" key which can be used to provide custom metadata.