diff --git a/.travis.yml b/.travis.yml index 11d51b4..f51c586 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,9 @@ php: - 5.5 - 5.6 - 7 + - 7.1 - hhvm + - nightly before_install: - export PATH=$HOME/.local/bin:$PATH diff --git a/src/Handshake/ClientNegotiator.php b/src/Handshake/ClientNegotiator.php index 52bcebc..4acf5e4 100644 --- a/src/Handshake/ClientNegotiator.php +++ b/src/Handshake/ClientNegotiator.php @@ -32,7 +32,7 @@ class ClientNegotiator { // https://bugs.php.net/bug.php?id=73373 // https://bugs.php.net/bug.php?id=74240 - need >=7.1.4 or >=7.0.18 - $supported = version_compare(PHP_VERSION, '7.0.18', '>=') && !version_compare(PHP_VERSION, '7.1.4', '<'); + $supported = PermessageDeflateOptions::permessageDeflateSupported(); if (!$supported) { if ($perMessageDeflateOptions->getDeflate()) { trigger_error('permessage-deflate is being disabled because it is not support by your PHP version.', E_USER_NOTICE); diff --git a/src/Handshake/PermessageDeflateOptions.php b/src/Handshake/PermessageDeflateOptions.php index 6d3ff3f..ff983c1 100644 --- a/src/Handshake/PermessageDeflateOptions.php +++ b/src/Handshake/PermessageDeflateOptions.php @@ -9,7 +9,8 @@ use Psr\Http\Message\ResponseInterface; final class PermessageDeflateOptions { const MAX_WINDOW_BITS = 15; - const VALID_BITS = ['8', '9', '10', '11', '12', '13', '14', '15']; + /* this is a private instead of const for 5.4 compatibility */ + private static $VALID_BITS = ['8', '9', '10', '11', '12', '13', '14', '15']; private $deflate = false; @@ -55,7 +56,7 @@ final class PermessageDeflateOptions } public function withServerMaxWindowBits($bits = self::MAX_WINDOW_BITS) { - if (!in_array($bits, self::VALID_BITS)) { + if (!in_array($bits, self::$VALID_BITS)) { throw new \Exception('server_max_window_bits must have a value between 8 and 15.'); } $new = clone $this; @@ -63,7 +64,7 @@ final class PermessageDeflateOptions } public function withClientMaxWindowBits($bits = self::MAX_WINDOW_BITS) { - if (!in_array($bits, self::VALID_BITS)) { + if (!in_array($bits, self::$VALID_BITS)) { throw new \Exception('client_max_window_bits must have a value between 8 and 15.'); } $new = clone $this; @@ -111,7 +112,7 @@ final class PermessageDeflateOptions $value = true; break; case "server_max_window_bits": - if (!in_array($value, self::VALID_BITS)) { + if (!in_array($value, self::$VALID_BITS)) { throw new InvalidPermessageDeflateOptionsException($key . ' must have a value between 8 and 15.'); } break; @@ -119,7 +120,7 @@ final class PermessageDeflateOptions if ($value === null) { $value = '15'; } - if (!in_array($value, self::VALID_BITS)) { + if (!in_array($value, self::$VALID_BITS)) { throw new InvalidPermessageDeflateOptionsException($key . ' must have no value or a value between 8 and 15.'); } break; @@ -245,4 +246,19 @@ final class PermessageDeflateOptions return $request->withAddedHeader('Sec-Websocket-Extensions', $header); } + + public static function permessageDeflateSupported($version = PHP_VERSION) { + if (!function_exists('deflate_init')) { + return false; + } + if (version_compare($version, '7.1.3', '>')) { + return true; + } + if (version_compare($version, '7.0.18', '>=') + && version_compare($version, '7.1.0', '<')) { + return true; + } + + return false; + } } diff --git a/src/Handshake/ServerNegotiator.php b/src/Handshake/ServerNegotiator.php index 3ee7e86..51752e3 100644 --- a/src/Handshake/ServerNegotiator.php +++ b/src/Handshake/ServerNegotiator.php @@ -24,7 +24,7 @@ class ServerNegotiator implements NegotiatorInterface { // https://bugs.php.net/bug.php?id=73373 // https://bugs.php.net/bug.php?id=74240 - need >=7.1.4 or >=7.0.18 - $supported = version_compare(PHP_VERSION, '7.0.18', '>=') && !version_compare(PHP_VERSION, '7.1.4', '<'); + $supported = PermessageDeflateOptions::permessageDeflateSupported(); if ($enablePerMessageDeflate && !$supported) { trigger_error('permessage-deflate is being disabled because it is not support by your PHP version.', E_USER_NOTICE); $enablePerMessageDeflate = false; diff --git a/tests/ab/clientRunner.php b/tests/ab/clientRunner.php index b51c4c0..60f4479 100644 --- a/tests/ab/clientRunner.php +++ b/tests/ab/clientRunner.php @@ -102,17 +102,19 @@ function getTestCases() { return $deferred->promise(); } +$cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator(PermessageDeflateOptions::createDefault()); + function runTest($case) { global $factory; global $testServer; + global $cn; $casePath = "/runCase?case={$case}&agent=" . AGENT; $deferred = new Deferred(); - $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred, $casePath, $case) { - $cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator(PermessageDeflateOptions::createDefault()); + $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($cn, $deferred, $casePath, $case) { /** @var RequestInterface $cnRequest */ $cnRequest = $cn->generateRequest(new Uri('ws://127.0.0.1:9001' . $casePath)); diff --git a/tests/ab/fuzzingclient_skip_deflate.json b/tests/ab/fuzzingclient_skip_deflate.json new file mode 100644 index 0000000..88732c9 --- /dev/null +++ b/tests/ab/fuzzingclient_skip_deflate.json @@ -0,0 +1,14 @@ +{ + "options": { + "failByDrop": false + } + , "outdir": "./reports/servers" + , "servers": [{ + "agent": "RatchetRFC/0.1.0" + , "url": "ws://localhost:9001" + , "options": {"version": 18} + }] + , "cases": ["*"] + , "exclude-cases": ["12.*", "13.*"] + , "exclude-agent-cases": {} +} diff --git a/tests/ab/fuzzingserver_skip_deflate.json b/tests/ab/fuzzingserver_skip_deflate.json new file mode 100644 index 0000000..3b90fc3 --- /dev/null +++ b/tests/ab/fuzzingserver_skip_deflate.json @@ -0,0 +1,10 @@ +{ + "url": "ws://127.0.0.1:9001" + , "options": { + "failByDrop": false + } + , "outdir": "./reports/clients" + , "cases": ["*"] + , "exclude-cases": ["12.*", "13.*"] + , "exclude-agent-cases": {} +} diff --git a/tests/ab/run_ab_tests.sh b/tests/ab/run_ab_tests.sh index 8fa9ced..16dcfd7 100644 --- a/tests/ab/run_ab_tests.sh +++ b/tests/ab/run_ab_tests.sh @@ -1,11 +1,23 @@ +set -x cd tests/ab -wstest -m fuzzingserver -s fuzzingserver.json & +SKIP_DEFLATE= +if [ "$TRAVIS" = "true" ]; then +if [ $(phpenv version-name) = "hhvm" -o $(phpenv version-name) = "5.4" -o $(phpenv version-name) = "5.5" -o $(phpenv version-name) = "5.6" ]; then + echo "Skipping deflate autobahn tests for $(phpenv version-name)" + SKIP_DEFLATE=_skip_deflate +fi +fi + +wstest -m fuzzingserver -s fuzzingserver$SKIP_DEFLATE.json & sleep 5 php clientRunner.php sleep 2 php startServer.php & +PHP_SERVER_PID=$! sleep 3 -wstest -m fuzzingclient -s fuzzingclient.json +wstest -m fuzzingclient -s fuzzingclient$SKIP_DEFLATE.json + +kill $PHP_SERVER_PID diff --git a/tests/unit/Handshake/PermessageDeflateOptionsTest.php b/tests/unit/Handshake/PermessageDeflateOptionsTest.php new file mode 100644 index 0000000..4b5fbe1 --- /dev/null +++ b/tests/unit/Handshake/PermessageDeflateOptionsTest.php @@ -0,0 +1,29 @@ +assertEquals($supported, PermessageDeflateOptions::permessageDeflateSupported($version)); + } +} \ No newline at end of file