From 3d269081df9ff82ae37c87928814c8f8c2f5d0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 7 Apr 2018 15:47:12 +0200 Subject: [PATCH 01/11] Support legacy HTTP servers that use only LF instead of CRLF --- src/Request.php | 3 ++- tests/FunctionalIntegrationTest.php | 23 +++++++++++++++++++++++ tests/TestCase.php | 11 +++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Request.php b/src/Request.php index ea4d50b..caa242b 100644 --- a/src/Request.php +++ b/src/Request.php @@ -134,7 +134,8 @@ public function handleData($data) { $this->buffer .= $data; - if (false !== strpos($this->buffer, "\r\n\r\n")) { + // buffer until double CRLF (or double LF for compatibility with legacy servers) + if (false !== strpos($this->buffer, "\r\n\r\n") || false !== strpos($this->buffer, "\n\n")) { try { list($response, $bodyChunk) = $this->parseResponse($this->buffer); } catch (\InvalidArgumentException $exception) { diff --git a/tests/FunctionalIntegrationTest.php b/tests/FunctionalIntegrationTest.php index 1ed2228..1deebc7 100644 --- a/tests/FunctionalIntegrationTest.php +++ b/tests/FunctionalIntegrationTest.php @@ -29,6 +29,29 @@ public function testRequestToLocalhostEmitsSingleRemoteConnection() $loop->run(); } + public function testRequestLegacyHttpServerWithOnlyLineFeedReturnsSuccessfulResponse() + { + $loop = Factory::create(); + + $server = new Server(0, $loop); + $server->on('connection', function (ConnectionInterface $conn) use ($server) { + $conn->end("HTTP/1.0 200 OK\n\nbody"); + $server->close(); + }); + + $client = new Client($loop); + $request = $client->request('GET', str_replace('tcp:', 'http:', $server->getAddress())); + + $once = $this->expectCallableOnceWith('body'); + $request->on('response', function (Response $response) use ($once) { + $response->on('data', $once); + }); + + $request->end(); + + $loop->run(); + } + /** @group internet */ public function testSuccessfulResponseEmitsEnd() { diff --git a/tests/TestCase.php b/tests/TestCase.php index 9e090bc..901f82f 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -26,6 +26,17 @@ protected function expectCallableOnce() return $mock; } + protected function expectCallableOnceWith($value) + { + $mock = $this->createCallableMock(); + $mock + ->expects($this->once()) + ->method('__invoke') + ->with($value); + + return $mock; + } + protected function expectCallableNever() { $mock = $this->createCallableMock(); From 7293f8d445c2bbe21a73c757b04e6cf6efd9d785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 7 Apr 2018 17:31:26 +0200 Subject: [PATCH 02/11] Apply maximum test timeouts for integration tests --- composer.json | 4 ++- tests/FunctionalIntegrationTest.php | 55 ++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index ecb19e5..4cd9d7f 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,9 @@ "ringcentral/psr7": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" + "clue/block-react": "^1.2", + "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35", + "react/promise-stream": "^1.1" }, "autoload": { "psr-4": { diff --git a/tests/FunctionalIntegrationTest.php b/tests/FunctionalIntegrationTest.php index 1deebc7..cc8d880 100644 --- a/tests/FunctionalIntegrationTest.php +++ b/tests/FunctionalIntegrationTest.php @@ -2,14 +2,37 @@ namespace React\Tests\HttpClient; +use Clue\React\Block; use React\EventLoop\Factory; use React\HttpClient\Client; use React\HttpClient\Response; +use React\Promise\Deferred; +use React\Promise\Stream; use React\Socket\Server; use React\Socket\ConnectionInterface; class FunctionalIntegrationTest extends TestCase { + /** + * Test timeout to use for local tests. + * + * In practice this would be near 0.001s, but let's leave some time in case + * the local system is currently busy. + * + * @var float + */ + const TIMEOUT_LOCAL = 1.0; + + /** + * Test timeout to use for remote (internet) tests. + * + * In pratice this should be below 1s, but this relies on infrastructure + * outside our control, so consider this a maximum to avoid running for hours. + * + * @var float + */ + const TIMEOUT_REMOTE = 10.0; + public function testRequestToLocalhostEmitsSingleRemoteConnection() { $loop = Factory::create(); @@ -24,9 +47,11 @@ public function testRequestToLocalhostEmitsSingleRemoteConnection() $client = new Client($loop); $request = $client->request('GET', 'http://localhost:' . $port); + + $promise = Stream\first($request, 'close'); $request->end(); - $loop->run(); + Block\await($promise, $loop, self::TIMEOUT_LOCAL); } public function testRequestLegacyHttpServerWithOnlyLineFeedReturnsSuccessfulResponse() @@ -47,9 +72,10 @@ public function testRequestLegacyHttpServerWithOnlyLineFeedReturnsSuccessfulResp $response->on('data', $once); }); + $promise = Stream\first($request, 'close'); $request->end(); - $loop->run(); + Block\await($promise, $loop, self::TIMEOUT_LOCAL); } /** @group internet */ @@ -65,9 +91,10 @@ public function testSuccessfulResponseEmitsEnd() $response->on('end', $once); }); + $promise = Stream\first($request, 'close'); $request->end(); - $loop->run(); + Block\await($promise, $loop, self::TIMEOUT_REMOTE); } /** @group internet */ @@ -79,11 +106,9 @@ public function testPostDataReturnsData() $data = str_repeat('.', 33000); $request = $client->request('POST', 'https://' . (mt_rand(0, 1) === 0 ? 'eu.' : '') . 'httpbin.org/post', array('Content-Length' => strlen($data))); - $buffer = ''; - $request->on('response', function (Response $response) use (&$buffer) { - $response->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); + $deferred = new Deferred(); + $request->on('response', function (Response $response) use ($deferred) { + $deferred->resolve(Stream\buffer($response)); }); $request->on('error', 'printf'); @@ -91,7 +116,7 @@ public function testPostDataReturnsData() $request->end($data); - $loop->run(); + $buffer = Block\await($deferred->promise(), $loop, self::TIMEOUT_REMOTE); $this->assertNotEquals('', $buffer); @@ -110,11 +135,9 @@ public function testPostJsonReturnsData() $data = json_encode(array('numbers' => range(1, 50))); $request = $client->request('POST', 'https://httpbin.org/post', array('Content-Length' => strlen($data), 'Content-Type' => 'application/json')); - $buffer = ''; - $request->on('response', function (Response $response) use (&$buffer) { - $response->on('data', function ($chunk) use (&$buffer) { - $buffer .= $chunk; - }); + $deferred = new Deferred(); + $request->on('response', function (Response $response) use ($deferred) { + $deferred->resolve(Stream\buffer($response)); }); $request->on('error', 'printf'); @@ -122,7 +145,7 @@ public function testPostJsonReturnsData() $request->end($data); - $loop->run(); + $buffer = Block\await($deferred->promise(), $loop, self::TIMEOUT_REMOTE); $this->assertNotEquals('', $buffer); @@ -142,7 +165,5 @@ public function testCancelPendingConnectionEmitsClose() $request->on('close', $this->expectCallableOnce()); $request->end(); $request->close(); - - $loop->run(); } } From f8e81a022b61938e0b37c94c6351fc170b7d87f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 10 Apr 2018 13:38:54 +0200 Subject: [PATCH 03/11] Prepare v0.5.9 release --- CHANGELOG.md | 8 ++++++++ README.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a923861..d97d680 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.5.9 (2018-04-10) + +* Feature: Support legacy HTTP servers that use only `LF` instead of `CRLF`. + (#130 by @clue) + +* Improve test suite by applying maximum test timeouts for integration tests. + (#131 by @clue) + ## 0.5.8 (2018-02-09) * Support legacy PHP 5.3 through PHP 7.2 and HHVM diff --git a/README.md b/README.md index 6ae1f97..a8926c0 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ The recommended way to install this library is [through Composer](https://getcom This will install the latest supported version: ```bash -$ composer require react/http-client:^0.5.8 +$ composer require react/http-client:^0.5.9 ``` See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. From ef902e384c74af3513e049a991ebcad6a5d055ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sun, 27 Jan 2019 17:24:20 +0100 Subject: [PATCH 04/11] Link to clue/reactphp-buzz for higher-level HTTP client --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index a8926c0..eb45105 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ Event-driven, streaming HTTP client for [ReactPHP](https://reactphp.org). +> Note that this is a very low-level HTTP client implementation that is currently + undergoing some major changes. In the meantime, we recommend using + [clue/reactphp-buzz](https://github.com/clue/reactphp-buzz) as a higher-level + HTTP client abstraction (which happens to build on top of this project). It + provides a Promise-based interface and common PSR-7 message abstraction which + makes getting started much easier. + **Table of Contents** * [Basic usage](#basic-usage) From 6826c75ad85245172fc2d1e91573baf297436248 Mon Sep 17 00:00:00 2001 From: Sam Reed Date: Sun, 1 Dec 2019 01:59:57 +0000 Subject: [PATCH 05/11] Add .gitattributes to exclude dev files from exports --- .gitattributes | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f2f51dd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/examples export-ignore +/phpunit.xml.dist export-ignore +/tests export-ignore From c24f511245d019929aba02294acc8e263fdf05de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 11 Jan 2020 18:11:46 +0100 Subject: [PATCH 06/11] Avoid unneeded warning when decoding invalid data on PHP 7.4 --- .travis.yml | 2 ++ composer.json | 2 +- phpunit.xml.dist | 1 - src/ChunkedStreamDecoder.php | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 46a0486..2715358 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,8 @@ php: - 7.0 - 7.1 - 7.2 + - 7.3 + - 7.4 - nightly # ignore errors, see below - hhvm # ignore errors, see below diff --git a/composer.json b/composer.json index 4cd9d7f..673e61c 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ }, "require-dev": { "clue/block-react": "^1.2", - "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35", + "phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35", "react/promise-stream": "^1.1" }, "autoload": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cba6d4d..79c0ee6 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,7 +8,6 @@ convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" - syntaxCheck="false" bootstrap="tests/bootstrap.php" > diff --git a/src/ChunkedStreamDecoder.php b/src/ChunkedStreamDecoder.php index a96592e..fc76d52 100644 --- a/src/ChunkedStreamDecoder.php +++ b/src/ChunkedStreamDecoder.php @@ -111,7 +111,7 @@ protected function iterateBuffer() } } $this->nextChunkIsLength = false; - if (dechex(hexdec($lengthChunk)) !== strtolower($lengthChunk)) { + if (dechex(@hexdec($lengthChunk)) !== strtolower($lengthChunk)) { $this->emit('error', array( new Exception('Unable to validate "' . $lengthChunk . '" as chunk length header'), )); From 83bcf79c957cb72d96e5fb17cd38814f64155eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 10 Jan 2020 17:39:44 +0100 Subject: [PATCH 07/11] Simplify test matrix and test setup --- .travis.yml | 27 +++++++++++++-------------- composer.json | 5 +++++ phpunit.xml.dist | 2 +- tests/bootstrap.php | 7 ------- 4 files changed, 19 insertions(+), 22 deletions(-) delete mode 100644 tests/bootstrap.php diff --git a/.travis.yml b/.travis.yml index 2715358..364429b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,5 @@ language: php -php: -# - 5.3 # requires old distro - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 - - 7.4 - - nightly # ignore errors, see below - - hhvm # ignore errors, see below - # lock distro so new future defaults will not break the build dist: trusty @@ -20,9 +7,21 @@ matrix: include: - php: 5.3 dist: precise + - php: 5.4 + - php: 5.5 + - php: 5.6 + - php: 7.0 + - php: 7.1 + - php: 7.2 + - php: 7.3 + - php: 7.4 + - php: nightly + - php: hhvm-3.18 + install: + - composer require phpunit/phpunit:^5 --dev --no-interaction # requires legacy phpunit allow_failures: - php: nightly - - php: hhvm + - php: hhvm-3.18 install: - composer install --no-interaction diff --git a/composer.json b/composer.json index 673e61c..9207639 100644 --- a/composer.json +++ b/composer.json @@ -21,5 +21,10 @@ "psr-4": { "React\\HttpClient\\": "src" } + }, + "autoload-dev": { + "psr-4": { + "React\\Tests\\HttpClient\\": "tests" + } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 79c0ee6..04d426b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,7 +8,7 @@ convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" - bootstrap="tests/bootstrap.php" + bootstrap="vendor/autoload.php" > diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index e3bed44..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,7 +0,0 @@ -addPsr4('React\\Tests\\HttpClient\\', __DIR__); From f16ab55150ec369f8f9b5db64972f248691093b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Tue, 14 Jan 2020 09:36:16 +0100 Subject: [PATCH 08/11] Prepare v0.5.10 release --- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d97d680..53eb29b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.5.10 (2020-01-14) + +* Fix: Avoid unneeded warning when decoding invalid data on PHP 7.4. + (#150 by @clue) + +* Add `.gitattributes` to exclude dev files from exports. + (#149 by @reedy) + +* Link to clue/reactphp-buzz for higher-level HTTP client. + (#139 by @clue) + +* Improve test suite by simplifying test matrix and test setup. + (#151 by @clue) + ## 0.5.9 (2018-04-10) * Feature: Support legacy HTTP servers that use only `LF` instead of `CRLF`. diff --git a/README.md b/README.md index eb45105..70a7c53 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ The recommended way to install this library is [through Composer](https://getcom This will install the latest supported version: ```bash -$ composer require react/http-client:^0.5.9 +$ composer require react/http-client:^0.5.10 ``` See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. From fc3e5d01688655c2ae73b5650ca567736c62ffac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sun, 6 Sep 2020 12:05:11 +0200 Subject: [PATCH 09/11] Add deprecation notice to suggest HTTP component instead --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 70a7c53..9ce6381 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,48 @@ -# HttpClient +# Deprecation notice + +This package has now been migrated over to +[react/http](https://github.com/reactphp/http) +and only exists for BC reasons. + +```bash +$ composer require react/http +``` + +If you've previously used this package, upgrading may take a moment or two. +The new API has been updated to use Promises and PSR-7 message abstractions. +This means it's now more powerful and easier to use than ever: + +```php +// old +$client = new React\HttpClient\Client($loop); +$request = $client->request('GET', 'https://example.com/'); +$request->on('response', function ($response) { + $response->on('data', function ($chunk) { + echo $chunk; + }); +}); +$request->end(); + +// new +$browser = new React\Http\Browser($loop); +$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) { + echo $response->getBody(); +}); +``` + +See [react/http](https://github.com/reactphp/http#client-usage) for more details. + +The below documentation applies to the last release of this package. +Further development will take place in the updated +[react/http](https://github.com/reactphp/http), +so you're highly recommended to upgrade as soon as possible. + +# Deprecated HttpClient [![Build Status](https://travis-ci.org/reactphp/http-client.svg?branch=master)](https://travis-ci.org/reactphp/http-client) Event-driven, streaming HTTP client for [ReactPHP](https://reactphp.org). -> Note that this is a very low-level HTTP client implementation that is currently - undergoing some major changes. In the meantime, we recommend using - [clue/reactphp-buzz](https://github.com/clue/reactphp-buzz) as a higher-level - HTTP client abstraction (which happens to build on top of this project). It - provides a Promise-based interface and common PSR-7 message abstraction which - makes getting started much easier. - **Table of Contents** * [Basic usage](#basic-usage) From 7c2ccd0ddb4e7daa106acb6bbd163a3c073201b9 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 7 Apr 2021 16:28:13 +0200 Subject: [PATCH 10/11] Minimal fix for PHP 8 --- src/ChunkedStreamDecoder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkedStreamDecoder.php b/src/ChunkedStreamDecoder.php index fc76d52..bc150ad 100644 --- a/src/ChunkedStreamDecoder.php +++ b/src/ChunkedStreamDecoder.php @@ -111,7 +111,7 @@ protected function iterateBuffer() } } $this->nextChunkIsLength = false; - if (dechex(@hexdec($lengthChunk)) !== strtolower($lengthChunk)) { + if (dechex((int)@hexdec($lengthChunk)) !== strtolower($lengthChunk)) { $this->emit('error', array( new Exception('Unable to validate "' . $lengthChunk . '" as chunk length header'), )); From 23dddb415b9bd36c81d1c78df63143e65702aa4b Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Wed, 7 Apr 2021 18:49:17 +0200 Subject: [PATCH 11/11] Prepare v0.5.11 release --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53eb29b..5a71f99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.5.11 (2021-04-07) + +* Fix: Minimal fix for PHP 8 + (#154 by @remicollet) + +* Documentation: Add deprecation notice to suggest HTTP component instead + (#153 by @clue) + ## 0.5.10 (2020-01-14) * Fix: Avoid unneeded warning when decoding invalid data on PHP 7.4. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy