-
Notifications
You must be signed in to change notification settings - Fork 4
Add support for using Buzz\Browser instance (fixes #2) #4
Conversation
$this->client = $client; | ||
|
||
if ($this->client === null) { | ||
$this->client = new FileGetContents(); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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( |
There was a problem hiding this comment.
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.)
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? |
609b6d3
to
27c6c20
Compare
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', |
There was a problem hiding this comment.
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'.
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. |
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. |
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. |
f3f3e8c
to
97c6b78
Compare
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. |
79e5ef8
to
dc8c4a2
Compare
// 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() && |
There was a problem hiding this comment.
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.
Awesome work. I think this looks really good! Thank you. |
b8f6ea3
to
2b5275c
Compare
// 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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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 ;-) 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.
2b5275c
to
89ff8c2
Compare
I've squashed my commits, is there anything else that needs doing on this? |
thanks a lot! |
Thanks all! 🎉 |
Sorry that I kind of missed this PR. Quickly reviewed it and it looks good to me. Thank you @lboynton for your work. |
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.