Passing some ab tests

This commit is contained in:
matt 2015-03-16 00:15:33 -04:00
parent 8653b92115
commit 1833a0f3ec
5 changed files with 64 additions and 22 deletions

View File

@ -2,7 +2,7 @@
namespace Ratchet\RFC6455\Handshake; namespace Ratchet\RFC6455\Handshake;
use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\RequestInterface;
use Ratchet\RFC6455\Encoding\ValidatorInterface; use Ratchet\RFC6455\Encoding\ValidatorInterface;
/** /**
@ -20,25 +20,16 @@ class Negotiator implements NegotiatorInterface {
*/ */
private $validator; private $validator;
/**
* A lookup of the valid close codes that can be sent in a frame
* @var array
* @deprecated
*/
private $closeCodes = [];
public function __construct(ValidatorInterface $validator) { public function __construct(ValidatorInterface $validator) {
$this->verifier = new RequestVerifier; $this->verifier = new RequestVerifier;
$this->setCloseCodes();
$this->validator = $validator; $this->validator = $validator;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function isProtocol(ServerRequestInterface $request) { public function isProtocol(RequestInterface $request) {
$version = (int)(string)$request->getHeader('Sec-WebSocket-Version'); $version = (int)(string)$request->getHeader('Sec-WebSocket-Version');
return ($this->getVersionNumber() === $version); return ($this->getVersionNumber() === $version);
@ -54,7 +45,7 @@ class Negotiator implements NegotiatorInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function handshake(ServerRequestInterface $request) { public function handshake(RequestInterface $request) {
if (true !== $this->verifier->verifyAll($request)) { if (true !== $this->verifier->verifyAll($request)) {
return new Response(400); return new Response(400);
} }
@ -71,9 +62,9 @@ class Negotiator implements NegotiatorInterface {
* @param \Ratchet\WebSocket\Version\RFC6455\Connection $from * @param \Ratchet\WebSocket\Version\RFC6455\Connection $from
* @param string $data * @param string $data
*/ */
public function onMessage(ConnectionInterface $from, $data) { // public function onMessage(ConnectionInterface $from, $data) {
//
} // }
/** /**
* Used when doing the handshake to encode the key, verifying client/server are speaking the same language * Used when doing the handshake to encode the key, verifying client/server are speaking the same language
@ -84,4 +75,26 @@ class Negotiator implements NegotiatorInterface {
public function sign($key) { public function sign($key) {
return base64_encode(sha1($key . static::GUID, true)); return base64_encode(sha1($key . static::GUID, true));
} }
/**
* Add supported protocols. If the request has any matching the response will include one
* @param string $id
*/
function addSupportedSubProtocol($id)
{
// TODO: Implement addSupportedSubProtocol() method.
}
/**
* If enabled and support for a subprotocol has been added handshake
* will not upgrade if a match between request and supported subprotocols
* @param boolean $enable
* @todo Consider extending this interface and moving this there.
* The spec does says the server can fail for this reason, but
* it is not a requirement. This is an implementation detail.
*/
function setStrictSubProtocolCheck($enable)
{
// TODO: Implement setStrictSubProtocolCheck() method.
}
} }

View File

@ -1,8 +1,8 @@
<?php <?php
namespace Ratchet\RFC6455\Handshake; namespace Ratchet\RFC6455\Handshake;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
/** /**
* A standard interface for interacting with the various version of the WebSocket protocol * A standard interface for interacting with the various version of the WebSocket protocol
@ -13,10 +13,10 @@ interface NegotiatorInterface {
/** /**
* Given an HTTP header, determine if this version should handle the protocol * Given an HTTP header, determine if this version should handle the protocol
* @param ServerRequestInterface $request * @param RequestInterface $request
* @return bool * @return bool
*/ */
function isProtocol(ServerRequestInterface $request); function isProtocol(RequestInterface $request);
/** /**
* Although the version has a name associated with it the integer returned is the proper identification * Although the version has a name associated with it the integer returned is the proper identification
@ -26,10 +26,10 @@ interface NegotiatorInterface {
/** /**
* Perform the handshake and return the response headers * Perform the handshake and return the response headers
* @param ServerRequestInterface $request * @param RequestInterface $request
* @return ResponseInterface * @return ResponseInterface
*/ */
function handshake(ServerRequestInterface $request); function handshake(RequestInterface $request);
/** /**
* Add supported protocols. If the request has any matching the response will include one * Add supported protocols. If the request has any matching the response will include one

View File

@ -1,6 +1,9 @@
<?php <?php
namespace Ratchet\RFC6455\Handshake; namespace Ratchet\RFC6455\Handshake;
use Psr\Http\Message\RequestInterface;
/** /**
* These are checks to ensure the client requested handshake are valid * These are checks to ensure the client requested handshake are valid
* Verification rules come from section 4.2.1 of the RFC6455 document * Verification rules come from section 4.2.1 of the RFC6455 document
@ -19,12 +22,12 @@ class RequestVerifier {
$passes += (int)$this->verifyMethod($request->getMethod()); $passes += (int)$this->verifyMethod($request->getMethod());
$passes += (int)$this->verifyHTTPVersion($request->getProtocolVersion()); $passes += (int)$this->verifyHTTPVersion($request->getProtocolVersion());
$passes += (int)$this->verifyRequestURI($request->getPath()); $passes += (int)$this->verifyRequestURI($request->getUri()->getPath());
$passes += (int)$this->verifyHost((string)$request->getHeader('Host')); $passes += (int)$this->verifyHost((string)$request->getHeader('Host'));
$passes += (int)$this->verifyUpgradeRequest((string)$request->getHeader('Upgrade')); $passes += (int)$this->verifyUpgradeRequest((string)$request->getHeader('Upgrade'));
$passes += (int)$this->verifyConnection((string)$request->getHeader('Connection')); $passes += (int)$this->verifyConnection((string)$request->getHeader('Connection'));
$passes += (int)$this->verifyKey((string)$request->getHeader('Sec-WebSocket-Key')); $passes += (int)$this->verifyKey((string)$request->getHeader('Sec-WebSocket-Key'));
$passes += (int)$this->verifyVersion($headers['Sec-WebSocket-Version']); $passes += (int)$this->verifyVersion((string)$request->getHeader('Sec-WebSocket-Version'));
return (8 === $passes); return (8 === $passes);
} }

View File

@ -7,6 +7,9 @@ class Message implements MessageInterface {
*/ */
private $_frames; private $_frames;
/** @var bool */
private $binary = false;
public function __construct() { public function __construct() {
$this->_frames = new \SplDoublyLinkedList; $this->_frames = new \SplDoublyLinkedList;
} }
@ -50,8 +53,12 @@ class Message implements MessageInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
* @todo Also, I should perhaps check the type...control frames (ping/pong/close) are not to be considered part of a message * @todo Also, I should perhaps check the type...control frames (ping/pong/close) are not to be considered part of a message
* @todo What should we do if there are binary and text mixed together?
*/ */
public function addFrame(FrameInterface $fragment) { public function addFrame(FrameInterface $fragment) {
if ($this->_frames->isEmpty()) {
$this->binary = $fragment->getOpcode() == Frame::OP_BINARY;
}
$this->_frames->push($fragment); $this->_frames->push($fragment);
return $this; return $this;
@ -118,4 +125,12 @@ class Message implements MessageInterface {
return $buffer; return $buffer;
} }
/**
* @return boolean
*/
public function isBinary()
{
return $this->binary;
}
} }

View File

@ -19,6 +19,12 @@ class MessageStreamer implements EventEmitterInterface {
/** @var array */ /** @var array */
private $closeCodes = []; private $closeCodes = [];
function __construct()
{
$this->setCloseCodes();
}
public function onData($data) { public function onData($data) {
$overflow = ''; $overflow = '';
@ -37,6 +43,11 @@ class MessageStreamer implements EventEmitterInterface {
if ($frame->isCoalesced()) { if ($frame->isCoalesced()) {
$opcode = $frame->getOpcode(); $opcode = $frame->getOpcode();
if ($opcode > 2) { if ($opcode > 2) {
if ($frame->getPayloadLength() > 125) {
// payload only allowed to 125 on control frames ab 2.5
$this->emit('close', [$frame::CLOSE_PROTOCOL]);
return;
}
switch ($opcode) { switch ($opcode) {
case $frame::OP_CLOSE: case $frame::OP_CLOSE:
$closeCode = 0; $closeCode = 0;