Skip to content

Commit d15b8df

Browse files
committed
Update to require PHP 7.1+
1 parent a2b4fe1 commit d15b8df

24 files changed

+55
-256
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,13 @@ jobs:
2222
- 7.3
2323
- 7.2
2424
- 7.1
25-
- 7.0
26-
- 5.6
27-
- 5.5
28-
- 5.4
29-
- 5.3
3025
steps:
3126
- uses: actions/checkout@v4
3227
- uses: shivammathur/setup-php@v2
3328
with:
3429
php-version: ${{ matrix.php }}
3530
coverage: xdebug
3631
ini-file: development
37-
- run: composer config secure-http false && composer config repo.packagist composer http://packagist.org && composer config preferred-install source
38-
if: ${{ matrix.php < 5.5 && matrix.os == 'windows-2022' }} # legacy PHP on Windows is allowed to use insecure downloads until it will be removed again
3932
- run: composer install
4033
- run: vendor/bin/phpunit --coverage-text
4134
if: ${{ matrix.php >= 7.3 }}
@@ -54,19 +47,3 @@ jobs:
5447
coverage: xdebug
5548
- run: composer install
5649
- run: vendor/bin/phpunit --coverage-text
57-
58-
PHPUnit-hhvm:
59-
name: PHPUnit (HHVM)
60-
runs-on: ubuntu-22.04
61-
continue-on-error: true
62-
steps:
63-
- uses: actions/checkout@v4
64-
- run: cp "$(which composer)" composer.phar && ./composer.phar self-update --2.2 # downgrade Composer for HHVM
65-
- name: Run hhvm composer.phar install
66-
uses: docker://hhvm/hhvm:3.30-lts-latest
67-
with:
68-
args: hhvm composer.phar install
69-
- name: Run hhvm vendor/bin/phpunit
70-
uses: docker://hhvm/hhvm:3.30-lts-latest
71-
with:
72-
args: hhvm vendor/bin/phpunit

README.md

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ $socket = new React\Socket\SocketServer('tls://127.0.0.1:8000', array(
472472
```
473473

474474
By default, this server supports TLSv1.0+ and excludes support for legacy
475-
SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
475+
SSLv2/SSLv3. You can also explicitly choose the TLS version you
476476
want to negotiate with the remote side:
477477

478478
```php
@@ -650,7 +650,7 @@ $server = new React\Socket\SecureServer($server, null, array(
650650
```
651651

652652
By default, this server supports TLSv1.0+ and excludes support for legacy
653-
SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
653+
SSLv2/SSLv3. You can also explicitly choose the TLS version you
654654
want to negotiate with the remote side:
655655

656656
```php
@@ -1087,7 +1087,7 @@ $connector->connect('tls://localhost:443')->then(function (React\Socket\Connecti
10871087
```
10881088

10891089
By default, this connector supports TLSv1.0+ and excludes support for legacy
1090-
SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
1090+
SSLv2/SSLv3. You can also explicitly choose the TLS version you
10911091
want to negotiate with the remote side:
10921092

10931093
```php
@@ -1370,7 +1370,7 @@ $secureConnector = new React\Socket\SecureConnector($dnsConnector, null, array(
13701370
```
13711371

13721372
By default, this connector supports TLSv1.0+ and excludes support for legacy
1373-
SSLv2/SSLv3. As of PHP 5.6+ you can also explicitly choose the TLS version you
1373+
SSLv2/SSLv3. You can also explicitly choose the TLS version you
13741374
want to negotiate with the remote side:
13751375

13761376
```php
@@ -1490,19 +1490,10 @@ composer require react/socket:^3@dev
14901490
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
14911491

14921492
This project aims to run on any platform and thus does not require any PHP
1493-
extensions and supports running on legacy PHP 5.3 through current PHP 8+ and HHVM.
1494-
It's *highly recommended to use the latest supported PHP version* for this project,
1495-
partly due to its vast performance improvements and partly because legacy PHP
1496-
versions require several workarounds as described below.
1497-
1498-
Secure TLS connections received some major upgrades starting with PHP 5.6, with
1499-
the defaults now being more secure, while older versions required explicit
1500-
context options.
1501-
This library does not take responsibility over these context options, so it's
1502-
up to consumers of this library to take care of setting appropriate context
1503-
options as described above.
1504-
1505-
PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() might
1493+
extensions and supports running on PHP 7.1 through current PHP 8+.
1494+
It's *highly recommended to use the latest supported PHP version* for this project.
1495+
1496+
Legacy PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() might
15061497
block with 100% CPU usage on fragmented TLS records.
15071498
We try to work around this by always consuming the complete receive
15081499
buffer at once to avoid stale data in TLS buffers. This is known to
@@ -1511,21 +1502,13 @@ cause very large data chunks for high throughput scenarios. The buggy
15111502
behavior can still be triggered due to network I/O buffers or
15121503
malicious peers on affected versions, upgrading is highly recommended.
15131504

1514-
PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big
1505+
Legacy PHP < 7.1.4 suffers from a bug when writing big
15151506
chunks of data over TLS streams at once.
15161507
We try to work around this by limiting the write chunk size to 8192
15171508
bytes for older PHP versions only.
15181509
This is only a work-around and has a noticable performance penalty on
15191510
affected versions.
15201511

1521-
This project also supports running on HHVM.
1522-
Note that really old HHVM < 3.8 does not support secure TLS connections, as it
1523-
lacks the required `stream_socket_enable_crypto()` function.
1524-
As such, trying to create a secure TLS connections on affected versions will
1525-
return a rejected promise instead.
1526-
This issue is also covered by our test suite, which will skip related tests
1527-
on affected versions.
1528-
15291512
## Tests
15301513

15311514
To run the test suite, you first need to clone this repo and then install all

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@
2626
}
2727
],
2828
"require": {
29-
"php": ">=5.3.0",
29+
"php": ">=7.1",
3030
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
3131
"react/dns": "^1.11",
3232
"react/event-loop": "^1.2",
3333
"react/promise": "^3 || ^2.6 || ^1.2.1",
3434
"react/stream": "^1.2"
3535
},
3636
"require-dev": {
37-
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
38-
"react/async": "^4 || ^3 || ^2",
37+
"phpunit/phpunit": "^9.6 || ^5.7",
38+
"react/async": "^4 || ^3",
3939
"react/promise-stream": "^1.4",
4040
"react/promise-timer": "^1.10"
4141
},

phpunit.xml.legacy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<!-- PHPUnit configuration file with old format for legacy PHPUnit -->
44
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/4.8/phpunit.xsd"
5+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.7/phpunit.xsd"
66
bootstrap="vendor/autoload.php"
77
colors="true">
88
<testsuites>

src/Connection.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ class Connection extends EventEmitter implements ConnectionInterface
4343

4444
public function __construct($resource, LoopInterface $loop)
4545
{
46-
// PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof() might
47-
// block with 100% CPU usage on fragmented TLS records.
46+
// Legacy PHP < 7.3.3 (and PHP < 7.2.15) suffers from a bug where feof()
47+
// might block with 100% CPU usage on fragmented TLS records.
4848
// We try to work around this by always consuming the complete receive
4949
// buffer at once to avoid stale data in TLS buffers. This is known to
5050
// work around high CPU usage for well-behaving peers, but this may
@@ -54,15 +54,15 @@ public function __construct($resource, LoopInterface $loop)
5454
// @link https://bugs.php.net/bug.php?id=77390
5555
$clearCompleteBuffer = \PHP_VERSION_ID < 70215 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70303);
5656

57-
// PHP < 7.1.4 (and PHP < 7.0.18) suffers from a bug when writing big
57+
// Legacy PHP < 7.1.4 suffers from a bug when writing big
5858
// chunks of data over TLS streams at once.
5959
// We try to work around this by limiting the write chunk size to 8192
6060
// bytes for older PHP versions only.
6161
// This is only a work-around and has a noticable performance penalty on
6262
// affected versions. Please update your PHP version.
6363
// This applies to all streams because TLS may be enabled later on.
6464
// See https://github.com/reactphp/socket/issues/105
65-
$limitWriteChunks = (\PHP_VERSION_ID < 70018 || (\PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70104));
65+
$limitWriteChunks = \PHP_VERSION_ID < 70104;
6666

6767
$this->input = new DuplexResourceStream(
6868
$resource,
@@ -157,22 +157,17 @@ private function parseAddress($address)
157157
}
158158

159159
if ($this->unix) {
160-
// remove trailing colon from address for HHVM < 3.19: https://3v4l.org/5C1lo
161-
// note that technically ":" is a valid address, so keep this in place otherwise
162-
if (\substr($address, -1) === ':' && \defined('HHVM_VERSION_ID') && \HHVM_VERSION_ID < 31900) {
163-
$address = (string)\substr($address, 0, -1); // @codeCoverageIgnore
164-
}
165-
166-
// work around unknown addresses should return null value: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556
167-
// PHP uses "\0" string and HHVM uses empty string (colon removed above)
168-
if ($address === '' || $address[0] === "\x00" ) {
160+
// Legacy PHP < 7.1.7 may use "\0" string instead of false: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556
161+
// Work around by returning null for "\0" string
162+
if ($address[0] === "\x00" ) {
169163
return null; // @codeCoverageIgnore
170164
}
171165

172166
return 'unix://' . $address;
173167
}
174168

175-
// check if this is an IPv6 address which includes multiple colons but no square brackets
169+
// Legacy PHP < 7.3 uses IPv6 address which includes multiple colons but no square brackets: https://bugs.php.net/bug.php?id=76136
170+
// Work around by adding square brackets around IPv6 address when not already present
176171
$pos = \strrpos($address, ':');
177172
if ($pos !== false && \strpos($address, ':') < $pos && \substr($address, 0, 1) !== '[') {
178173
$address = '[' . \substr($address, 0, $pos) . ']:' . \substr($address, $pos + 1); // @codeCoverageIgnore

src/SecureConnector.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
use React\EventLoop\Loop;
66
use React\EventLoop\LoopInterface;
77
use React\Promise;
8-
use BadMethodCallException;
9-
use InvalidArgumentException;
10-
use UnexpectedValueException;
118

129
final class SecureConnector implements ConnectorInterface
1310
{
@@ -24,10 +21,6 @@ public function __construct(ConnectorInterface $connector, LoopInterface $loop =
2421

2522
public function connect($uri)
2623
{
27-
if (!\function_exists('stream_socket_enable_crypto')) {
28-
return Promise\reject(new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)')); // @codeCoverageIgnore
29-
}
30-
3124
if (\strpos($uri, '://') === false) {
3225
$uri = 'tls://' . $uri;
3326
}

src/SecureServer.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
use Evenement\EventEmitter;
66
use React\EventLoop\Loop;
77
use React\EventLoop\LoopInterface;
8-
use BadMethodCallException;
9-
use UnexpectedValueException;
108

119
/**
1210
* The `SecureServer` class implements the `ServerInterface` and is responsible
@@ -118,16 +116,11 @@ final class SecureServer extends EventEmitter implements ServerInterface
118116
* @param ServerInterface|TcpServer $tcp
119117
* @param ?LoopInterface $loop
120118
* @param array $context
121-
* @throws BadMethodCallException for legacy HHVM < 3.8 due to lack of support
122119
* @see TcpServer
123120
* @link https://www.php.net/manual/en/context.ssl.php for TLS context options
124121
*/
125122
public function __construct(ServerInterface $tcp, LoopInterface $loop = null, array $context = array())
126123
{
127-
if (!\function_exists('stream_socket_enable_crypto')) {
128-
throw new \BadMethodCallException('Encryption not supported on your platform (HHVM < 3.8?)'); // @codeCoverageIgnore
129-
}
130-
131124
// default to empty passphrase to suppress blocking passphrase prompt
132125
$context += array(
133126
'passphrase' => ''

src/StreamEncryption.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,18 @@ public function __construct(LoopInterface $loop, $server = true)
2626

2727
// support TLSv1.0+ by default and exclude legacy SSLv2/SSLv3.
2828
// As of PHP 7.2+ the main crypto method constant includes all TLS versions.
29-
// As of PHP 5.6+ the crypto method is a bitmask, so we explicitly include all TLS versions.
30-
// For legacy PHP < 5.6 the crypto method is a single value only and this constant includes all TLS versions.
29+
// In prior PHP versions, the crypto method is a bitmask, so we explicitly include all TLS versions.
3130
// @link https://3v4l.org/9PSST
3231
if ($server) {
3332
$this->method = \STREAM_CRYPTO_METHOD_TLS_SERVER;
3433

35-
if (\PHP_VERSION_ID < 70200 && \PHP_VERSION_ID >= 50600) {
34+
if (\PHP_VERSION_ID < 70200) {
3635
$this->method |= \STREAM_CRYPTO_METHOD_TLSv1_0_SERVER | \STREAM_CRYPTO_METHOD_TLSv1_1_SERVER | \STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; // @codeCoverageIgnore
3736
}
3837
} else {
3938
$this->method = \STREAM_CRYPTO_METHOD_TLS_CLIENT;
4039

41-
if (\PHP_VERSION_ID < 70200 && \PHP_VERSION_ID >= 50600) {
40+
if (\PHP_VERSION_ID < 70200) {
4241
$this->method |= \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; // @codeCoverageIgnore
4342
}
4443
}

src/TcpConnector.php

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,9 @@ public function connect($uri)
6262
'SNI_enabled' => true,
6363
'peer_name' => $args['hostname']
6464
);
65-
66-
// Legacy PHP < 5.6 ignores peer_name and requires legacy context options instead.
67-
// The SNI_server_name context option has to be set here during construction,
68-
// as legacy PHP ignores any values set later.
69-
// @codeCoverageIgnoreStart
70-
if (\PHP_VERSION_ID < 50600) {
71-
$context['ssl'] += array(
72-
'SNI_server_name' => $args['hostname'],
73-
'CN_match' => $args['hostname']
74-
);
75-
}
76-
// @codeCoverageIgnoreEnd
7765
}
7866

79-
// latest versions of PHP no longer accept any other URI components and
80-
// HHVM fails to parse URIs with a query but no path, so let's simplify our URI here
67+
// PHP 7.1.4 does not accept any other URI components (such as a query with no path), so let's simplify our URI here
8168
$remote = 'tcp://' . $parts['host'] . ':' . $parts['port'];
8269

8370
$stream = @\stream_socket_client(
@@ -108,7 +95,7 @@ public function connect($uri)
10895
// If we reach this point, we know the connection is dead, but we don't know the underlying error condition.
10996
// @codeCoverageIgnoreStart
11097
if (\function_exists('socket_import_stream')) {
111-
// actual socket errno and errstr can be retrieved with ext-sockets on PHP 5.4+
98+
// actual socket errno and errstr can be retrieved with ext-sockets
11299
$socket = \socket_import_stream($stream);
113100
$errno = \socket_get_option($socket, \SOL_SOCKET, \SO_ERROR);
114101
$errstr = \socket_strerror($errno);
@@ -149,13 +136,6 @@ public function connect($uri)
149136
$loop->removeWriteStream($stream);
150137
\fclose($stream);
151138

152-
// @codeCoverageIgnoreStart
153-
// legacy PHP 5.3 sometimes requires a second close call (see tests)
154-
if (\PHP_VERSION_ID < 50400 && \is_resource($stream)) {
155-
\fclose($stream);
156-
}
157-
// @codeCoverageIgnoreEnd
158-
159139
throw new \RuntimeException(
160140
'Connection to ' . $uri . ' cancelled during TCP/IP handshake (ECONNABORTED)',
161141
\defined('SOCKET_ECONNABORTED') ? \SOCKET_ECONNABORTED : 103

src/UnixServer.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ public function __construct($path, LoopInterface $loop = null, array $context =
6868
\set_error_handler(function ($_, $error) use (&$errno, &$errstr) {
6969
// PHP does not seem to report errno/errstr for Unix domain sockets (UDS) right now.
7070
// This only applies to UDS server sockets, see also https://3v4l.org/NAhpr.
71-
// Parse PHP warning message containing unknown error, HHVM reports proper info at least.
7271
if (\preg_match('/\(([^\)]+)\)|\[(\d+)\]: (.*)/', $error, $match)) {
7372
$errstr = isset($match[3]) ? $match['3'] : $match[1];
7473
$errno = isset($match[2]) ? (int)$match[2] : 0;

0 commit comments

Comments
 (0)