Server passing tests - client passes most tests - refactoring and API help needed

This commit is contained in:
Matt Bonneau 2017-03-10 00:17:23 -05:00
parent 7280ddcd19
commit 8eed9e7db2
5 changed files with 41 additions and 32 deletions

View File

@ -36,7 +36,7 @@ class ClientNegotiator {
if ($enablePerMessageDeflate) { if ($enablePerMessageDeflate) {
$this->defaultHeader = $this->defaultHeader->withAddedHeader( $this->defaultHeader = $this->defaultHeader->withAddedHeader(
'Sec-WebSocket-Extensions', 'Sec-WebSocket-Extensions',
'permessage-deflate'); 'permessage-deflate; client_max_window_bits');
} }
} }

View File

@ -121,7 +121,6 @@ final class PermessageDeflateOptions
*/ */
public function getClientNoContextTakeover() public function getClientNoContextTakeover()
{ {
return false; // always return false unless we want to conserve resources
return $this->client_no_context_takeover; return $this->client_no_context_takeover;
} }
@ -163,11 +162,9 @@ final class PermessageDeflateOptions
if ($this->client_max_window_bits != 15) { if ($this->client_max_window_bits != 15) {
$header .= '; client_max_window_bits='. $this->client_max_window_bits; $header .= '; client_max_window_bits='. $this->client_max_window_bits;
} }
// this would only be needed if you want to save server resources (no buffer needed) if ($this->client_no_context_takeover) {
// worse compression $header .= '; client_no_context_takeover';
// if ($this->client_no_context_takeover) { }
// $header .= '; client_no_context_takeover';
// }
if ($this->server_max_window_bits != 15) { if ($this->server_max_window_bits != 15) {
$header .= '; server_max_window_bits=' . $this->server_max_window_bits; $header .= '; server_max_window_bits=' . $this->server_max_window_bits;
} }
@ -175,8 +172,6 @@ final class PermessageDeflateOptions
$header .= '; server_no_context_takeover'; $header .= '; server_no_context_takeover';
} }
echo $header . "\n";
return $response->withAddedHeader('Sec-Websocket-Extensions', $header); return $response->withAddedHeader('Sec-Websocket-Extensions', $header);
} }
} }

View File

@ -124,6 +124,8 @@ class MessageBuffer {
return ''; return '';
} }
} else { } else {
//echo "fin: " . json_encode($this->frameBuffer->isFinal()) . ", bCount: " . $this->messageBuffer->count() . ", Rsv1: " . json_encode($this->frameBuffer->getRsv1()) . "\n";
if ($this->messageBuffer->count() === 0 && $this->frameBuffer->getRsv1()) { if ($this->messageBuffer->count() === 0 && $this->frameBuffer->getRsv1()) {
$this->compressedMessage = true; $this->compressedMessage = true;
} }
@ -305,7 +307,7 @@ class MessageBuffer {
if ($final) { if ($final) {
// reset deflator if client doesn't remember contexts // reset deflator if client doesn't remember contexts
if ($this->permessageDeflateOptions->getClientNoContextTakeover()) { if ($this->getDeflateNoContextTakeover()) {
$this->deflator = null; $this->deflator = null;
} }
$this->streamingMessageOpCode = -1; $this->streamingMessageOpCode = -1;
@ -314,17 +316,38 @@ class MessageBuffer {
private $inflator; private $inflator;
private function getDeflateNoContextTakeover() {
return $this->checkForMask ?
$this->permessageDeflateOptions->getServerNoContextTakeover() :
$this->permessageDeflateOptions->getClientNoContextTakeover();
}
private function getDeflateWindowBits() {
return $this->checkForMask ? $this->permessageDeflateOptions->getServerMaxWindowBits() : $this->permessageDeflateOptions->getClientMaxWindowBits();
}
private function getInflateNoContextTakeover() {
return $this->checkForMask ?
$this->permessageDeflateOptions->getClientNoContextTakeover() :
$this->permessageDeflateOptions->getServerNoContextTakeover();
}
private function getInflateWindowBits() {
return $this->checkForMask ? $this->permessageDeflateOptions->getClientMaxWindowBits() : $this->permessageDeflateOptions->getServerMaxWindowBits();
}
private function inflateFrame(Frame $frame) { private function inflateFrame(Frame $frame) {
if ($this->inflator === null) { if ($this->inflator === null) {
// $this->inflator = inflate_init(ZLIB_ENCODING_RAW); $options = [
$this->inflator = inflate_init(
ZLIB_ENCODING_RAW,
[
'level' => -1, 'level' => -1,
'memory' => 8, 'memory' => 8,
'window' => $this->permessageDeflateOptions->getClientMaxWindowBits(), 'window' => $this->getInflateWindowBits(),
'strategy' => ZLIB_DEFAULT_STRATEGY 'strategy' => ZLIB_DEFAULT_STRATEGY
] ];
//echo "inflate_init(RAW, " . json_encode($options) . ")\n";
$this->inflator = inflate_init(
ZLIB_ENCODING_RAW,
$options
); );
} }
@ -349,16 +372,12 @@ class MessageBuffer {
} }
if ($this->deflator === null) { if ($this->deflator === null) {
// $this->deflator = deflate_init(
// ZLIB_ENCODING_RAW
// );
echo "init with " . $this->permessageDeflateOptions->getServerMaxWindowBits();
$this->deflator = deflate_init( $this->deflator = deflate_init(
ZLIB_ENCODING_RAW, ZLIB_ENCODING_RAW,
[ [
'level' => -1, 'level' => -1,
'memory' => 8, 'memory' => 8,
'window' => $this->permessageDeflateOptions->getServerMaxWindowBits(), 'window' => $this->getDeflateWindowBits(),
'strategy' => ZLIB_DEFAULT_STRATEGY 'strategy' => ZLIB_DEFAULT_STRATEGY
] ]
); );

View File

@ -1,5 +1,7 @@
<?php <?php
use GuzzleHttp\Psr7\Uri; use GuzzleHttp\Psr7\Uri;
use Psr\Http\Message\RequestInterface;
use Ratchet\RFC6455\Handshake\PermessageDeflateOptions;
use Ratchet\RFC6455\Handshake\ResponseVerifier; use Ratchet\RFC6455\Handshake\ResponseVerifier;
use Ratchet\RFC6455\Messaging\MessageBuffer; use Ratchet\RFC6455\Messaging\MessageBuffer;
use React\Promise\Deferred; use React\Promise\Deferred;
@ -20,10 +22,6 @@ $factory = new \React\SocketClient\Connector($loop, $dnsResolver);
function echoStreamerFactory($conn, $permessageDeflateOptions = null) function echoStreamerFactory($conn, $permessageDeflateOptions = null)
{ {
if ($permessageDeflateOptions === null) {
$permessageDeflateOptions = [];
}
return new \Ratchet\RFC6455\Messaging\MessageBuffer( return new \Ratchet\RFC6455\Messaging\MessageBuffer(
new \Ratchet\RFC6455\Messaging\CloseFrameChecker, new \Ratchet\RFC6455\Messaging\CloseFrameChecker,
function (\Ratchet\RFC6455\Messaging\MessageInterface $msg, MessageBuffer $messageBuffer) use ($conn) { function (\Ratchet\RFC6455\Messaging\MessageInterface $msg, MessageBuffer $messageBuffer) use ($conn) {
@ -112,6 +110,7 @@ function runTest($case)
$factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred, $casePath, $case) { $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred, $casePath, $case) {
$cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator(true); $cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator(true);
/** @var RequestInterface $cnRequest */
$cnRequest = $cn->generateRequest(new Uri('ws://127.0.0.1:9001' . $casePath)); $cnRequest = $cn->generateRequest(new Uri('ws://127.0.0.1:9001' . $casePath));
$rawResponse = ""; $rawResponse = "";
@ -129,15 +128,13 @@ function runTest($case)
$response = \GuzzleHttp\Psr7\parse_response($rawResponse); $response = \GuzzleHttp\Psr7\parse_response($rawResponse);
if (!$cn->validateResponse($cnRequest, $response)) { if (!$cn->validateResponse($cnRequest, $response)) {
echo "Invalid response.\n";
$stream->end(); $stream->end();
$deferred->reject(); $deferred->reject();
} else { } else {
$ms = echoStreamerFactory( $ms = echoStreamerFactory(
$stream, $stream,
(new ResponseVerifier())->getPermessageDeflateOptions( PermessageDeflateOptions::fromRequestOrResponse($response)[0]
$cnRequest->getHeader('Sec-WebSocket-Extensions'),
$response->getHeader('Sec-WebSocket-Extensions')
)
); );
} }
} }

View File

@ -1,7 +1,5 @@
<?php <?php
use Ratchet\RFC6455\Handshake\PermessageDeflateOptions; use Ratchet\RFC6455\Handshake\PermessageDeflateOptions;
use Ratchet\RFC6455\Handshake\RequestVerifier;
use Ratchet\RFC6455\Handshake\ResponseVerifier;
use Ratchet\RFC6455\Messaging\MessageBuffer; use Ratchet\RFC6455\Messaging\MessageBuffer;
use Ratchet\RFC6455\Messaging\MessageInterface; use Ratchet\RFC6455\Messaging\MessageInterface;
use Ratchet\RFC6455\Messaging\FrameInterface; use Ratchet\RFC6455\Messaging\FrameInterface;