diff --git a/README.md b/README.md index 2d2eb4ce..ba8d8330 100644 --- a/README.md +++ b/README.md @@ -373,20 +373,19 @@ See also [`withFollowRedirects()`](#withfollowredirects) for more details. As stated above, this library provides you a powerful, async API by default. -If, however, you want to integrate this into your traditional, blocking environment, -you should look into also using [clue/reactphp-block](https://github.com/clue/reactphp-block). - -The resulting blocking code could look something like this: +You can also integrate this into your traditional, blocking environment by using +[reactphp/async](https://github.com/reactphp/async). This allows you to simply +await async HTTP requests like this: ```php -use Clue\React\Block; +use function React\Async\await; $browser = new React\Http\Browser(); $promise = $browser->get('http://example.com/'); try { - $response = Block\await($promise, Loop::get()); + $response = await($promise); // response successfully received } catch (Exception $e) { // an error occurred while performing the request @@ -396,15 +395,20 @@ try { Similarly, you can also process multiple requests concurrently and await an array of `Response` objects: ```php +use function React\Async\await; +use function React\Promise\all; + $promises = array( $browser->get('http://example.com/'), $browser->get('http://www.example.org/'), ); -$responses = Block\awaitAll($promises, Loop::get()); +$responses = await(all($promises)); ``` -Please refer to [clue/reactphp-block](https://github.com/clue/reactphp-block#readme) for more details. +This is made possible thanks to fibers available in PHP 8.1+ and our +compatibility API that also works on all supported PHP versions. +Please refer to [reactphp/async](https://github.com/reactphp/async#readme) for more details. Keep in mind the above remark about buffering the whole response message in memory. As an alternative, you may also see one of the following chapters for the diff --git a/composer.json b/composer.json index 4c9a0383..57adfc2c 100644 --- a/composer.json +++ b/composer.json @@ -38,11 +38,12 @@ "ringcentral/psr7": "^1.2" }, "require-dev": { - "clue/block-react": "^1.5", "clue/http-proxy-react": "^1.7", "clue/reactphp-ssh-proxy": "^1.3", "clue/socks-react": "^1.3", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "react/async": "^4 || ^3 || ^2", + "react/promise-timer": "^1.9" }, "autoload": { "psr-4": { "React\\Http\\": "src" } diff --git a/tests/BrowserTest.php b/tests/BrowserTest.php index 39be453a..f14b9ee6 100644 --- a/tests/BrowserTest.php +++ b/tests/BrowserTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http; -use Clue\React\Block; use Psr\Http\Message\RequestInterface; use React\Http\Browser; use React\Promise\Promise; diff --git a/tests/Client/FunctionalIntegrationTest.php b/tests/Client/FunctionalIntegrationTest.php index 64a3ea8a..d95bf828 100644 --- a/tests/Client/FunctionalIntegrationTest.php +++ b/tests/Client/FunctionalIntegrationTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http\Client; -use Clue\React\Block; use Psr\Http\Message\ResponseInterface; use React\EventLoop\Loop; use React\Http\Client\Client; @@ -51,7 +50,7 @@ public function testRequestToLocalhostEmitsSingleRemoteConnection() $promise = Stream\first($request, 'close'); $request->end(); - Block\await($promise, null, self::TIMEOUT_LOCAL); + \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT_LOCAL)); } public function testRequestLegacyHttpServerWithOnlyLineFeedReturnsSuccessfulResponse() @@ -73,7 +72,7 @@ public function testRequestLegacyHttpServerWithOnlyLineFeedReturnsSuccessfulResp $promise = Stream\first($request, 'close'); $request->end(); - Block\await($promise, null, self::TIMEOUT_LOCAL); + \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT_LOCAL)); } /** @group internet */ @@ -94,7 +93,7 @@ public function testSuccessfulResponseEmitsEnd() $promise = Stream\first($request, 'close'); $request->end(); - Block\await($promise, null, self::TIMEOUT_REMOTE); + \React\Async\await(\React\Promise\Timer\timeout($promise, self::TIMEOUT_REMOTE)); } /** @group internet */ @@ -122,7 +121,7 @@ public function testPostDataReturnsData() $request->end($data); - $buffer = Block\await($deferred->promise(), null, self::TIMEOUT_REMOTE); + $buffer = \React\Async\await(\React\Promise\Timer\timeout($deferred->promise(), self::TIMEOUT_REMOTE)); $this->assertNotEquals('', $buffer); @@ -154,7 +153,7 @@ public function testPostJsonReturnsData() $request->end($data); - $buffer = Block\await($deferred->promise(), null, self::TIMEOUT_REMOTE); + $buffer = \React\Async\await(\React\Promise\Timer\timeout($deferred->promise(), self::TIMEOUT_REMOTE)); $this->assertNotEquals('', $buffer); diff --git a/tests/FunctionalBrowserTest.php b/tests/FunctionalBrowserTest.php index 2b7bd58c..95092ac1 100644 --- a/tests/FunctionalBrowserTest.php +++ b/tests/FunctionalBrowserTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http; -use Clue\React\Block; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use React\EventLoop\Loop; @@ -24,6 +23,9 @@ class FunctionalBrowserTest extends TestCase private $browser; private $base; + /** @var ?SocketServer */ + private $socket; + /** * @before */ @@ -88,14 +90,17 @@ public function setUpBrowserAndServer() } if ($path === '/delay/10') { - return new Promise(function ($resolve) { - Loop::addTimer(10, function () use ($resolve) { + $timer = null; + return new Promise(function ($resolve) use (&$timer) { + $timer = Loop::addTimer(10, function () use ($resolve) { $resolve(new Response( 200, array(), 'hello' )); }); + }, function () use (&$timer) { + Loop::cancelTimer($timer); }); } @@ -140,10 +145,20 @@ public function setUpBrowserAndServer() var_dump($path); }); - $socket = new SocketServer('127.0.0.1:0'); - $http->listen($socket); - $this->base = str_replace('tcp:', 'http:', $socket->getAddress()) . '/'; + $this->socket = new SocketServer('127.0.0.1:0'); + $http->listen($this->socket); + + $this->base = str_replace('tcp:', 'http:', $this->socket->getAddress()) . '/'; + } + + /** + * @after + */ + public function cleanUpSocketServer() + { + $this->socket->close(); + $this->socket = null; } /** @@ -151,7 +166,7 @@ public function setUpBrowserAndServer() */ public function testSimpleRequest() { - Block\await($this->browser->get($this->base . 'get')); + \React\Async\await($this->browser->get($this->base . 'get')); } public function testGetRequestWithRelativeAddressRejects() @@ -159,7 +174,7 @@ public function testGetRequestWithRelativeAddressRejects() $promise = $this->browser->get('delay'); $this->setExpectedException('InvalidArgumentException', 'Invalid request URL given'); - Block\await($promise); + \React\Async\await($promise); } /** @@ -167,7 +182,7 @@ public function testGetRequestWithRelativeAddressRejects() */ public function testGetRequestWithBaseAndRelativeAddressResolves() { - Block\await($this->browser->withBase($this->base)->get('get')); + \React\Async\await($this->browser->withBase($this->base)->get('get')); } /** @@ -175,7 +190,7 @@ public function testGetRequestWithBaseAndRelativeAddressResolves() */ public function testGetRequestWithBaseAndFullAddressResolves() { - Block\await($this->browser->withBase('http://example.com/')->get($this->base . 'get')); + \React\Async\await($this->browser->withBase('http://example.com/')->get($this->base . 'get')); } public function testCancelGetRequestWillRejectRequest() @@ -184,7 +199,7 @@ public function testCancelGetRequestWillRejectRequest() $promise->cancel(); $this->setExpectedException('RuntimeException'); - Block\await($promise); + \React\Async\await($promise); } public function testCancelRequestWithPromiseFollowerWillRejectRequest() @@ -195,13 +210,13 @@ public function testCancelRequestWithPromiseFollowerWillRejectRequest() $promise->cancel(); $this->setExpectedException('RuntimeException'); - Block\await($promise); + \React\Async\await($promise); } public function testRequestWithoutAuthenticationFails() { $this->setExpectedException('RuntimeException'); - Block\await($this->browser->get($this->base . 'basic-auth/user/pass')); + \React\Async\await($this->browser->get($this->base . 'basic-auth/user/pass')); } /** @@ -211,7 +226,7 @@ public function testRequestWithAuthenticationSucceeds() { $base = str_replace('://', '://user:pass@', $this->base); - Block\await($this->browser->get($base . 'basic-auth/user/pass')); + \React\Async\await($this->browser->get($base . 'basic-auth/user/pass')); } /** @@ -225,7 +240,7 @@ public function testRedirectToPageWithAuthenticationSendsAuthenticationFromLocat { $target = str_replace('://', '://user:pass@', $this->base) . 'basic-auth/user/pass'; - Block\await($this->browser->get($this->base . 'redirect-to?url=' . urlencode($target))); + \React\Async\await($this->browser->get($this->base . 'redirect-to?url=' . urlencode($target))); } /** @@ -240,7 +255,7 @@ public function testRedirectFromPageWithInvalidAuthToPageWithCorrectAuthenticati $base = str_replace('://', '://unknown:invalid@', $this->base); $target = str_replace('://', '://user:pass@', $this->base) . 'basic-auth/user/pass'; - Block\await($this->browser->get($base . 'redirect-to?url=' . urlencode($target))); + \React\Async\await($this->browser->get($base . 'redirect-to?url=' . urlencode($target))); } public function testCancelRedirectedRequestShouldReject() @@ -252,7 +267,7 @@ public function testCancelRedirectedRequestShouldReject() }); $this->setExpectedException('RuntimeException', 'Request cancelled'); - Block\await($promise); + \React\Async\await($promise); } public function testTimeoutDelayedResponseShouldReject() @@ -260,7 +275,7 @@ public function testTimeoutDelayedResponseShouldReject() $promise = $this->browser->withTimeout(0.1)->get($this->base . 'delay/10'); $this->setExpectedException('RuntimeException', 'Request timed out after 0.1 seconds'); - Block\await($promise); + \React\Async\await($promise); } public function testTimeoutDelayedResponseAfterStreamingRequestShouldReject() @@ -270,7 +285,7 @@ public function testTimeoutDelayedResponseAfterStreamingRequestShouldReject() $stream->end(); $this->setExpectedException('RuntimeException', 'Request timed out after 0.1 seconds'); - Block\await($promise); + \React\Async\await($promise); } /** @@ -278,7 +293,7 @@ public function testTimeoutDelayedResponseAfterStreamingRequestShouldReject() */ public function testTimeoutFalseShouldResolveSuccessfully() { - Block\await($this->browser->withTimeout(false)->get($this->base . 'get')); + \React\Async\await($this->browser->withTimeout(false)->get($this->base . 'get')); } /** @@ -286,7 +301,7 @@ public function testTimeoutFalseShouldResolveSuccessfully() */ public function testRedirectRequestRelative() { - Block\await($this->browser->get($this->base . 'redirect-to?url=get')); + \React\Async\await($this->browser->get($this->base . 'redirect-to?url=get')); } /** @@ -294,7 +309,7 @@ public function testRedirectRequestRelative() */ public function testRedirectRequestAbsolute() { - Block\await($this->browser->get($this->base . 'redirect-to?url=' . urlencode($this->base . 'get'))); + \React\Async\await($this->browser->get($this->base . 'redirect-to?url=' . urlencode($this->base . 'get'))); } /** @@ -304,7 +319,7 @@ public function testFollowingRedirectsFalseResolvesWithRedirectResult() { $browser = $this->browser->withFollowRedirects(false); - Block\await($browser->get($this->base . 'redirect-to?url=get')); + \React\Async\await($browser->get($this->base . 'redirect-to?url=get')); } public function testFollowRedirectsZeroRejectsOnRedirect() @@ -312,12 +327,12 @@ public function testFollowRedirectsZeroRejectsOnRedirect() $browser = $this->browser->withFollowRedirects(0); $this->setExpectedException('RuntimeException'); - Block\await($browser->get($this->base . 'redirect-to?url=get')); + \React\Async\await($browser->get($this->base . 'redirect-to?url=get')); } public function testResponseStatus204ShouldResolveWithEmptyBody() { - $response = Block\await($this->browser->get($this->base . 'status/204')); + $response = \React\Async\await($this->browser->get($this->base . 'status/204')); $this->assertFalse($response->hasHeader('Content-Length')); $body = $response->getBody(); @@ -327,7 +342,7 @@ public function testResponseStatus204ShouldResolveWithEmptyBody() public function testResponseStatus304ShouldResolveWithEmptyBodyButContentLengthResponseHeader() { - $response = Block\await($this->browser->get($this->base . 'status/304')); + $response = \React\Async\await($this->browser->get($this->base . 'status/304')); $this->assertEquals('12', $response->getHeaderLine('Content-Length')); $body = $response->getBody(); @@ -342,7 +357,7 @@ public function testGetRequestWithResponseBufferMatchedExactlyResolves() { $promise = $this->browser->withResponseBuffer(5)->get($this->base . 'get'); - Block\await($promise); + \React\Async\await($promise); } public function testGetRequestWithResponseBufferExceededRejects() @@ -354,7 +369,7 @@ public function testGetRequestWithResponseBufferExceededRejects() 'Response body size of 5 bytes exceeds maximum of 4 bytes', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 0 ); - Block\await($promise); + \React\Async\await($promise); } public function testGetRequestWithResponseBufferExceededDuringStreamingRejects() @@ -366,7 +381,7 @@ public function testGetRequestWithResponseBufferExceededDuringStreamingRejects() 'Response body size exceeds maximum of 4 bytes', defined('SOCKET_EMSGSIZE') ? SOCKET_EMSGSIZE : 0 ); - Block\await($promise); + \React\Async\await($promise); } /** @@ -379,7 +394,7 @@ public function testCanAccessHttps() $this->markTestSkipped('Not supported on HHVM'); } - Block\await($this->browser->get('https://www.google.com/')); + \React\Async\await($this->browser->get('https://www.google.com/')); } /** @@ -400,7 +415,7 @@ public function testVerifyPeerEnabledForBadSslRejects() $browser = new Browser($connector); $this->setExpectedException('RuntimeException'); - Block\await($browser->get('https://self-signed.badssl.com/')); + \React\Async\await($browser->get('https://self-signed.badssl.com/')); } /** @@ -421,7 +436,7 @@ public function testVerifyPeerDisabledForBadSslResolves() $browser = new Browser($connector); - Block\await($browser->get('https://self-signed.badssl.com/')); + \React\Async\await($browser->get('https://self-signed.badssl.com/')); } /** @@ -430,13 +445,13 @@ public function testVerifyPeerDisabledForBadSslResolves() public function testInvalidPort() { $this->setExpectedException('RuntimeException'); - Block\await($this->browser->get('http://www.google.com:443/')); + \React\Async\await($this->browser->get('http://www.google.com:443/')); } public function testErrorStatusCodeRejectsWithResponseException() { try { - Block\await($this->browser->get($this->base . 'status/404')); + \React\Async\await($this->browser->get($this->base . 'status/404')); $this->fail(); } catch (ResponseException $e) { $this->assertEquals(404, $e->getCode()); @@ -448,14 +463,14 @@ public function testErrorStatusCodeRejectsWithResponseException() public function testErrorStatusCodeDoesNotRejectWithRejectErrorResponseFalse() { - $response = Block\await($this->browser->withRejectErrorResponse(false)->get($this->base . 'status/404')); + $response = \React\Async\await($this->browser->withRejectErrorResponse(false)->get($this->base . 'status/404')); $this->assertEquals(404, $response->getStatusCode()); } public function testPostString() { - $response = Block\await($this->browser->post($this->base . 'post', array(), 'hello world')); + $response = \React\Async\await($this->browser->post($this->base . 'post', array(), 'hello world')); $data = json_decode((string)$response->getBody(), true); $this->assertEquals('hello world', $data['data']); @@ -463,7 +478,7 @@ public function testPostString() public function testRequestStreamReturnsResponseBodyUntilConnectionsEndsForHttp10() { - $response = Block\await($this->browser->withProtocolVersion('1.0')->get($this->base . 'stream/1')); + $response = \React\Async\await($this->browser->withProtocolVersion('1.0')->get($this->base . 'stream/1')); $this->assertEquals('1.0', $response->getProtocolVersion()); $this->assertFalse($response->hasHeader('Transfer-Encoding')); @@ -474,7 +489,7 @@ public function testRequestStreamReturnsResponseBodyUntilConnectionsEndsForHttp1 public function testRequestStreamReturnsResponseWithTransferEncodingChunkedAndResponseBodyDecodedForHttp11() { - $response = Block\await($this->browser->get($this->base . 'stream/1')); + $response = \React\Async\await($this->browser->get($this->base . 'stream/1')); $this->assertEquals('1.1', $response->getProtocolVersion()); @@ -486,7 +501,7 @@ public function testRequestStreamReturnsResponseWithTransferEncodingChunkedAndRe public function testRequestStreamWithHeadRequestReturnsEmptyResponseBodWithTransferEncodingChunkedForHttp11() { - $response = Block\await($this->browser->head($this->base . 'stream/1')); + $response = \React\Async\await($this->browser->head($this->base . 'stream/1')); $this->assertEquals('1.1', $response->getProtocolVersion()); @@ -505,7 +520,9 @@ public function testRequestStreamReturnsResponseWithResponseBodyUndecodedWhenRes $this->base = str_replace('tcp:', 'http:', $socket->getAddress()) . '/'; - $response = Block\await($this->browser->get($this->base . 'stream/1')); + $response = \React\Async\await($this->browser->get($this->base . 'stream/1')); + + $socket->close(); $this->assertEquals('1.1', $response->getProtocolVersion()); @@ -528,10 +545,10 @@ public function testReceiveStreamAndExplicitlyCloseConnectionEvenWhenServerKeeps $this->base = str_replace('tcp:', 'http:', $socket->getAddress()) . '/'; - $response = Block\await($this->browser->get($this->base . 'get', array())); + $response = \React\Async\await($this->browser->get($this->base . 'get', array())); $this->assertEquals('hello', (string)$response->getBody()); - $ret = Block\await($closed->promise(), null, 0.1); + $ret = \React\Async\await(\React\Promise\Timer\timeout($closed->promise(), 0.1)); $this->assertTrue($ret); $socket->close(); @@ -545,7 +562,7 @@ public function testPostStreamChunked() $stream->end('hello world'); }); - $response = Block\await($this->browser->post($this->base . 'post', array(), $stream)); + $response = \React\Async\await($this->browser->post($this->base . 'post', array(), $stream)); $data = json_decode((string)$response->getBody(), true); $this->assertEquals('hello world', $data['data']); @@ -561,7 +578,7 @@ public function testPostStreamKnownLength() $stream->end('hello world'); }); - $response = Block\await($this->browser->post($this->base . 'post', array('Content-Length' => 11), $stream)); + $response = \React\Async\await($this->browser->post($this->base . 'post', array('Content-Length' => 11), $stream)); $data = json_decode((string)$response->getBody(), true); $this->assertEquals('hello world', $data['data']); @@ -581,7 +598,7 @@ public function testPostStreamWillStartSendingRequestEvenWhenBodyDoesNotEmitData $this->base = str_replace('tcp:', 'http:', $socket->getAddress()) . '/'; $stream = new ThroughStream(); - Block\await($this->browser->post($this->base . 'post', array(), $stream)); + \React\Async\await($this->browser->post($this->base . 'post', array(), $stream)); $socket->close(); } @@ -591,7 +608,7 @@ public function testPostStreamClosed() $stream = new ThroughStream(); $stream->close(); - $response = Block\await($this->browser->post($this->base . 'post', array(), $stream)); + $response = \React\Async\await($this->browser->post($this->base . 'post', array(), $stream)); $data = json_decode((string)$response->getBody(), true); $this->assertEquals('', $data['data']); @@ -611,7 +628,7 @@ public function testSendsHttp11ByDefault() $this->base = str_replace('tcp:', 'http:', $socket->getAddress()) . '/'; - $response = Block\await($this->browser->get($this->base)); + $response = \React\Async\await($this->browser->get($this->base)); $this->assertEquals('1.1', (string)$response->getBody()); $socket->close(); @@ -631,7 +648,7 @@ public function testSendsExplicitHttp10Request() $this->base = str_replace('tcp:', 'http:', $socket->getAddress()) . '/'; - $response = Block\await($this->browser->withProtocolVersion('1.0')->get($this->base)); + $response = \React\Async\await($this->browser->withProtocolVersion('1.0')->get($this->base)); $this->assertEquals('1.0', (string)$response->getBody()); $socket->close(); @@ -639,7 +656,7 @@ public function testSendsExplicitHttp10Request() public function testHeadRequestReceivesResponseWithEmptyBodyButWithContentLengthResponseHeader() { - $response = Block\await($this->browser->head($this->base . 'get')); + $response = \React\Async\await($this->browser->head($this->base . 'get')); $this->assertEquals('5', $response->getHeaderLine('Content-Length')); $body = $response->getBody(); @@ -649,7 +666,7 @@ public function testHeadRequestReceivesResponseWithEmptyBodyButWithContentLength public function testRequestStreamingGetReceivesResponseWithStreamingBodyAndKnownSize() { - $response = Block\await($this->browser->requestStreaming('GET', $this->base . 'get')); + $response = \React\Async\await($this->browser->requestStreaming('GET', $this->base . 'get')); $this->assertEquals('5', $response->getHeaderLine('Content-Length')); $body = $response->getBody(); @@ -660,7 +677,7 @@ public function testRequestStreamingGetReceivesResponseWithStreamingBodyAndKnown public function testRequestStreamingGetReceivesResponseWithStreamingBodyAndUnknownSizeFromStreamingEndpoint() { - $response = Block\await($this->browser->requestStreaming('GET', $this->base . 'stream/1')); + $response = \React\Async\await($this->browser->requestStreaming('GET', $this->base . 'stream/1')); $this->assertFalse($response->hasHeader('Content-Length')); $body = $response->getBody(); @@ -671,7 +688,7 @@ public function testRequestStreamingGetReceivesResponseWithStreamingBodyAndUnkno public function testRequestStreamingGetReceivesStreamingResponseBody() { - $buffer = Block\await( + $buffer = \React\Async\await( $this->browser->requestStreaming('GET', $this->base . 'get')->then(function (ResponseInterface $response) { return Stream\buffer($response->getBody()); }) @@ -682,7 +699,7 @@ public function testRequestStreamingGetReceivesStreamingResponseBody() public function testRequestStreamingGetReceivesStreamingResponseBodyEvenWhenResponseBufferExceeded() { - $buffer = Block\await( + $buffer = \React\Async\await( $this->browser->withResponseBuffer(4)->requestStreaming('GET', $this->base . 'get')->then(function (ResponseInterface $response) { return Stream\buffer($response->getBody()); }) diff --git a/tests/FunctionalHttpServerTest.php b/tests/FunctionalHttpServerTest.php index 6fa85903..eb3b448c 100644 --- a/tests/FunctionalHttpServerTest.php +++ b/tests/FunctionalHttpServerTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http; -use Clue\React\Block; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ServerRequestInterface; use React\EventLoop\Loop; @@ -37,7 +36,7 @@ public function testPlainHttpOnRandomPort() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('http://' . noScheme($socket->getAddress()) . '/', $response); @@ -64,7 +63,7 @@ function () { return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 404 Not Found", $response); @@ -88,7 +87,7 @@ public function testPlainHttpOnRandomPortWithoutHostHeaderUsesSocketUri() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('http://' . noScheme($socket->getAddress()) . '/', $response); @@ -113,7 +112,7 @@ public function testPlainHttpOnRandomPortWithOtherHostHeaderTakesPrecedence() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('http://localhost:1000/', $response); @@ -146,7 +145,7 @@ public function testSecureHttpsOnRandomPort() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('https://' . noScheme($socket->getAddress()) . '/', $response); @@ -183,7 +182,7 @@ public function testSecureHttpsReturnsData() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString("\r\nContent-Length: 33000\r\n", $response); @@ -217,7 +216,7 @@ public function testSecureHttpsOnRandomPortWithoutHostHeaderUsesSocketUri() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('https://' . noScheme($socket->getAddress()) . '/', $response); @@ -246,7 +245,7 @@ public function testPlainHttpOnStandardPortReturnsUriWithNoPort() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('http://127.0.0.1/', $response); @@ -275,7 +274,7 @@ public function testPlainHttpOnStandardPortWithoutHostHeaderReturnsUriWithNoPort return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('http://127.0.0.1/', $response); @@ -313,7 +312,7 @@ public function testSecureHttpsOnStandardPortReturnsUriWithNoPort() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('https://127.0.0.1/', $response); @@ -351,7 +350,7 @@ public function testSecureHttpsOnStandardPortWithoutHostHeaderUsesSocketUri() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('https://127.0.0.1/', $response); @@ -380,7 +379,7 @@ public function testPlainHttpOnHttpsStandardPortReturnsUriWithPort() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('http://127.0.0.1:443/', $response); @@ -418,7 +417,7 @@ public function testSecureHttpsOnHttpStandardPortReturnsUriWithPort() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertContainsString("HTTP/1.0 200 OK", $response); $this->assertContainsString('https://127.0.0.1:80/', $response); @@ -446,7 +445,7 @@ public function testClosedStreamFromRequestHandlerWillSendEmptyBody() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertStringStartsWith("HTTP/1.0 200 OK", $response); $this->assertStringEndsWith("\r\n\r\n", $response); @@ -477,7 +476,7 @@ function (RequestInterface $request) use ($once) { }); }); - Block\sleep(0.1); + \React\Async\await(\React\Promise\Timer\sleep(0.1)); $socket->close(); } @@ -507,7 +506,7 @@ function (RequestInterface $request) use ($stream) { }); // stream will be closed within 0.1s - $ret = Block\await(Stream\first($stream, 'close'), null, 0.1); + $ret = \React\Async\await(\React\Promise\Timer\timeout(Stream\first($stream, 'close'), 0.1)); $socket->close(); @@ -536,7 +535,7 @@ public function testStreamFromRequestHandlerWillBeClosedIfConnectionCloses() }); // await response stream to be closed - $ret = Block\await(Stream\first($stream, 'close'), null, 1.0); + $ret = \React\Async\await(\React\Promise\Timer\timeout(Stream\first($stream, 'close'), 1.0)); $socket->close(); @@ -571,7 +570,7 @@ public function testUpgradeWithThroughStreamReturnsDataAsGiven() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertStringStartsWith("HTTP/1.1 101 Switching Protocols\r\n", $response); $this->assertStringEndsWith("\r\n\r\nhelloworld", $response); @@ -608,7 +607,7 @@ public function testUpgradeWithRequestBodyAndThroughStreamReturnsDataAsGiven() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertStringStartsWith("HTTP/1.1 101 Switching Protocols\r\n", $response); $this->assertStringEndsWith("\r\n\r\nhelloworld", $response); @@ -644,7 +643,7 @@ public function testConnectWithThroughStreamReturnsDataAsGiven() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertStringStartsWith("HTTP/1.1 200 OK\r\n", $response); $this->assertStringEndsWith("\r\n\r\nhelloworld", $response); @@ -684,7 +683,7 @@ public function testConnectWithThroughStreamReturnedFromPromiseReturnsDataAsGive return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertStringStartsWith("HTTP/1.1 200 OK\r\n", $response); $this->assertStringEndsWith("\r\n\r\nhelloworld", $response); @@ -717,7 +716,7 @@ public function testConnectWithClosedThroughStreamReturnsNoData() return Stream\buffer($conn); }); - $response = Block\await($result, null, 1.0); + $response = \React\Async\await(\React\Promise\Timer\timeout($result, 1.0)); $this->assertStringStartsWith("HTTP/1.1 200 OK\r\n", $response); $this->assertStringEndsWith("\r\n\r\n", $response); @@ -760,7 +759,7 @@ function (ServerRequestInterface $request) { }); } - $responses = Block\await(Promise\all($result), null, 1.0); + $responses = \React\Async\await(\React\Promise\Timer\timeout(Promise\all($result), 1.0)); foreach ($responses as $response) { $this->assertContainsString("HTTP/1.0 200 OK", $response, $response); diff --git a/tests/HttpServerTest.php b/tests/HttpServerTest.php index 31bc32ee..72d48468 100644 --- a/tests/HttpServerTest.php +++ b/tests/HttpServerTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http; -use Clue\React\Block; use Psr\Http\Message\ServerRequestInterface; use React\EventLoop\Loop; use React\Http\HttpServer; @@ -142,7 +141,7 @@ public function testPostFormData() $this->socket->emit('connection', array($this->connection)); $this->connection->emit('data', array("POST / HTTP/1.0\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 7\r\n\r\nfoo=bar")); - $request = Block\await($deferred->promise()); + $request = \React\Async\await($deferred->promise()); assert($request instanceof ServerRequestInterface); $form = $request->getParsedBody(); @@ -180,7 +179,7 @@ public function testPostFileUpload() } }); - $request = Block\await($deferred->promise()); + $request = \React\Async\await($deferred->promise()); assert($request instanceof ServerRequestInterface); $this->assertEmpty($request->getParsedBody()); @@ -213,7 +212,7 @@ public function testPostJsonWillNotBeParsedByDefault() $this->socket->emit('connection', array($this->connection)); $this->connection->emit('data', array("POST / HTTP/1.0\r\nContent-Type: application/json\r\nContent-Length: 6\r\n\r\n[true]")); - $request = Block\await($deferred->promise()); + $request = \React\Async\await($deferred->promise()); assert($request instanceof ServerRequestInterface); $this->assertNull($request->getParsedBody()); diff --git a/tests/Io/MiddlewareRunnerTest.php b/tests/Io/MiddlewareRunnerTest.php index d8f5f232..1f49facd 100644 --- a/tests/Io/MiddlewareRunnerTest.php +++ b/tests/Io/MiddlewareRunnerTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http\Io; -use Clue\React\Block; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -161,7 +160,7 @@ public function testProcessStack(array $middlewares, $expectedCallCount) $response = $middlewareStack($request); $this->assertTrue($response instanceof PromiseInterface); - $response = Block\await($response); + $response = \React\Async\await($response); $this->assertTrue($response instanceof ResponseInterface); $this->assertSame(200, $response->getStatusCode()); @@ -228,7 +227,7 @@ function () use ($errorHandler, &$called, $response, $exception) { $request = new ServerRequest('GET', 'https://example.com/'); - $this->assertSame($response, Block\await($runner($request))); + $this->assertSame($response, \React\Async\await($runner($request))); $this->assertSame(1, $retryCalled); $this->assertSame(2, $called); $this->assertSame($exception, $error); diff --git a/tests/Io/SenderTest.php b/tests/Io/SenderTest.php index 1c6d1d6b..587ba0c2 100644 --- a/tests/Io/SenderTest.php +++ b/tests/Io/SenderTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http\Io; -use Clue\React\Block; use React\Http\Client\Client as HttpClient; use React\Http\Client\RequestData; use React\Http\Io\ReadableBodyStream; @@ -42,8 +41,12 @@ public function testSenderRejectsInvalidUri() $promise = $sender->send($request); - $this->setExpectedException('InvalidArgumentException'); - Block\await($promise, $this->loop); + $exception = null; + $promise->then(null, function ($e) use (&$exception) { + $exception = $e; + }); + + $this->assertInstanceOf('InvalidArgumentException', $exception); } public function testSenderConnectorRejection() @@ -57,8 +60,12 @@ public function testSenderConnectorRejection() $promise = $sender->send($request); - $this->setExpectedException('RuntimeException'); - Block\await($promise, $this->loop); + $exception = null; + $promise->then(null, function ($e) use (&$exception) { + $exception = $e; + }); + + $this->assertInstanceOf('RuntimeException', $exception); } public function testSendPostWillAutomaticallySendContentLengthHeader() @@ -318,8 +325,12 @@ public function testCancelRequestWillCancelConnector() $promise = $sender->send($request); $promise->cancel(); - $this->setExpectedException('RuntimeException'); - Block\await($promise, $this->loop); + $exception = null; + $promise->then(null, function ($e) use (&$exception) { + $exception = $e; + }); + + $this->assertInstanceOf('RuntimeException', $exception); } public function testCancelRequestWillCloseConnection() @@ -337,8 +348,12 @@ public function testCancelRequestWillCloseConnection() $promise = $sender->send($request); $promise->cancel(); - $this->setExpectedException('RuntimeException'); - Block\await($promise, $this->loop); + $exception = null; + $promise->then(null, function ($e) use (&$exception) { + $exception = $e; + }); + + $this->assertInstanceOf('RuntimeException', $exception); } public function provideRequestProtocolVersion() diff --git a/tests/Io/TransactionTest.php b/tests/Io/TransactionTest.php index d62147b5..83d218c7 100644 --- a/tests/Io/TransactionTest.php +++ b/tests/Io/TransactionTest.php @@ -2,10 +2,10 @@ namespace React\Tests\Http\Io; -use Clue\React\Block; use PHPUnit\Framework\MockObject\MockObject; use Psr\Http\Message\RequestInterface; -use RingCentral\Psr7\Response; +use Psr\Http\Message\ResponseInterface; +use React\Http\Io\ReadableBodyStream; use React\Http\Io\Transaction; use React\Http\Message\ResponseException; use React\EventLoop\Loop; @@ -14,7 +14,7 @@ use React\Stream\ThroughStream; use React\Tests\Http\TestCase; use RingCentral\Psr7\Request; -use React\Http\Io\ReadableBodyStream; +use RingCentral\Psr7\Response; class TransactionTest extends TestCase { @@ -372,13 +372,14 @@ public function testReceivingErrorResponseWillRejectWithResponseException() $transaction = $transaction->withOptions(array('timeout' => -1)); $promise = $transaction->send($request); - try { - Block\await($promise, $loop); - $this->fail(); - } catch (ResponseException $exception) { - $this->assertEquals(404, $exception->getCode()); - $this->assertSame($response, $exception->getResponse()); - } + $exception = null; + $promise->then(null, function ($reason) use (&$exception) { + $exception = $reason; + }); + + assert($exception instanceof ResponseException); + $this->assertEquals(404, $exception->getCode()); + $this->assertSame($response, $exception->getResponse()); } public function testReceivingStreamingBodyWillResolveWithBufferedResponseByDefault() @@ -399,7 +400,7 @@ public function testReceivingStreamingBodyWillResolveWithBufferedResponseByDefau $transaction = new Transaction($sender, Loop::get()); $promise = $transaction->send($request); - $response = Block\await($promise); + $response = \React\Async\await($promise); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('hello world', (string)$response->getBody()); @@ -422,7 +423,7 @@ public function testReceivingStreamingBodyWithSizeExceedingMaximumResponseBuffer $promise = $transaction->send($request); $this->setExpectedException('OverflowException'); - Block\await($promise, null, 0.001); + \React\Async\await(\React\Promise\Timer\timeout($promise, 0.001)); } public function testCancelBufferingResponseWillCloseStreamAndReject() @@ -443,7 +444,7 @@ public function testCancelBufferingResponseWillCloseStreamAndReject() $promise->cancel(); $this->setExpectedException('RuntimeException'); - Block\await($promise, null, 0.001); + \React\Async\await(\React\Promise\Timer\timeout($promise, 0.001)); } public function testReceivingStreamingBodyWillResolveWithStreamingResponseIfStreamingIsEnabled() @@ -461,8 +462,12 @@ public function testReceivingStreamingBodyWillResolveWithStreamingResponseIfStre $transaction = $transaction->withOptions(array('streaming' => true, 'timeout' => -1)); $promise = $transaction->send($request); - $response = Block\await($promise, $loop); + $response = null; + $promise->then(function ($value) use (&$response) { + $response = $value; + }); + assert($response instanceof ResponseInterface); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('', (string)$response->getBody()); } diff --git a/tests/Middleware/RequestBodyBufferMiddlewareTest.php b/tests/Middleware/RequestBodyBufferMiddlewareTest.php index e073e1f0..0edec7da 100644 --- a/tests/Middleware/RequestBodyBufferMiddlewareTest.php +++ b/tests/Middleware/RequestBodyBufferMiddlewareTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Http\Middleware; -use Clue\React\Block; use Psr\Http\Message\ServerRequestInterface; use React\EventLoop\Loop; use React\Http\Io\HttpBodyStream; @@ -128,7 +127,7 @@ public function testKnownExcessiveSizedBodyIsDisgardedTheRequestIsPassedDownToTh ); $buffer = new RequestBodyBufferMiddleware(1); - $response = Block\await($buffer( + $response = \React\Async\await($buffer( $serverRequest, function (ServerRequestInterface $request) { return new Response(200, array(), $request->getBody()->getContents()); @@ -153,7 +152,7 @@ public function testKnownExcessiveSizedWithIniLikeSize() ); $buffer = new RequestBodyBufferMiddleware('1K'); - $response = Block\await($buffer( + $response = \React\Async\await($buffer( $serverRequest, function (ServerRequestInterface $request) { return new Response(200, array(), $request->getBody()->getContents()); @@ -206,7 +205,7 @@ function (ServerRequestInterface $request) { $stream->end('aa'); - $exposedResponse = Block\await($promise->then( + $exposedResponse = \React\Async\await($promise->then( null, $this->expectCallableNever() )); @@ -236,7 +235,7 @@ function (ServerRequestInterface $request) { $stream->emit('error', array(new \RuntimeException())); $this->setExpectedException('RuntimeException'); - Block\await($promise); + \React\Async\await($promise); } public function testFullBodyStreamedBeforeCallingNextMiddleware()