Replace Response class with PSR-7 Response class#152
Conversation
WyriHaximus
left a comment
There was a problem hiding this comment.
👍 for your work, found some things, any comment that occurs more then once is to point out all occurrences for the given comment.
README.md
Outdated
README.md
Outdated
README.md
Outdated
README.md
Outdated
src/Server.php
Outdated
There was a problem hiding this comment.
Shouldn't be a second check to ensure the contents of this header is chunked before we run the body through the chunked encoder? In case we add transfer encoding X or Y in the future?
There was a problem hiding this comment.
This is necessary at moment because nothing else would be allowed here. But have changed it to make this more ovious.
README.md
Outdated
There was a problem hiding this comment.
This line and the 3 lines above it are no longer relevant and ended up in middle of a code example, see https://github.com/legionth/http/blob/c0aef5da52404f458222acf3554c5f591c63395d/README.md#response
README.md
Outdated
There was a problem hiding this comment.
We don't pass $response anymore since this PR
README.md
Outdated
There was a problem hiding this comment.
We don't pass $response anymore since this PR
README.md
Outdated
There was a problem hiding this comment.
We don't pass $response anymore since this PR
README.md
Outdated
There was a problem hiding this comment.
We don't pass $response anymore since this PR
src/Server.php
Outdated
There was a problem hiding this comment.
Shouldn't we be using our own response class here, as it extends that class? Also we have a class name conflict: https://travis-ci.org/reactphp/http/jobs/215140364#L237
There was a problem hiding this comment.
Yea, must be a leftover thank you for spotting this.
src/Server.php
Outdated
There was a problem hiding this comment.
These 6 lines can be shortened to:
$promise = \React\Promise\resolve($callback($request));Additional benefit: supports also foreign thenables.
Another question: What happens if $callback synchronously throws an exception/throwable? This should probably turned into a rejected promises:
try {
$promise = \React\Promise\resolve($callback($request));
} catch (\Throwable $e) {
$promise = \React\Promise\reject($e);
} catch (\Exception $e) {
$promise = \React\Promise\reject($e);
}I'd prefer this over just letting the exception bubble up because it would handle exceptions in the same ways as if $callback returns a rejected promises (see also my next comment).
There was a problem hiding this comment.
The problem with $promise = \React\Promise\resolve($callback($request)); is that would have to use try-catch. With my lines the Exception would be handled by the Promise and will be recognized as rejected. But thanks for the line didn't knew it ;)
| } | ||
| $that->handleResponse($conn, $response, $request->getProtocolVersion()); | ||
| } | ||
| ); |
There was a problem hiding this comment.
This must also handle a rejected promise returned from $callback.
There was a problem hiding this comment.
You are right. Added something to cover this. Have a look 👍
README.md
Outdated
There was a problem hiding this comment.
misses trailing ,
same thing happening below
There was a problem hiding this comment.
Thx for spotting this.
clue
left a comment
There was a problem hiding this comment.
Love this feature and I'm happy to get this in once the outstanding change requests are resolved! ![]()
|
@clue yeah can't wait for |
57cc76c to
fd1affb
Compare
|
Thank you for all your rewievs! I rebased the branch. This didn't really changed the code much, but I hope this will make clearer what really changed. Happy to hear your opinons about this. |
README.md
Outdated
There was a problem hiding this comment.
…is responsible for processing the request and returning a response, which…
README.md
Outdated
There was a problem hiding this comment.
…MUST return an instance implementing…
README.md
Outdated
There was a problem hiding this comment.
I would suggest moving this to above the example, what do you think?
README.md
Outdated
There was a problem hiding this comment.
Why is this a SHOULD, what happens if consumers ignore this?
README.md
Outdated
README.md
Outdated
There was a problem hiding this comment.
Last sentence can probably be omitted?
README.md
Outdated
README.md
Outdated
There was a problem hiding this comment.
There's room for improvement here 👍 Is this really still necessary? 👍
README.md
Outdated
README.md
Outdated
There was a problem hiding this comment.
What happens if the callback function returns the wrong value?
src/Server.php
Outdated
There was a problem hiding this comment.
Note, that promises can be rejected with a non-exception (there is a pending PR to change that: reactphp/promise#93). The docs suggest a typehint against Exception for the error event listeners.
$http->on('error', function (Exception $e) {
});Maybe check against \Exception/ \Throwable here and turn non-exceptions into a \Exception?
There was a problem hiding this comment.
Added code to cover this behaviour.
| use Psr\Http\Message\ResponseInterface; | ||
| use RingCentral; | ||
| use React\Stream\ReadableStream; | ||
| use React\Promise\Promise; |
There was a problem hiding this comment.
Since you're starting to use react/promise explicitely, i recommend adding it to the composer.json. At the moment react/promise is only indirectly required via react/socket.
There was a problem hiding this comment.
Added to react/promise to composer.json
fd1affb to
b71e67b
Compare
|
Ping @clue . I fixed the README, also found some mistakes myself :) . Have a look. |
src/Server.php
Outdated
There was a problem hiding this comment.
Should test against \Throwable too.
There was a problem hiding this comment.
Keep in mind that the error event is type-hinted as Exception though!
src/Server.php
Outdated
There was a problem hiding this comment.
This exception message is very generic. Suggestion:
$ex = new \InvalidArgumentException(
sprintf(
'The response callback returned a rejected promise with a reason of type "%s" instead of a \Throwable or \Exception instance.'
is_object($ex) ? get_class($ex) : gettype($ex)
)
);
src/Server.php
Outdated
There was a problem hiding this comment.
Very generic exception message. Suggestion:
$ex = new \InvalidArgumentException(
sprintf(
'The response callback is expected to return an object implementing Psr\Http\Message\ResponseInterface, but returned "%s" instead.'
is_object($response) ? get_class($response) : gettype($response)
)
);There was a problem hiding this comment.
Added a more useful message. Have a look.
src/Server.php
Outdated
There was a problem hiding this comment.
Very generic exception message. Suggestion:
$ex = new \InvalidArgumentException(
sprintf(
'The response callback returned a rejected promise with a reason of type "%s" instead of a \Throwable or \Exception instance.'
is_object($ex) ? get_class($ex) : gettype($ex)
)
);There was a problem hiding this comment.
Added a more useful message. Have a look.
src/Server.php
Outdated
There was a problem hiding this comment.
Should test against \Throwable too.
There was a problem hiding this comment.
Thanks for the review.I reconsidered this and changed the code. The error-event on the Server should always be an Exception.
In the newest changes a RuntimeExpception will always be created, and a thrown exception will be added as previous to this RuntimeException.
Checkout the documentation and the code.
README.md
Outdated
There was a problem hiding this comment.
Does this paragraph still apply? I see some room for improvement here with the updated API 👍
There was a problem hiding this comment.
Yes this does still apply, at least for streams. Changed the documenation, have a look.
| ``` | ||
|
|
||
| If you do not want to send this header at all, you can use an empty array as | ||
| value like this: |
examples/01-hello-world.php
Outdated
There was a problem hiding this comment.
See above comment, is this line really (still) necessary?
There was a problem hiding this comment.
You are right. Change it in the newest commit.
|
|
||
| if ($response->getHeaderLine('Transfer-Encoding') === 'chunked') { | ||
| $stream = new ChunkedEncoder($body); | ||
| } |
There was a problem hiding this comment.
Isn't this header always removed or am I missing something? Also, who should be in control of this behavior in this first place? This whole method looks unneeded complex to me, sending a constant string body could be simplified, what do you think?
There was a problem hiding this comment.
Changed structure
b71e67b to
afc1bcd
Compare
| 'X-Powered-By' => 'PHP 3' | ||
| )); | ||
| $server = new Server($socket, function (RequestInterface $request) { | ||
| return new Response(200, array('X-Powered-By' => 'PHP 3')); |
There was a problem hiding this comment.
👍 on using PHP 3 as example, although I would have approved of 6 as well 😆
There was a problem hiding this comment.
Well, I can still change it while I'm on it. Just used the same example as before 😅
There was a problem hiding this comment.
If it where up to me: go for it 😎
8b954bc to
64839a4
Compare
64839a4 to
ce27ec6
Compare
| function ($error) use ($that, $conn) { | ||
| $message = 'The response callback is expected to resolve with an object implementing Psr\Http\Message\ResponseInterface, but rejected with "%s" instead.'; | ||
| $message = sprintf($message, is_object($error) ? get_class($error) : gettype($error)); | ||
| $exception = new \RuntimeException($message, null, $error instanceof \Exception ? $error : null); |
This is big PR. I recommend to try reviewing the single commits here.
The
Responseclass will be replaced with an that implements the PSR-7 ResponseInterface.So the callback function only needs the request object to be called. A
PSR-7 Responseobject will now be returned. Alternatively a Promise can be returned in this function, but this promise MUST resolve aPSR-7 Response. If the response need time be created, a promise must be used (checkoutexamples/04-stream-request.php).The new
Responseextends fromRingCentral\Psr7\Responsebut adds the possibility to add an ReadstreamInterface implemnation as body.Refs #28
Builds on top of #146