-
Notifications
You must be signed in to change notification settings - Fork 7
Fix react/http-client 0.4.13 response body issue #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
4476a7a to
7a3dc7b
Compare
| * @param ReactClient|null $client | ||
| */ | ||
| public function __construct( | ||
| ResponseFactory $responseFactory = null, |
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.
This is BC Break, you should add it to the last parameter of the constructor, it would still be BC break but less given people may use the discovery system.
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.
I know this is BC Break but seems more "logic" to add it just after the ResponseFactory... I think more persons will use a custom ResponseFactory / StreamFactory than a custom Loop or Client...
|
If we use the StreamFactory as the last parameter of the constructor and we add php-http/message to the dependencies tree there will be no BC break, as react/http-client already include guzzle/psr7 implementation and this library has a dependency on php-http/discovery then you will always have a StreamFactory service even if it was not injected. |
|
Ok 😅 so I'll update my code! |
|
LGTM, @dbu @sagikazarmark Ok for you ? IMO there is no bc break here. |
| $bodyStream = $this->streamFactory->createStream(); | ||
| $reactResponse->on('data', function ($data) use (&$bodyStream) { | ||
| if ($data instanceof StreamInterface) { | ||
| $bodyStream = $data; |
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.
could this have side effects? maybe on performance when we have large streams?
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.
You're right, this mean load the whole string in memory... Maybe I can use the incoming stream as $bodyStream like before ? This is just a compatibility statement with react < 0.4.13.
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.
Not to mention getContents reads the remainder, not the whole stream
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.
Maybe I can use the incoming stream as $bodyStream like before ?
I think this will be very hard :/. There is no way to avoid memory problem here as react want us to work with data and not stream so the react interface block us from doing anything.
The only way to do that is to be sure that we create a stream using php://temp by example (not in memory, or at least not to much) and then read -> write by chunk of specified size (8192 is the best as it's the default chunk for PHP so there is no internal buffer).
But i don't think we should do this as the last version of react only give us data as a string and not a StreamInterface so this would be an enhancement for old version (so when people will update this lib with the enhancement they will certainly also update react/http-client which does not provide a StreamInterface anymore, so this enhancement will never be used...).
Not to mention getContents reads the remainder, not the whole stream
👍 We should only cast the stream to string $bodyStream->write((string) $data); in the same way that react has update it's library.
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.
In fact you could remove the condition and only do :
$bodyStream->write((string) $data);
|
As long as the comment above is resolved OK for me |
|
I've updated the code with string cast, much simpler 😄. |
composer.json
Outdated
| "react/stream": "^0.4.3", | ||
| "php-http/discovery": "^1.0" | ||
| "php-http/discovery": "^1.0", | ||
| "php-http/message": "^1.0" |
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.
Why is php-http/message added?
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.
This library now require a StreamFactory to work which is added in the constructor, but it can be set to null and use the discovery system to work.
So if we keep it like that, this will be BC for people setting all the contrusctor parameters in order to avoid using Discovery, as the new parameter cannnot be found.
However react/http-client depends on guzzlehttp/psr7 so by adding php-http/message we are sure to found a service for the StreamFactory in all cases so there is no BC.
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.
Okey, I've missed that discussion.
I agree. But I would like to remove that line before tagging 1.0 (and preferably before tagging 0.3.0).
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.
So you want that I remove that line in this PR ?
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.
No.
if this PR does not break BC then I'm happy leaving this line. But it should be removed next time we release a BC breaking change.
| $bodyStream = $data; | ||
| } else { | ||
| $bodyStream->write($data); | ||
| } |
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.
Code style: (string) $data
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.
Updated
Before the first body received was a StreamInterface then a string… Now it’s always a string. StreamFactory discovery have been introduced to handle stream creation. Also require “php-http/message” as dev dependency to get StreamFactory object.
|
Hello ! To address #20 in the same time (and avoid adding / moving the line in two different commits) I've already moved I also added a changelog update. If everyone is OK, I'll merge the PR asap. |
What's in this PR?
This PR has been pushed to fixed the compatibility error with
react/http-clientv0.4.13.Why?
There was a break change published in v0.4.13 around response body type. Before the first response body was sent as a
StreamInterfaceinstance, now it's "just" string.Before we are using that
StreamInterfaceinstance as$bodyStream... Now it has been updated to use theHttp\Message\StreamFactoryto build a valid StreamInterface instance.If a BC Break because I've introduced a new constructor parameter to be able to inject
StreamFactoryinstance...Of course the
Http\Discovery\StreamFactoryDiscoveryobject is used when parameter is empty.With this change, I've tested on lowest dependencies and it works too.
Checklist
To Do