Guzzle, an extensible PHP HTTP client

Overview

Guzzle

Guzzle, PHP HTTP client

Latest Version Build Status Total Downloads

Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services.

  • Simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data, etc...
  • Can send both synchronous and asynchronous requests using the same interface.
  • Uses PSR-7 interfaces for requests, responses, and streams. This allows you to utilize other PSR-7 compatible libraries with Guzzle.
  • Supports PSR-18 allowing interoperability between other PSR-18 HTTP Clients.
  • Abstracts away the underlying HTTP transport, allowing you to write environment and transport agnostic code; i.e., no hard dependency on cURL, PHP streams, sockets, or non-blocking event loops.
  • Middleware system allows you to augment and compose client behavior.
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');

echo $response->getStatusCode(); // 200
echo $response->getHeaderLine('content-type'); // 'application/json; charset=utf8'
echo $response->getBody(); // '{"id": 1420053, "name": "guzzle", ...}'

// Send an asynchronous request.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
    echo 'I completed! ' . $response->getBody();
});

$promise->wait();

Help and docs

We use GitHub issues only to discuss bugs and new features. For support please refer to:

Installing Guzzle

The recommended way to install Guzzle is through Composer.

composer require guzzlehttp/guzzle

Version Guidance

Version Status Packagist Namespace Repo Docs PSR-7 PHP Version
3.x EOL guzzle/guzzle Guzzle v3 v3 No >= 5.3.3
4.x EOL guzzlehttp/guzzle GuzzleHttp v4 N/A No >= 5.4
5.x EOL guzzlehttp/guzzle GuzzleHttp v5 v5 No >= 5.4
6.x Security fixes guzzlehttp/guzzle GuzzleHttp v6 v6 Yes >= 5.5
7.x Latest guzzlehttp/guzzle GuzzleHttp v7 v7 Yes >= 7.2
Issues
  • Call to undefined function GuzzleHttp_idn_uri_convert()

    Call to undefined function GuzzleHttp_idn_uri_convert()

    Hello - after the December 2019 updates, we are receiving the following error. Our client code calls into Guzzle at #2, so we don't call GuzzleHttp_idn_uri_convert() directly:

    [28-Dec-2019 17:57:20 UTC] PHP Fatal error: Uncaught Error: Call to undefined function GuzzleHttp_idn_uri_convert() in wp-content/plugins/q4vrplugin/vendor/guzzlehttp/guzzle/src/Client.php:220 Stack trace: #0 guzzlehttp/guzzle/src/Client.php(155): GuzzleHttp\Client->buildUri(Object(GuzzleHttp\Psr7\Uri), Array)

    #1 guzzlehttp/guzzle/src/Client.php(183): GuzzleHttp\Client->requestAsync('GET', 'units', Array)

    #2 plugin/Models/ApiClient.php(97): GuzzleHttp\Client->request('GET', 'units', Array)

    Please let me know what additional information I can provide to assist.

    Thanks!

    Jim

    area/intl-icu 
    opened by jkelley33tech 74
  • Asynchronous requests with requestAsync() are not actually sent until you call  ->wait()

    Asynchronous requests with requestAsync() are not actually sent until you call ->wait()

    I expected that using $client->getAsync() with Curl will fire request immediately, leaving me some time to perform additional work before it completes:

    $req = $client->getAsync('http://api.com/get_a_lot_of_data'); // Shouldn't request be sent here ? ...
    
    // do something while the long request is in progress in order not to waste time
    do_work();
    
    $req->then(...);
    $req->wait(); // ... so here request can already complete
    

    But it turns out, that request will actually be fired only when you call $req->wait(), acting like a plain synchronous request.

    opened by drscre 73
  • Fix #312, #317, Response\*Visitor rewrite

    Fix #312, #317, Response\*Visitor rewrite

    This fixes #312 and allows for traversal of XML documents including nested attributes and namespaces.

    • [x] Remove implicit conversion of SimpleXMLElement to array
    • [x] Add traversal of XML document in XMLVisitor.
    • [x] Investigate ways of working around OperationResponseParser::visitAdditionalProperties() limitations
    • [x] Add XML namespace support traversal.
    • [x] Add combination tests for OperationResponseParser
    • [x] Add complex nested XML structures' tests with attributes and various additionalProperties stances.
    • [x] Protect xml and json structures in Visitors
    • [x] Optimize XmlVisitor::xmlToArray()
    • [x] Incorporate support for top-level arrays and model location definition.
    • [x] Fix Response\HeaderVisitor with additionalProperties
    opened by Thinkscape 55
  • PHP error:

    PHP error: "failed to open stream: Too many open files"

    I tried to do like 5k concurrent requests and got the above error. Can somebody help me please?

    kind/support 
    opened by TKafassis 43
  • INTL_IDNA_VARIANT_2003 is deprecated

    INTL_IDNA_VARIANT_2003 is deprecated

    Guzzle version(s) affected: 6.5.3 PHP version: 7.3.16 (hint: php --version) cURL version: 7.69.1 (hint: php -i | grep cURL)

    Description
    My Telegram Bot is giving me this error when upgrade from 6.4.0 to 6.5.3:

    idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated

    in Utils.php line 35 at HandleExceptions->handleError(8192, 'idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', '/home/erich33/vendor/guzzlehttp/guzzle/src/Utils.php', 35, array('uri' => object(Uri), 'options' => 0, 'idnaVariant' => 0))

    How to reproduce
    When somebody message to my Telegram Bot, I have a script which send to my email the Exceptions, and turns now a hell with this error.

    Possible Solution
    Downgrade to 6.4? Something with symfony idn?

    Additional context
    My actual composer.lock:

    { "name": "laravel/laravel", "type": "project", "description": "The Laravel Framework.", "keywords": [ "framework", "laravel" ], "license": "MIT", "require": { "php": "^7.3", "artesaos/seotools": "^0.17.1", "binarytorch/larecipe": "^2.2", "biscolab/laravel-recaptcha": "^4.0", "facebook/graph-sdk": "^5.7", "fideloper/proxy": "^4.0", "guzzlehttp/guzzle": "^6.5", "intervention/image": "^2.5", "irazasyed/telegram-bot-sdk": "3.1.0", "laravel-notification-channels/facebook": "^0.1.0", "laravel-notification-channels/facebook-poster": "^2.0", "laravel-notification-channels/telegram": "^0.3.0", "laravel-notification-channels/twitter": "^3.0", "laravel/framework": "^6.2", "laravel/passport": "^8.4", "laravel/socialite": "^4.1", "laravel/tinker": "^2.2", "overtrue/laravel-like": "^2.0", "predis/predis": "^1.1", "renatomarinho/laravel-page-speed": "^1.8", "rennokki/befriended": "^3.0", "rennokki/rating": "^2.0", "spatie/laravel-permission": "^3.11", "spatie/laravel-responsecache": "^6.3", "spatie/laravel-sitemap": "^5.3", "spatie/schema-org": "^2.2", "tedivm/fetch": "^0.7.1" }, "require-dev": { "barryvdh/laravel-debugbar": "^3.2", "beyondcode/laravel-dump-server": "^1.0", "filp/whoops": "^2.0", "fzaninotto/faker": "^1.4", "mockery/mockery": "^1.0", "nunomaduro/collision": "^3.0", "phpunit/phpunit": "^9.0" }, "config": { "optimize-autoloader": true, "preferred-install": "dist", "sort-packages": true }, "extra": { "laravel": { "dont-discover": [] } }, "autoload": { "files": [ "app/Helpers/Helper.php" ], "psr-4": { "App\": "app/" }, "classmap": [ "database/seeds", "database/factories" ] }, "autoload-dev": { "psr-4": { "Tests\": "tests/" } }, "minimum-stability": "dev", "prefer-stable": true, "scripts": { "post-autoload-dump": [ "Illuminate\Foundation\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi", "@php artisan optimize", "@php artisan view:clear", "@php artisan cache:clear", "@php artisan responsecache:clear" ], "post-root-package-install": [ "@php -r "file_exists('.env') || copy('.env.example', '.env');"" ], "post-create-project-cmd": [ "@php artisan key:generate --ansi" ] } }

    area/intl-icu 
    opened by n3omaster 38
  • PHP Fatal error:  Uncaught GuzzleHttp\Exception\RequestException: cURL error 2: easy handle already used in multi handle

    PHP Fatal error: Uncaught GuzzleHttp\Exception\RequestException: cURL error 2: easy handle already used in multi handle

    Guzzle: 6.2.3 PHP: 7.3.16 Curl: 7.19.7

    Description

    Library used for Google Shopping API product feeds

    Feeds worked successfully every 20 minutes for 2 years and first 5 hours of 17 April 2020

    Then:

    PHP Fatal error: Uncaught GuzzleHttp\Exception\RequestException: cURL error 2: easy handle already used in multi handle (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) in ../vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:162 Stack trace: #0 ../vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(129): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array) #1 ../vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(89): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory)) #2 ../vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory)) #3 ../vendor/guzzlehttp/guzzle/src/Handl in ../vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php on line 162

    No change to server, site configuration or any associated php or library files.

    Same error every time the script now runs.

    I am not a programmer but can follow instructions!

    Any leads or guidance will be appreciated as the feed developer is no longer available.

    TIA

    opened by EsSa55 35
  • using GuzzleHttp\Pool doesn't free up memory after request is fulfilled

    using GuzzleHttp\Pool doesn't free up memory after request is fulfilled

    I need to download a lot of remote packages. I am using the Pool function according to the documentation here: http://docs.guzzlephp.org/en/latest/quickstart.html#making-a-request

    I'm not sure how I can free up the used memory. The packages are all small but several tens of thousands. How can I properly unset/free $response? unset(), $response->getBody()->close(); all seem not to do what I want.

    
    use GuzzleHttp\Pool;
    use GuzzleHttp\Client;
    use GuzzleHttp\Psr7\Request;
    
    require __DIR__ . '/vendor/autoload.php';
    
    $client = new Client(['base_uri' => '...']);
    
    $requests = function ()
    {
        ...
    
        yield $index => new Request('GET', ...);
    };
    
    $pool = new Pool($client, $requests(), [
        'concurrency' => 50,
        'fulfilled' => function ($response, $index)
        {
            $content = $response->getBody()
                                ->getContents();
    
            file_put_contents('storage/' . $index, $content);
    
            print 'fulfilled index:' . $index . PHP_EOL;
        },
        'rejected' => function ($reason, $index)
        {
            print 'rejected index:' . $index . PHP_EOL;
        },
    ]);
    
    $promise = $pool->promise();
    
    $promise->wait();
    
    blocked/needs-more-information lifecycle/stale 
    opened by drsect0r 35
  • Sequential POSTs suffer drastic performance hit due to php:// streams

    Sequential POSTs suffer drastic performance hit due to php:// streams

    I'm going to preface this by saying I'm not sure if it is a bug, or simply something that needs to be documented. Or perhaps I'm just using Guzzle incorrectly! :)

    I was seeing extremely slow performance on sequential Guzzle requests. For example, here is a benchmark where I am issuing 100 sequential POST requests ( not in parallel, these are entirely serial) with request bodies of various sizes (from about 20 bytes up to 5kb):

        Method Name             Iterations    Average Time      Ops/second
        ---------------------  ------------  --------------    -------------
        curlMultiHandleSmall : [100       ] [0.0012452316284] [803.06344]
        curlMultiHandleMedium: [100       ] [0.0025620341301] [390.31486]
        curlMultiHandleLarge : [100       ] [0.0020819020271] [480.33000]
        guzzleSmall          : [100       ] [0.0424066281319] [23.58122]
        guzzleMedium         : [100       ] [0.0430183744431] [23.24588]
        guzzleLarge          : [100       ] [0.0423791432381] [23.59651]
    

    curlMultiHandle is my own simple, naive implementation of a curl multi-handle transport layer. I wrote it initially just as a placeholder so I could implement everything else. I'm now replacing it with Guzzle for obvious reasons (unit test coverage, battle-hardened with bug fixes, etc).

    However, the performance drop was staggering. A peek at xdebug/cachegrind shows that Guzzle is eating time with curl_multi_select (times are absolute and in milliseconds):

    selection_033

    What is surprising is that this behavior is not found in my naive implementation, despite the fact that the actual multi-handle code is extremely similar (pretty much identical process, just simplified). Representative cachegrind from my code shows that curl_multi_select isn't even represented (most of the time is actually taken by curl_multi_exec, but its an order of magnitude less than Guzzle):

    selection_034

    So that's odd. I spent a few hours debugging and eventually thought to look at curl's transfer stats. Turns out, Guzzle's "speed_download" and "speed_upload" are atrociously slow:

                [total_time] => 0.040236
                [namelookup_time] => 2.7E-5
                [connect_time] => 2.7E-5
                [pretransfer_time] => 9.2E-5
                [size_upload] => 19
                [size_download] => 100
                [speed_download] => 2485
                [speed_upload] => 472
    

    Compared to my implementation:

                [total_time] => 0.001016
                [namelookup_time] => 1.5E-5
                [connect_time] => 1.5E-5
                [pretransfer_time] => 7.6E-5
                [size_upload] => 19
                [size_download] => 100
                [speed_download] => 98425
                [speed_upload] => 18700
    

    So with that in mind, I continued digging through Guzzle and discovered that Guzzle loads all request bodies into a PHP temp memory stream. After a bit more digging, I discovered the body_as_string parameter to force Guzzle to pass the request body as a string.

    $options = array(
        'curl.options' => array(
            'body_as_string'   => true,
        )
    );
    $client = new \Guzzle\Http\Client(null, $options);
    

    Turns out that was the issue. Benchmark:

        Method Name             Iterations    Average Time      Ops/second
        ---------------------  ------------  --------------    -------------
        curlMultiHandleSmall : [100       ] [0.0027452158928] [364.27008]
        curlMultiHandleMedium: [100       ] [0.0023763251305] [420.81784]
        curlMultiHandleLarge : [100       ] [0.0021409964561] [467.07224]
        guzzleSmall          : [100       ] [0.0032468485832] [307.99096]
        guzzleMedium         : [100       ] [0.0037671685219] [265.45136]
        guzzleLarge          : [100       ] [0.0039931154251] [250.43103]
    

    curl stats show normal upload/downloat speed:

        [total_time] => 0.000739
        [namelookup_time] => 8.0E-6
        [connect_time] => 8.0E-6
        [pretransfer_time] => 2.7E-5
        [size_upload] => 19
        [size_download] => 100
        [speed_download] => 135317
        [speed_upload] => 25710
    

    And finally the cachegrind looks much improved:

    selection_035

    So I guess that's a long winded way of saying " Hey, there is a performance issue but I'm not sure why ". I don't use php://temp streams much myself, so I'm not sure what issues are associated with them. I wouldn't assume they are slow, since they are memory streams, but clearly something is going wrong.

    I would love to hear your thoughts!

    opened by polyfractal 33
  • composer fails with

    composer fails with "requires ext-curl" when cURL is installed

    I'm 100% positive I have curl installed - I use it often, and have for many hears. That said, when I run composer from the Tumblr PHP API (which has guzzle as a dependency), it fails with:

    Loading composer repositories with package information
    Installing dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - guzzle/guzzle v3.8.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.8.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.7.4 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.7.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.7.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.7.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.7.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.6.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.5.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.4.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.4.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.4.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.4.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.3.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.3.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.2.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.1.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.1.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - guzzle/guzzle v3.1.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
        - Installation request for guzzle/guzzle >=3.1.0,<4 -> satisfiable by guzzle/guzzle[v3.1.0, v3.1.1, v3.1.2, v3.2.0, v3.3.0, v3.3.1, v3.4.0, v3.4.1, v3.4.2, v3.4.3, v3.5.0, v3.6.0, v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4, v3.8.0, v3.8.1].
    

    WAMP, Windows 8.1

    Is this a known issue, or am I missing something?

    TYIA

    opened by moagrius 30
  • Exception Message truncation isn't so friendly

    Exception Message truncation isn't so friendly

    Hi everyone,

    I know this has been extensively discussed here https://github.com/guzzle/guzzle/issues/1722 but unfortunately the exception truncation is a constant pain-point for me to the point that I'm almost maintaining a fork of Guzzle just to change that number. I understand a few of the points made in the thread such as the uncertainty of the size of the content in the response. A counter-argument that I would like to raise is the fact that we are forced into treating Guzzle Exceptions differently in our systems because Guzzle won't let me see enough of the response content. And then I have to turn this

    $client->get($resource);
    

    into this

    try {
        $client->get($resource);
    } catch(BadResponseException $e) {
        $e->getResponse()->getBody()->getContents();
    }
    

    throughout my entire platform. Sometimes we include packages that make usage of Guzzle and the package won't let me see the full error message as well.

    This seem such a small issue that brings a lot of headache. an extremely simple static Client::MESSAGE_SIZE = 6400; would suffice for me and probably for most of the people suffering from this. The pain-point for me is located on 5xx requests and 4xx requests between internal microservices. Those are not production-ready code that I'm working on and trying to stabilize them in a way that I'll never have a 5xx or 4xx, but I don't know what to fix because I can't see the error message.

    Something else described on the linked thread was this:

    Obviously you don't want to log that 10k JSON, so in this case you should extract the necessary/useful information from the body, and properly log it instead of the exception message.

    Why Obviously I don't want to log that 10k JSON? What if I do? Even if I don't need the 10k, 120 characters is still not enough for me to see which table name does not exist from a standard MySQL error.

    Anyway, I would really hope that this could be revisited. I would like to finish by saying that what Guzzle is doing right now is forcing me to catch an exception not because I should catch it, but because I cannot see the exception's message if I don't. I would like to be able to only catch exceptions that I really need to catch and let all other exceptions be reported.

    Thanks for the this amazing tool.

    opened by deleugpn 30
  • Guzzle adds an empty header on multipart POST request containing an animated GIF

    Guzzle adds an empty header on multipart POST request containing an animated GIF

    Guzzle version(s) affected: 7.3, dev-master PHP version: 7.4.19 cURL version: 7.77.0

    Description
    When used to make a multipart POST request containing an animated GIF, the guzzle client adds an HTTP header consisting only of whitespace (6 spaces in the name, 12 in the value). This invalid header causes server errors when using strict HTTP message implementations such as nyholm/psr7.

    How to reproduce

    $client = new GuzzleHttp\Client();
    $options = [
      'multipart' => [
        [
          'name' => 'file',
          'contents' => fopen('/path/to/an/animated.gif', 'r'), // e.g. https://micropub.rocks/media/w3c-socialwg.gif
          'filename' => 'img.gif'
        ]
      ]
    ];
    $res = $client->request('POST', 'https://micropub.taprootproject.com/upload.php', $options);
    

    results in apache_request_headers() looking like this:

    Array
    (
        [Host] => micropub.taprootproject.com
        [      ] =>             
        [User-Agent] => GuzzleHttp/7
        [Content-Type] => multipart/form-data; boundary=fbd6adfea2ba76bcfbd21b673ab289ec6e65c7be
        [Content-Length] => 1509659
    )
    

    …and $_SERVER containing this key/value:

    [HTTP_______] =>             
    

    For the moment, I’ll leave my test page https://micropub.taprootproject.com/upload.php as it is, a no-op which prints the results of apache_request_headers().

    Additional context
    This seems to occur only when uploading animated gifs. I tried two different animated gifs and one static gif. Both animated gifs caused the empty header, the static one did not.

    Making the same request via command line curl 7.64.1 doesn’t include the mysterious header: shell commands and output

    When using nyholm/psr7-server, a request containing invalid headers such as this one results in the following stack trace:

    [18-Jun-2021 17:38:41 UTC] PHP Fatal error:  Uncaught InvalidArgumentException: Header name must be an RFC 7230 compatible string. in /home/•••/domains/micropub.taprootproject.com/vendor/nyholm/psr7/src/MessageTrait.php:179
    Stack trace:
    #0 /home/•••/domains/micropub.taprootproject.com/vendor/nyholm/psr7/src/MessageTrait.php(146): Nyholm\Psr7\ServerRequest->validateAndTrimHeader('      ', '            ')
    #1 /home/•••/domains/micropub.taprootproject.com/vendor/nyholm/psr7/src/MessageTrait.php(98): Nyholm\Psr7\ServerRequest->setHeaders(Array)
    #2 /home/•••/domains/micropub.taprootproject.com/vendor/nyholm/psr7-server/src/ServerRequestCreator.php(90): Nyholm\Psr7\ServerRequest->withAddedHeader('      ', '            ')
    #3 /home/•••/domains/micropub.taprootproject.com/vendor/nyholm/psr7-server/src/ServerRequestCreator.php(71): Nyholm\Psr7Server\ServerRequestCreator->fromArrays(Array, Array, Array, Array, Array, Array, Resource id #127)
    #4 /home/•••/domains/micropub.taprootproject.com/vendor/slim/slim/Slim/Factory/Psr1 in /•••/domains/micropub.taprootproject.com/vendor/nyholm/psr7/src/MessageTrait.php on line 179
    
    opened by barnabywalters 2
  • Improve the comment regarding `CURLOPT_ENCODING` handling

    Improve the comment regarding `CURLOPT_ENCODING` handling

    While researching how the decode_content option is meant to be used and looking into the Guzzle source code I stumbled over this part of the code, because it was non-obvious to me that providing an empty string to CURLOPT_ENCODING does not disable the decoding, but instead enables all decoders.

    opened by TimWolla 0
  • Non treated exception on StreamHandler.php causes error_handler problems

    Non treated exception on StreamHandler.php causes error_handler problems

    Guzzle version(s) affected: 7.x PHP version: 7.3.22 cURL version: x.y.z

    Description
    An exception in the function "createResource" of the class "StreamHandler" (vendor\guzzlehttp\guzzle\src\Handler\StreamHandler.php) breaks the code and causes the function "restore_error_handler" not to be called. As it is the error_handler is not reset to the previous one and lose the hability to handle errors and warnings.

    How to reproduce
    I think tha by justo looking at the core it becomes clear that this behavior happends. The same problem has already been solved in the function "tryFopen" in the file "Utils.php".

    Possible Solution
    Inspired in the solutions of the above file mentiond this solved my problem. image

    opened by ewrubleski 0
  • Message: Call to undefined method GuzzleHttp\Utils::chooseHandler()

    Message: Call to undefined method GuzzleHttp\Utils::chooseHandler()

    Guzzle version(s) affected: 7.3.0 PHP version: 7.4.14 cURL version: 7.58.0 (hint: php -i | grep cURL)

    Description
    GuzzleHttp\Utils::chooseHandler() when calling google ads api

    How to reproduce
    https://github.com/googleads/google-ads-php/issues/612#issuecomment-859560324

    opened by chiragvels 3
  • Could Not Resolve Host

    Could Not Resolve Host

    The introduction of amp/http-client will cause guzzlehttp to trigger the could not resolve host exception (occasionally)

    It should be noted that: only composer refers to amp/http-client, and does not use any code inside

    When I removed the dependency of amp/http-client from composer, everything returned to normal, and it was the same result after repeated testing.

    opened by mztlive 0
  • Fixed typo in SetCookieTest

    Fixed typo in SetCookieTest

    Closes https://github.com/guzzle/guzzle/issues/2894.

    opened by GrahamCampbell 2
  • Chore: Enable strict typing in tests

    Chore: Enable strict typing in tests

    opened by GrahamCampbell 0
  • Typo or PHP voodoo magic?

    Typo or PHP voodoo magic?

    Hi everyone. Can someone explain this line?

    https://github.com/guzzle/guzzle/blob/de6f1e58e735754b888649495ed4cb9ae3b19589/tests/Cookie/SetCookieTest.php#L377

    @SamuelWei @FelixJacobi and I think the != should be a -.

    opened by sualko 0
  • [Docs] Add clarification on redirects and PSR-18

    [Docs] Add clarification on redirects and PSR-18

    Using GuzzleHttp\Client::sendRequest() ignores the allow_redirects configuration option. This is discussed in #2584.

    I ran into this issue while upgrading from Guzzle 6 with HttPlug to Guzzle 7. This different behavior is not documented properly in my opinion. I only found out why the redirects are not followed by going through closed issues on the repository.

    If the wording is not in line with the rest of the document feel free to rewrite or reject. This is merely an attempt to help others :)

    opened by timoschinkel 0
Releases(7.3.0)
  • 7.3.0(Mar 23, 2021)

  • 7.2.0(Oct 10, 2020)

  • 7.1.1(Sep 30, 2020)

  • 7.1.0(Sep 22, 2020)

  • 7.0.1(Jun 27, 2020)

  • 7.0.0(Jun 27, 2020)

  • 7.0.0-rc.1(Jun 15, 2020)

  • 7.0.0-beta.2(May 25, 2020)

  • 7.0.0-beta.1(Dec 30, 2019)

    First beta release of the 7.x release branch.

    Major changes:

    • PSR-18 support
    • Dropped PHP 5.x support

    Enjoy!

    Many thanks to everyone who worked on this release, especially:

    • @Nyholm
    • @gmponos
    • @alexeyshockov
    • @GrahamCampbell
    Source code(tar.gz)
    Source code(zip)
  • 6.5.2(Dec 23, 2019)

  • 6.5.1(Dec 21, 2019)

  • 5.3.3(Jul 31, 2018)

  • 6.3.2(Mar 26, 2018)

    • Bug fix: Parsing 0 epoch expiry times in cookies #2014
    • Improvement: Better ConnectException detection #2012
    • Bug fix: Malformed domain that contains a "/" #1999
    • Bug fix: Undefined offset when a cookie has no first key-value pair #1998
    • Improvement: Support PHPUnit 6 #1953
    • Bug fix: Support empty headers #1915
    • Bug fix: Ignore case during header modifications #1916
    • Minor code cleanups, documentation fixes and clarifications.
    Source code(tar.gz)
    Source code(zip)
    guzzle.phar(421.25 KB)
    guzzle.zip(133.15 KB)
  • 6.3.0(Jun 22, 2017)

    • Feature: force IP resolution (ipv4 or ipv6) #1608, #1659
    • Improvement: Don't include summary in exception message when body is empty #1621
    • Improvement: Handle on_headers option in MockHandler #1580
    • Improvement: Added SUSE Linux CA path #1609
    • Improvement: Use class reference for getting the name of the class instead of using hardcoded strings #1641
    • Feature: Added read_timeout option #1611
    • Bug fix: PHP 7.x fixes #1685, #1686, #1811
    • Deprecation: BadResponseException instantiation without a response #1642
    • Feature: Added NTLM auth #1569
    • Feature: Track redirect HTTP status codes #1711
    • Improvement: Check handler type during construction #1745
    • Improvement: Always include the Content-Length if there's a body #1721
    • Feature: Added convenience method to access a cookie by name #1318
    • Bug fix: Fill CURLOPT_CAPATH and CURLOPT_CAINFO properly #1684
    • Improvement: Use \GuzzleHttp\Promise\rejection_for function instead of object init #1827
    • Minor code cleanups, documentation fixes and clarifications.
    Source code(tar.gz)
    Source code(zip)
    guzzle.phar(419.51 KB)
    guzzle.zip(132.80 KB)
  • 6.2.1(Jul 18, 2016)

    • Addressing HTTP_PROXY security vulnerability, CVE-2016-5385: https://httpoxy.org/. Please update to this version of Guzzle in order to mitigate the vulnerability when sending Guzzle requests inside of a CGI application.
    • Fixing timeout bug with StreamHandler
    • Only read up to Content-Length in PHP StreamHandler to avoid timeouts when a server does not honor Connection: close.
    • Ignore URI fragment when sending requests.
    Source code(tar.gz)
    Source code(zip)
    guzzle.phar(386.57 KB)
    guzzle.zip(122.94 KB)
  • 6.2.0(Mar 21, 2016)

    • Feature: added GuzzleHttp\json_encode and GuzzleHttp\json_decode. https://github.com/guzzle/guzzle/pull/1389
    • Bug fix: Fix sleep calculation when waiting for delayed requests. https://github.com/guzzle/guzzle/pull/1324
    • Feature: More flexible history containers. https://github.com/guzzle/guzzle/pull/1373
    • Bug fix: defer sink stream opening in StreamHandler. https://github.com/guzzle/guzzle/pull/1377
    • Bug fix: do not attempt to escape cookie values. https://github.com/guzzle/guzzle/pull/1406
    • Feature: report original content encoding and length on decoded responses. https://github.com/guzzle/guzzle/pull/1409
    • Bug fix: rewind seekable request bodies before dispatching to cURL. https://github.com/guzzle/guzzle/pull/1422
    • Bug fix: provide an empty string to http_build_query for HHVM workaround. https://github.com/guzzle/guzzle/pull/1367
    Source code(tar.gz)
    Source code(zip)
    guzzle.phar(366.93 KB)
    guzzle.zip(118.02 KB)
  • 6.1.1(Nov 22, 2015)

    • Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4
    • Feature: HandlerStack is now more generic. https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e
    • Bug fix: setting verify to false in the StreamHandler now disables peer verification. https://github.com/guzzle/guzzle/issues/1256
    • Feature: Middleware now uses an exception factory, including more error context. https://github.com/guzzle/guzzle/pull/1282
    • Feature: better support for disabled functions. https://github.com/guzzle/guzzle/pull/1287
    • Bug fix: fixed regression where MockHandler was not using sink. https://github.com/guzzle/guzzle/pull/1292
    Source code(tar.gz)
    Source code(zip)
    guzzle.phar(361.73 KB)
    guzzle.zip(116.17 KB)
  • 6.0.0(May 26, 2015)

    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]);
    
    Source code(tar.gz)
    Source code(zip)
    guzzle.phar(339.97 KB)
    guzzle.zip(110.11 KB)
Owner
Guzzle
An extensible PHP HTTP client
Guzzle
HTTP header kit for PHP 7.1+ (incl. PHP 8) based on PSR-7

HTTP header kit for PHP 7.1+ (incl. PHP 8) based on PSR-7 Installation composer require sunrise/http-header-kit How to use? HTTP Header Collection Mor

Sunrise // PHP 60 Apr 10, 2021
PHP's lightweight HTTP client

Buzz - Scripted HTTP browser Buzz is a lightweight (<1000 lines of code) PHP 7.1 library for issuing HTTP requests. The library includes three clients

Kris Wallsmith 1.9k Jun 11, 2021
Custom PHP curl library for the Laravel 5 framework - developed by Ixudra

ixudra/curl Custom PHP cURL library for the Laravel 4 or 5 framework - developed by Ixudra. The package provides an easy interface for sending cURL re

Jan Oris 545 Jun 17, 2021
Supercharge your app or SDK with a testing library specifically for Guzzle

Full Documentation at guzzler.dev Supercharge your app or SDK with a testing library specifically for Guzzle. Guzzler covers the process of setting up

null 274 May 21, 2021
HTTPlug, the HTTP client abstraction for PHP

HTTPlug HTTPlug, the HTTP client abstraction for PHP. Intro HTTP client standard built on PSR-7 HTTP messages. The HTTPlug client interface is compati

The PHP HTTP group 2.2k Jun 13, 2021
Simple handler system used to power clients and servers in PHP (this project is no longer used in Guzzle 6+)

RingPHP Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function. RingPHP be used to power HTTP clie

Guzzle 845 Jun 10, 2021
Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.

This is a port of the VCR Ruby library to PHP. Record your test suite's HTTP interactions and replay them during future test runs for fast, determinis

php-vcr 991 Jun 14, 2021
Retrofit implementation in PHP. A REST client for PHP.

Retrofit PHP Retrofit is a type-safe REST client. It is blatantly stolen from square/retrofit and implemented in PHP. ❗ UPGRADE NOTICE ❗ Version 3 int

null 151 May 3, 2021
A super lightweight PSR-7 implementation

PSR-7 implementation A super lightweight PSR-7 implementation. Very strict and very fast. Description Guzzle Laminas Slim Nyholm Lines of code 3.300 3

Tobias Nyholm 745 Jun 20, 2021
Unirest in PHP: Simplified, lightweight HTTP client library.

Unirest for PHP Unirest is a set of lightweight HTTP libraries available in multiple languages, built and maintained by Mashape, who also maintain the

Kong 1.2k Jun 12, 2021
PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs

PHP Curl Class: HTTP requests made easy PHP Curl Class makes it easy to send HTTP requests and integrate with web APIs. Installation Requirements Quic

null 2.8k Jun 14, 2021
A Chainable, REST Friendly, PHP HTTP Client. A sane alternative to cURL.

Httpful Httpful is a simple Http Client library for PHP 7.2+. There is an emphasis of readability, simplicity, and flexibility – basically provide the

Nate Good 1.7k May 31, 2021
↪️ Bypass for PHP creates a custom HTTP Server to return predefined responses to client requests

Bypass for PHP provides a quick way to create a custom HTTP Server to return predefined responses to client requests.Useful for tests with Pest PHP or PHPUnit.

CiaReis 74 Jun 16, 2021
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.4k Jun 12, 2021