Code Monkey home page Code Monkey logo

guzzle6-adapter's People

Contributors

alexander-schranz avatar dbu avatar ddeboer avatar gmponos avatar grahamcampbell avatar joelwurtz avatar nyholm avatar sagikazarmark avatar xabbuh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

guzzle6-adapter's Issues

Another case for allowing PHP 8 in composer.json

Considering the previous six conversations about this topic have been closed as won't fix, I was reluctant to bring this up again. But not all facts have been brought up in the previous discussions and I believe explicitly disallowing PHP 8 is not the right decision. Please let me explain.

It's true the version constraints on Guzzle 5 and 6 were wrong, they unintentionally allow PHP 8. Guzzle 5 does not work on PHP 8 and the version constraints have been updated [1] accordingly. Guzzle 6 is in security-only mode so did not receive the PHP 8 fixes Guzzle 7 had and PHP 8 is not officially supported. But accidentally, it does work. Looking at the changes done to Guzzle 7 to support PHP 8 [2], they only touch annotations and tests.

While nobody will guarantee every part of the library works on PHP 8, in practice Guzzle 6 runs fine on PHP 8, including the async functions used by this adapter. Also, Drupal 9.1 officially supports PHP 8 and they do that using Guzzle 6.5.5.

So, yes it's good advice to tell people to upgrade to Guzzle 7. A warning about using Guzzle 6 on PHP 8 might be appropriate too. But I don't see why people depending on Guzzle 6 should be forced to fork this repository if they have a depedency on this adapter.

If there actually is an incompatibility I'd appreciate it if someone could point out what part is incompatible.

[1] guzzle/guzzle#2834
[2] https://github.com/guzzle/guzzle/pull/2715/files

Related issues: #76 #77 #78 #80 #81 #82

PHP 8 support

Description

It would be great if this adapter could support PHP 8. Guzzle 6 allows it in composer.json

Add auto discovery for GuzzleClient

Q A
Bug? no
New Feature? yes

Actual Behavior

If you want to use this Adapter, then you have to instantiate the Guzzle Client and pass through the constructor.

Expected Behavior

Use the php-http/discovery package to auto discover the Guzzle Client and create it.

Possible Solutions

Add the php-http/discovery package as requirement.
Add documentation.

Trying to send multipart

Hi,

I am building an API Client at the moment and I am trying to send a POST request with multipart data.

The data I am trying to send looks like the following.

array:1 [▼
  "multipart" => array:2 [▼
    0 => array:2 [▼
      "name" => "file"
      "contents" => stream resource @135 ▶} // contents is fopen($file, 'r')
    ]
    1 => array:2 [▼
      "name" => "apikey"
      "contents" => "mysecretapikey"
    ]
  ]
]

Using Guzzle 6 Standalone I would do it like this and this works just fine.

$guzzle = new \GuzzleHttp\Client($options);

$response = $guzzle->request('POST', $uri, ['multipart' => $body]);

dump($response->getBody()->getContents());

Now when trying to use the adapter I came up with this.

$guzzle = new \GuzzleHttp\Client($options);

$adapter = new \Http\Adapter\Guzzle6\Client($guzzle);

// For form_params I could do ...
// $body = \GuzzleHttp\Psr7\stream_for(http_build_query($params));
// but how am I going to add multipart data to a request?
$request = new \GuzzleHttp\Psr7\Request($method, $uri, $headers, $body);

$pluginClient = new HttpMethodsClient(
    new PluginClient($adapter, $this->plugins),
    $this->messageFactory
);

$response = $adapter->sendRequest($request);

Sending the request with the adapter always results in a 403 Forbidden because the multipart data gets useless after building it with stream_for. So how do I send a multipartrequest with this adapter since there is no request method?

Empty response body on some URLs

Hi there,

When using the Guzzle 6 adapter, the response body of some URLs will be empty, whereas if I just use the Guzzle HTTP client alone, the content comes through just fine.

Before you ask, I'm using the sendRequest() method, not the sendAsyncRequest() one, so I don't have to explicitly do Promise handling.

Steps to reproduce:

Add the following to a composer.json file and run composer install:

{
    "require": {
        "php-http/message": "^1.2",
        "php-http/guzzle6-adapter": "^1.1"
    }
}

Proof of concept code:

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use Http\Adapter\Guzzle6\Client as HttpClient;
use Http\Message\MessageFactory\GuzzleMessageFactory as MessageFactory;

$sources = [
    // Only the Guzzle HTTP client can fetch the contents of this URL
    'http://www.artstation.com/artwork.rss',

    // Both methods can fetch the contents of this URL
    'http://feeds2.feedburner.com/webdesignerdepot',
];

$timeout = 6;

foreach ($sources as $url) {
    //
    // Guzzle HTTP client
    //
    $client = new Client([
        'timeout'         => $timeout,
        'connect_timeout' => $timeout,
    ]);

    $response = $client->request('GET', $url);
    $guzzle = $response->getBody()->getContents();

    //
    // Guzzle 6 HTTPlug adapter
    // 
    $client = HttpClient::createWithConfig([
        'timeout'         => $timeout,
        'connect_timeout' => $timeout,
    ]);

    $message = new MessageFactory;

    $request = $message->createRequest('GET', $url);
    $response = $client->sendRequest($request);

    $httplug = $response->getBody()->getContents();


    // Uncomment to see the actual contents
    // var_dump($guzzle, $httplug);

    // Show the fetched URL and the MD5 hash of the content we got
    // d41d8cd98f00b204e9800998ecf8427e is the MD5 hash of an empty string
    echo $url.':'.PHP_EOL.md5($guzzle).PHP_EOL.md5($httplug).PHP_EOL.PHP_EOL;
}

Edited:
Versions tested:

  • PHP 5.5.29 and 7.0.8
  • php-http/guzzle6-adapter 1.1.1
  • guzzlehttp/guzzle 6.0.0, 6.0.1, 6.0.2, 6.1.0, 6.1.1, 6.2.0, 6.2.1

No Redirects following (default guzzle behaviour changed)

PHP version: PHP 7.4.8 (But should happen in any other I guess)

Description
When I use guzzle6, it follows redirects, when I use this adapter, it doesn't follow redirects by default.

How to reproduce

<?php
require "vendor/autoload.php";

$uri = new \GuzzleHttp\Psr7\Uri('https://embed.spotify.com/oembed?url=https%3A%2F%2Fopen.spotify.com%2Fplaylist%2F37i9dQZF1DWYtg7TV07mgz%3Fsi%3DOTx1DyDhSPK5q5V1CTR5NQ&format=json');
$request = new \GuzzleHttp\Psr7\Request('GET',$uri);

$goodOldGuzzle = new \GuzzleHttp\Client();
$guzzleAdapter = \Http\Adapter\Guzzle6\Client::createWithConfig([]);

var_dump(
	$goodOldGuzzle->send($request)->getStatusCode(),
	$guzzleAdapter->sendRequest($request)->getStatusCode(),
);

Responses will be 200 and 304.

e.g.: https://phpsandbox.io/n/bitter-frog-l2q1

Possible Solution
Sorry, I didn't dig much into this library so no idea. My guess is to not change the default options of guzzle maybe ? 🤷

Additional context
I made this one sandbox thingy to prove my problem.
https://phpsandbox.io/n/bitter-frog-l2q1

production.ERROR: Interface 'Http\Client\HttpClient' not found

PHP 7.4

Receiving this error in the laravel log

[2020-07-06 09:20:11] production.ERROR: Interface 'Http\Client\HttpClient' not found {"exception":"[object] (Error(code: 0): Interface 'Http\Client\HttpClient' not found at /home/livefreshr/public_html/livefreshr.com/releases/113/vendor/php-http/guzzle6-adapter/src/Client.php:21)
[stacktrace]

Any idea how to resolve?

Exception is thrown with 4XX and 5XX responses

Q A
Bug? yes
New Feature? no
Version v1.1.1

Actual Behavior

Documentation says:

By default clients will always return a PSR-7 response instead of throwing a HttpException. Write your application to check the response status or use the Error Plugin to make sure the HttpException is thrown.

However both sendRequest() and sendAsyncRequest() throw an HttpException instead of returning the response. See example script below for comparing behaviour of different clients and 404response.

https://gist.github.com/tuupola/527823d9a37848a6b35621204ec7b121

Expected Behavior

Call to sendRequest() should return response object with 404 status. Promise from sendAsyncRequest() call should resolve to fulfilled promise and receive response object with 404 status.

Steps to Reproduce

use Http\Adapter\Guzzle6\Client as Guzzle;
use GuzzleHttp\Client as GuzzleClient;
use Http\Message\MessageFactory\DiactorosMessageFactory;
use Http\Message\StreamFactory\DiactorosStreamFactory;
use Psr\Http\Message\ResponseInterface;

$nosuch = (new DiactorosMessageFactory)->createRequest("GET", "http://google.com/nosuch");
$guzzle = new Guzzle(new GuzzleClient);

$promise = $guzzle
    ->sendAsyncRequest($nosuch)
    ->then(function (ResponseInterface $response) {
        print "Guzzle async status: ". $response->getStatusCode() . "\n";
        return $response;
    });

try {
    $promise->wait();
    print "Guzzle promise state: " . $promise->getState() . "\n";
} catch (\Exception $exception) {
    print "Guzzle async exception: " . get_class($exception) . "\n";
}

try {
    $response = $guzzle->sendRequest($nosuch);
    print "Guzzle sync status: " . $response->getStatusCode() . "\n";
} catch (\Exception $exception) {
    print "Guzzle sync exception: " . get_class($exception) . "\n";
}

/*
$ php guzzle.php
Guzzle async exception: Http\Client\Exception\HttpException
Guzzle sync exception: Http\Client\Exception\HttpException
*/

Guzzle 7 support

Description

Guzzle 7 is now released. The differences between 6 and 7 are minimal, and having updated a few private libraries/projects it's generally trivial to support both.

Support for PHP8

PHP8 has just been released. According to composer.json, this repo requires "php": "^7.1". Any plans to make it work with PHP8?

how to set up guzzle

it seems to set up guzzle in a way that it throws exceptions when receiving a 403 response. that exception is correctly converted to a php-http exception, but still not expected if i understand correctly how we wanted things to be set up. (i did not add any plugins, so the plugin to convert error responses to exceptions is not there.)

it seems that we have the Middleware::httpErrors in the guzzle stack. looking at https://github.com/php-http/guzzle6-adapter/blob/master/src/Guzzle6HttpAdapter.php#L32 and https://github.com/guzzle/guzzle/blob/master/src/Client.php#L64-L65 i think we would need to provide an empty or reduced handler stack. this in turn means that using php-http results in a very bare-bone - but the alternative is inconsistent behaviour.

found this while working on FriendsOfSymfony/FOSHttpCache#257 - to see a stack trace, look for Http\Client\Exception\HttpException: Client error:GET http://localhost:6181/user_context.php`resulted in a403 Forbiddenresponse:` in the travis output.

Exceptions thrown in chained promises are wrapped

Q A
Bug? yes
New Feature? no
Version v1.1.1

Actual Behavior

When chaining a promise and throwing an exception, the exception is wrapped inside an Exception with the message Invalid exception returned from Guzzle6.

Expected Behavior

That my exception is thrown directly.

Steps to Reproduce

$httpClient->sendAsyncRequest(new Request('GET', 'https://www.example.com/'))
    ->then(function (ResponseInterface $response) {
        throw new \Exception('Some problem');
    })
    ->wait();

... results in a RuntimeException with the message Invalid exception returned from Guzzle6 (with my Exception as previous).

Possible Solutions

The exception wrapping only makes sense when the actual request is being made (anything beyond that is not Guzzle). Either then return a different promise type in Promise::then()

return new static($this->promise->then($onFulfilled, $onRejected), $this->request);
or stop catching any exception
} elseif ($reason instanceof \Exception) {
$this->exception = new \RuntimeException('Invalid exception returned from Guzzle6', 0, $reason);
} else {
$this->exception = new \UnexpectedValueException('Reason returned from Guzzle6 must be an Exception', 0, $reason);
}

(Related, this will also hide any fatal errors (eg TypeError) behind the meaningless 'Reason returned from Guzzle6 must be an Exception' exception.)

Make an empty v3 version for guzzle7 compat

Description
Somewhat by design, the Guzzle6-adapter is incompatible with Guzzle7. Unfortunately it means that a dependent library/module cannot work with with Guzzle6 and 7 at the same time if it requires the features from the guzzle6-adapter.

So instead, I propose creating an empty version (v3) that requires Guzzle7. This will allow downstream users of this library to work with both versions of Guzzle. (require: guzzle6-adapter: ^2|^3; Guzzle: ^6|^7)

Unable to install via Composer

Defining the php-http/client-implementation virtual package dependency interactively does not work, as it is unable to resolve a package.

Setting up both values manually in composer.json like so:

"require": {
        ...
        "php-http/client-implementation": "^1.0"
    },
    "require-dev": {
        ...
        "php-http/guzzle6-adapter": "^1.0"
    },

also fails with the following errors:

  Problem 1
    - The requested package php-http/client-implementation could not be found in any version, there may be a typo in the package name.
  Problem 2
    - The requested package php-http/guzzle6-adapter could not be found in any version, there may be a typo in the package name.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.

@dbu says it's due to the adapter being outdated and providing the wrong thing.

FYI I am using php-http to replace the concrete Guzzle 5 dependency in this lib. The whole thing will result in a post on SitePoint.

Non PSR-18 exceptions

Q A
Bug? yes
New Feature? no
Version 2.0

Hello,

According to PSR-18

A Client MUST throw an instance of Psr\Http\Client\ClientExceptionInterface if and only if it is unable to send the HTTP request at all or if the HTTP response could not be parsed into a PSR-7 response object.

There was a tag made today that Guzzle-6 adapter is PSR-18 compliant https://github.com/php-http/guzzle6-adapter/releases/tag/v2.0.0

I am trying to understand how this works since there are cases that guzzle throws non PSR exception.

https://github.com/guzzle/guzzle/blob/master/src/Handler/StreamHandler.php#L55
https://github.com/guzzle/guzzle/blob/master/src/Handler/StreamHandler.php#L252
https://github.com/guzzle/guzzle/blob/master/src/Handler/CurlFactory.php#L458
https://github.com/guzzle/guzzle/blob/master/src/Handler/CurlFactory.php#L531

Maybe I am wrong or I miss something..

Imposible to post via adapter

Q A
Version 1.1.1

Actual Behavior

Post is absolutely useless via package, because not sending any options, so is it expected behaviour?

Steps to Reproduce

first server has such code:

var_export($_POST);die;

on second server such code:

    $config = [
        'connect_timeout' => 10,
        'timeout' => 10,
    ];
    $guzzle = new \GuzzleHttp\Client($config);
    $adapter = new \Http\Adapter\Guzzle6\Client($guzzle);

    $d["data1"] = rand(1, 1000);
    $d["data2"] =  rand(1, 1000);

    $request = new \GuzzleHttp\Psr7\Request('POST', 'http://testing.dev', ['form_params' => $d]);
    $response = $adapter->sendRequest($request);
    var_dump($response->getBody()->getContents());

output:

array (
)

Possible Solutions

Taking from original class, \guzzlehttp\guzzle\src\Client.php:92
public function sendAsync(RequestInterface $request, array $options = []) there is an option parameter, which catches any additional info, including form_data. But your code

    public function sendAsyncRequest(RequestInterface $request)
    {
        $promise = $this->client->sendAsync($request);

        return new Promise($promise, $request);
    }

does not pass such info. Neither in sendRequest method

Request for 1.2.0 stable

Q A
Bug? no
New Feature? no
Version master

Is there an ETA for stabilisation of the 1.2 minor version? I have a project that is currently relying on the unstable 1.2.x-dev branch, but I would love to use a stable tag.

Release 1.2.0

Before releasing 2.0, I think we should release 1.2 as the last version in the 1.x release branch.

Composer Installation Failed

Q A
New Feature? no
Version v2.0.0

Actual Behavior

Composer is giving me a error return then the package isn't intalled.
composer-fail

Your requirements could not be resolved to an installable set of packages.

Problem 1
- php-http/guzzle6-adapter v2.0.0 requires php-http/httplug ^2.0 -> satisfiable by php-http/httplug[v2.0.0].
- php-http/guzzle6-adapter v2.0.1 requires php-http/httplug ^2.0 -> satisfiable by php-http/httplug[v2.0.0].
- Conclusion: don't install php-http/httplug v2.0.0
- Installation request for php-http/guzzle6-adapter ^2.0 -> satisfiable by php-http/guzzle6-adapter[v2.0.0, v2.0.1].

Installation failed, reverting ./composer.json to its original content.

Steps to Reproduce

Just exec the command: composer require php-http/guzzle6-adapter

Could someone help me with this issue, please?

PHP increase breaks existing composer installs

Q A
Bug? yes
New Feature? no
Version Specific version or SHA of a commit

Actual Behavior

What is the actual behavior?

Downstream requirement of package breaks suddenly, as PHP version change was not announced previously, and there isn't a jump in version number.

Expected Behavior

What is the behavior you expect?

Version number increment to prevent packages requiring this library from breaking.

Steps to Reproduce

What are the steps to reproduce this bug? Please add code examples,
screenshots or links to GitHub repositories that reproduce the problem.

Many packages, for example SparkPost/php-sparkpost have a reliance on this package.

Recently, without warning the PHP requirements for this package were arbitrarily raised without increasing the version number for the package correspondingly. This lead to unexpected issues with composer unable to work out of the blue on PHP versions 5.5, 5.6 and 7.0 branches.

While I don't personally agree with the idea of raising PHP version requirements just for the sake of doing so (as there doesn't appear to be any sort of code requirement for this), what's harmful here is a package that wasn't updated in over a year suddenly updated, and particularly without increasing their version number), so that new installs of the same version number suddenly start failing.

Possible Solutions

This commit should be reverted, and then a new minor release tagged, so that there is a final version with PHP 5.5 - 7.0 compat. Then if desired it could be re-added with a corresponding tag of a new major release, so that people running composer update don't find things suddenly broken.

Promise\settle() is not working properly

Q A
Bug? yes
New Feature? no
Version guzzlehttp/guzzle 6.3.3 guzzlehttp/promises v1.3.1 guzzlehttp/psr7 1.4.2 php-http/guzzle6-adapter v1.1.1

Actual Behavior

If the first HTTP call (promise) returns HTTP >= 400 (which triggers and exception in Guzzle by default) then the adapter throws the exception for the first HTTP call instead it would return the result of all promises.

<?php

require_once "vendor/autoload.php";

use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Psr7\Request;


$client = new Client(['base_uri' => 'http://httpbin.org/']);

$pluginClient = new \Http\Client\Common\PluginClient(
  new Http\Adapter\Guzzle6\Client($client), []
);


// Initiate each request but do not block
$promises = [
  'image' => $pluginClient->sendAsyncRequest(new Request('GET', 'status/404')),
  'png'   => $pluginClient->sendAsyncRequest(new Request('GET', 'status/200')),
  'jpeg'  => $pluginClient->sendAsyncRequest(new Request('GET', 'status/200')),
  'webp'  => $pluginClient->sendAsyncRequest(new Request('GET', 'status/404'))
];

try {
  // Wait for the requests to complete, even if some of them fail
  $results = Promise\settle($promises)->wait();
}
catch (\Exception $e) {
  echo $e->getMessage();
}
exit(0);

Expected Behaviour

settle() should "Wait for the requests to complete, even if some of them fail". So even if the first HTTP call returns HTTP >= 400 an exception should not be thrown.

http://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests

<?php

require_once "vendor/autoload.php";

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client(['base_uri' => 'http://httpbin.org/']);

// Initiate each request but do not block
$promises = [
  'image' => $client->getAsync('status/404'),
  'png'   => $client->getAsync('status/200'),
  'jpeg'  => $client->getAsync('status/200'),
  'webp'  => $client->getAsync('status/404')
];

try {
  // Wait for the requests to complete, even if some of them fail
  $results = Promise\settle($promises)->wait();
}
catch (\Exception $e) {
  echo $e->getMessage();
}
exit(0);

Steps to Reproduce

See the code snippets above.

Possible Solutions

For the first sight it seems the adapter should also wrap the result of all promises to a Promise object and return that instead of returning the results directly. At least this is what Guzzle Promise's working code indicates for me.
https://github.com/guzzle/promises/blob/v1.3.1/src/Promise.php#L69

Upgrade the guzzlehttp version to maximum.

PHP version: x.y.z (hint: php --version)

Description

How to reproduce
conflict with pusher package.

Possible Solution
just replace "guzzlehttp/guzzle": "^7.2" add this line into the composer.json

Additional context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.