Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

Conversation

lboynton
Copy link
Contributor

@lboynton lboynton commented Jul 6, 2016

This change allows instances of Buzz\Browser to be used in the adapater, which is what people generally use with Buzz. Also allow any instance implementing Buzz's ClientInterface to be used, such as the curl implementation.

Note that MultiCurl does not work at this time as it needs to be flushed to send requests.

$this->client = $client;

if ($this->client === null) {
$this->client = new FileGetContents();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the default be FileGetContents or Browser?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that a Browser would be an unnecessary overhead here, if the user doesn't care about the underlying instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, will leave this as is then.

@lboynton
Copy link
Contributor Author

lboynton commented Jul 6, 2016

As mentioned in #2, the tests fail when using Buzz's Curl instance because no request body is sent for GET, HEAD and TRACE requests. The tests explicitly send a request body rather use query string parameters in these cases, which isn't what you would do in practice.

}

if ((!$this->client instanceof ClientInterface) && (!$this->client instanceof Browser)) {
throw new InvalidArgumentException(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prefer using \InvalidArgumentException. (Generally root namespace classes should not be imported.)

@sagikazarmark
Copy link
Member

Hm, since I haven't written the adapter tests I can't say for sure why we send a body for GET requests. @egeloen any ideas? Is this something that we should fix in the test suite?

@lboynton lboynton force-pushed the support-browser-instance branch from 609b6d3 to 27c6c20 Compare July 6, 2016 10:50
@lboynton
Copy link
Contributor Author

lboynton commented Jul 6, 2016

This is the relevant section in the test suite btw: https://github.com/php-http/adapter-integration-tests/blob/master/src/HttpBaseTest.php#L188

if ((!$this->client instanceof ClientInterface) && (!$this->client instanceof Browser)) {
throw new \InvalidArgumentException(
sprintf(
'Buzz adapter client of instance %s must implement %s or be an instance of %s',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we say 'The client passed to the Buzz adapter must either implement %s or be an instance of %s. You passed %s'.

@dbu
Copy link
Contributor

dbu commented Jul 7, 2016

thanks @lboynton , looks good!

GET requests are allowed to have a body. see for example elasticsearch...

so i think if the tests want to explicitly set a body, its fair to test that the body exists. is this what we talk about, or do the tests expect an empty body to be automatically present even when not doing anything? the later would sound like an implementation detail that should not be required by the tests.

@lboynton
Copy link
Contributor Author

lboynton commented Jul 7, 2016

Yes GET requests can have a body, but the Curl class in Buzz does not send a body for GET requests. So the current tests fail with the Curl class, but in practice the Curl class will probably work fine with the adapter as people don't generally use GET bodies. Perhaps this should be documented in the adapter.

@dbu
Copy link
Contributor

dbu commented Jul 7, 2016

okay, so that is essentially a bug of the buzz curl class. imo what we should do in the adapter is throw an exception when a body is set on a GET request to tell the user this is not supported. if somebody wants to use elasticsearch for example, they will be glad to have an exception rather than nothing working as expected.

the tests are currently green, not sure why. but i think in that case it would be ok to make the acceptance test skip the test about GET body, or have an alternative test that ensures we get the exception when setting a body.

the test suite should also do GET requests without body, if it not already does.

@lboynton lboynton force-pushed the support-browser-instance branch 4 times, most recently from f3f3e8c to 97c6b78 Compare July 7, 2016 14:19
@lboynton
Copy link
Contributor Author

lboynton commented Jul 7, 2016

OK I've added an exception which is thrown when trying to send a request body for GET, HEAD or TRACE requests when using the Curl client.

I've overridden the test methods to assert this behaviour. I'm not sure if this is the best approach or if I should modify the acceptance tests directly to be more flexible.

@lboynton lboynton force-pushed the support-browser-instance branch 2 times, most recently from 79e5ef8 to dc8c4a2 Compare July 7, 2016 16:57
// The Buzz Curl client does not send request bodies for request methods such as GET, HEAD and TRACE. Instead of
// silently ignoring the request body in these cases, throw an exception to make users aware.
if ($this->client instanceof Curl &&
$request->getBody()->getContents() &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use getSize() instead of getContents(), I believe that would be faster.

@Nyholm
Copy link
Member

Nyholm commented Jul 7, 2016

Awesome work. I think this looks really good! Thank you.

@lboynton lboynton force-pushed the support-browser-instance branch 2 times, most recently from b8f6ea3 to 2b5275c Compare July 7, 2016 19:53
// silently ignoring the request body in these cases, throw an exception to make users aware.
if ($this->client instanceof Curl &&
$request->getBody()->getSize() &&
!in_array(strtoupper($request->getMethod()), $validMethods, true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about custom methods, can they not have a body? that is, does buzz only keep the body if its one of those methods?

Copy link
Contributor Author

@lboynton lboynton Jul 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request methods which have request bodies are defined with CURLOPT_POSTFIELDS here: https://github.com/kriswallsmith/Buzz/blob/master/lib/Buzz/Client/AbstractCurl.php#L96

case RequestInterface::METHOD_POST:
case RequestInterface::METHOD_PUT:
case RequestInterface::METHOD_DELETE:
case RequestInterface::METHOD_PATCH:
case RequestInterface::METHOD_OPTIONS:
    $options[CURLOPT_POSTFIELDS] = $fields = static::getPostFields($request);

You can see it's just POST, PUT, DELETE, PATCH and OPTIONS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed. okay, thanks. @sagikazarmark do you have anything to add? from my point of view this PR is good to squash and merge.

@dbu
Copy link
Contributor

dbu commented Jul 7, 2016

great work, i think this is exactly right. also the tests seem to me what they should be. i consider it a bug or at least unexpected restriction from buzz to not support bodies in GET requests, so we should not make the test suite encourage such behaviour ;-)
your test alterations are exactly at the right place.

apart from that question about custom HTTP methods with body, this looks good to merge.

This change allows instances of Buzz\Browser to be used in the adapater, which is what people generally use with Buzz. Also allow any instance implementing Buzz's ClientInterface to be used, such as the curl implementation.

Note that:

- MultiCurl does not work at this time as it needs to be flushed to send requests.
- The Curl client does not apply request bodies to certain request methods such as GET, HEAD and TRACE. In order to inform users about this, we throw an exception if the Curl client is being used, and we're trying to send a request body with one of these methods.
@lboynton lboynton force-pushed the support-browser-instance branch from 2b5275c to 89ff8c2 Compare July 7, 2016 20:34
@lboynton
Copy link
Contributor Author

I've squashed my commits, is there anything else that needs doing on this?

@dbu dbu merged commit 4b1310a into php-http:master Jul 12, 2016
@dbu
Copy link
Contributor

dbu commented Jul 12, 2016

thanks a lot!

@lboynton
Copy link
Contributor Author

Thanks all! 🎉

@sagikazarmark
Copy link
Member

Sorry that I kind of missed this PR. Quickly reviewed it and it looks good to me. Thank you @lboynton for your work.

@lboynton lboynton deleted the support-browser-instance branch July 12, 2016 13:53
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants