[WebSocket][Tests] Passing AB tests 3.* and 7.*

This commit is contained in:
Chris Boden 2012-07-11 10:45:34 -04:00
parent 693cda9526
commit 89660863c3
2 changed files with 108 additions and 0 deletions

View File

@ -21,8 +21,11 @@ class RFC6455 implements VersionInterface {
*/ */
protected $_verifier; protected $_verifier;
private $closeCodes = array();
public function __construct() { public function __construct() {
$this->_verifier = new HandshakeVerifier; $this->_verifier = new HandshakeVerifier;
$this->setCloseCodes();
} }
/** /**
@ -92,6 +95,13 @@ class RFC6455 implements VersionInterface {
if ($from->WebSocket->frame->isCoalesced()) { if ($from->WebSocket->frame->isCoalesced()) {
$frame = $from->WebSocket->frame; $frame = $from->WebSocket->frame;
if (false !== $frame->getRsv1() ||
false !== $frame->getRsv2() ||
false !== $frame->getRsv3()
) {
return $from->close($frame::CLOSE_PROTOCOL);
}
if (!$frame->isMasked()) { if (!$frame->isMasked()) {
return $from->close($frame::CLOSE_PROTOCOL); return $from->close($frame::CLOSE_PROTOCOL);
} }
@ -105,6 +115,26 @@ class RFC6455 implements VersionInterface {
switch ($opcode) { switch ($opcode) {
case $frame::OP_CLOSE: case $frame::OP_CLOSE:
$closeCode = 0;
$bin = $frame->getPayload();
if (empty($bin)) {
return $from->close();
}
if (strlen($bin) >= 2) {
list($closeCode) = array_merge(unpack('n*', substr($bin, 0, 2)));
}
if (!$this->isValidCloseCode($closeCode)) {
return $from->close($frame::CLOSE_PROTOCOL);
}
if (!mb_check_encoding(substr($bin, 2), 'UTF-8')) {
return $from->close($frame::CLOSE_BAD_PAYLOAD);
}
return $from->close($frame); return $from->close($frame);
break; break;
case $frame::OP_PING: case $frame::OP_PING:
@ -190,4 +220,40 @@ class RFC6455 implements VersionInterface {
public function sign($key) { public function sign($key) {
return base64_encode(sha1($key . static::GUID, true)); return base64_encode(sha1($key . static::GUID, true));
} }
/**
* Determine if a close code is valid
* @param int|string
* @return bool
*/
public function isValidCloseCode($val) {
if (array_key_exists($val, $this->closeCodes)) {
return true;
}
if ($val >= 3000 && $val <= 4999) {
return true;
}
return false;
if (empty($val)) {
return false;
}
}
/**
* Creates a private lookup of valid, private close codes
*/
protected function setCloseCodes() {
$this->closeCodes[Frame::CLOSE_NORMAL] = true;
$this->closeCodes[Frame::CLOSE_GOING_AWAY] = true;
$this->closeCodes[Frame::CLOSE_PROTOCOL] = true;
$this->closeCodes[Frame::CLOSE_BAD_DATA] = true;
$this->closeCodes[Frame::CLOSE_BAD_PAYLOAD] = true;
$this->closeCodes[Frame::CLOSE_POLICY] = true;
$this->closeCodes[Frame::CLOSE_TOO_BIG] = true;
$this->closeCodes[Frame::CLOSE_MAND_EXT] = true;
$this->closeCodes[Frame::CLOSE_SRV_ERR] = true;
}
} }

View File

@ -132,6 +132,48 @@ class Frame implements FrameInterface {
return (boolean)(int)$fbb[0]; return (boolean)(int)$fbb[0];
} }
/**
* @return boolean
* @throws UnderflowException
*/
public function getRsv1() {
if ($this->bytesRecvd < 1) {
throw new \UnderflowException('Not enough bytes received to determine reserved bit');
}
$fbb = sprintf('%08b', ord(substr($this->data, 0, 1)));
return (boolean)(int)$fbb[1];
}
/**
* @return boolean
* @throws UnderflowException
*/
public function getRsv2() {
if ($this->bytesRecvd < 1) {
throw new \UnderflowException('Not enough bytes received to determine reserved bit');
}
$fbb = sprintf('%08b', ord(substr($this->data, 0, 1)));
return (boolean)(int)$fbb[2];
}
/**
* @return boolean
* @throws UnderflowException
*/
public function getRsv3() {
if ($this->bytesRecvd < 1) {
throw new \UnderflowException('Not enough bytes received to determine reserved bit');
}
$fbb = sprintf('%08b', ord(substr($this->data, 0, 1)));
return (boolean)(int)$fbb[3];
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */