API docs and message length

RFC6455 Message::getPayloadLenght now returns a value
This commit is contained in:
Chris Boden 2012-04-29 19:20:59 -04:00
parent 852e5777e3
commit 381dd7bab6
6 changed files with 112 additions and 3 deletions

View File

@ -16,6 +16,9 @@ use Guzzle\Http\Message\Response;
* @link http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
*/
class Hixie76 implements VersionInterface {
/**
* {@inheritdoc}
*/
public static function isProtocol(RequestInterface $request) {
return !(null === $request->getHeader('Sec-WebSocket-Key2'));
}
@ -40,14 +43,23 @@ class Hixie76 implements VersionInterface {
return $response;
}
/**
* @return Hixie76\Message
*/
public function newMessage() {
return new Hixie76\Message;
}
/**
* @return Hixie76\Frame
*/
public function newFrame() {
return new Hixie76\Frame;
}
/**
* {@inheritdoc}
*/
public function frame($message, $mask = true) {
return chr(0) . $message . chr(255);
}

View File

@ -12,26 +12,44 @@ class Frame implements FrameInterface {
*/
protected $_data = '';
/**
* {@inheritdoc}
*/
public function isCoalesced() {
return (boolean)($this->_data[0] == chr(0) && substr($this->_data, -1) == chr(255));
}
/**
* {@inheritdoc}
*/
public function addBuffer($buf) {
$this->_data .= (string)$buf;
}
/**
* {@inheritdoc}
*/
public function isFinal() {
return true;
}
/**
* {@inheritdoc}
*/
public function isMasked() {
return false;
}
/**
* {@inheritdoc}
*/
public function getOpcode() {
return 1;
}
/**
* {@inheritdoc}
*/
public function getPayloadLength() {
if (!$this->isCoalesced()) {
throw new \UnderflowException('Not enough of the message has been buffered to determine the length of the payload');
@ -40,10 +58,16 @@ class Frame implements FrameInterface {
return strlen($this->_data) - 2;
}
/**
* {@inheritdoc}
*/
public function getMaskingKey() {
return '';
}
/**
* {@inheritdoc}
*/
public function getPayload() {
if (!$this->isCoalesced()) {
return new \UnderflowException('Not enough data buffered to read payload');

View File

@ -9,10 +9,16 @@ class Message implements MessageInterface {
*/
protected $_frame = null;
/**
* {@inheritdoc}
*/
public function __toString() {
return $this->getPayload();
}
/**
* {@inheritdoc}
*/
public function isCoalesced() {
if (!($this->_frame instanceof FrameInterface)) {
return false;
@ -21,6 +27,9 @@ class Message implements MessageInterface {
return $this->_frame->isCoalesced();
}
/**
* {@inheritdoc}
*/
public function addFrame(FrameInterface $fragment) {
if (null !== $this->_frame) {
throw new \OverflowException('Hixie76 does not support multiple framing of messages');
@ -29,15 +38,24 @@ class Message implements MessageInterface {
$this->_frame = $fragment;
}
/**
* {@inheritdoc}
*/
public function getOpcode() {
// Hixie76 only supported text messages
return 1;
}
/**
* {@inheritdoc}
*/
public function getPayloadLength() {
throw new \DomainException('Please sir, may I have some code? (' . __FUNCTION__ . ')');
}
/**
* {@inheritdoc}
*/
public function getPayload() {
if (!$this->isCoalesced()) {
throw new \UnderflowException('Message has not been fully buffered yet');

View File

@ -20,14 +20,16 @@ class RFC6455 implements VersionInterface {
$this->_verifier = new HandshakeVerifier;
}
/**
* {@inheritdoc}
*/
public static function isProtocol(RequestInterface $request) {
$version = (int)$request->getHeader('Sec-WebSocket-Version', -1);
return (13 === $version);
}
/**
* @return array
* I kept this as an array and combined in App for future considerations...easier to add a subprotol as a key value than edit a string
* {@inheritdoc}
* @todo Decide what to do on failure...currently throwing an exception and I think socket connection is closed. Should be sending 40x error - but from where?
*/
public function handshake(RequestInterface $request) {
@ -62,6 +64,7 @@ class RFC6455 implements VersionInterface {
* Thanks to @lemmingzshadow for the code on decoding a HyBi-10 frame
* @link https://github.com/lemmingzshadow/php-websocket
* @todo look into what happens when false is returned here
* @todo This is needed when a client is created - needs re-write as missing parts of protocol
* @param string
* @return string
*/

View File

@ -27,6 +27,9 @@ class Frame implements FrameInterface {
*/
protected $_pay_check = -1;
/**
* {@inheritdoc}
*/
public function isCoalesced() {
try {
$payload_length = $this->getPayloadLength();
@ -38,6 +41,9 @@ class Frame implements FrameInterface {
return $payload_length + $payload_start === $this->_bytes_rec;
}
/**
* {@inheritdoc}
*/
public function addBuffer($buf) {
$buf = (string)$buf;
@ -45,6 +51,9 @@ class Frame implements FrameInterface {
$this->_bytes_rec += strlen($buf);
}
/**
* {@inheritdoc}
*/
public function isFinal() {
if ($this->_bytes_rec < 1) {
throw new \UnderflowException('Not enough bytes received to determine if this is the final frame in message');
@ -54,6 +63,9 @@ class Frame implements FrameInterface {
return (boolean)(int)$fbb[0];
}
/**
* {@inheritdoc}
*/
public function isMasked() {
if ($this->_bytes_rec < 2) {
throw new \UnderflowException("Not enough bytes received ({$this->_bytes_rec}) to determine if mask is set");
@ -62,6 +74,9 @@ class Frame implements FrameInterface {
return (boolean)bindec(substr(sprintf('%08b', ord($this->_data[1])), 0, 1));
}
/**
* {@inheritdoc}
*/
public function getOpcode() {
if ($this->_bytes_rec < 1) {
throw new \UnderflowException('Not enough bytes received to determine opcode');
@ -125,6 +140,9 @@ class Frame implements FrameInterface {
return (1 + $this->getNumPayloadBits()) / 8;
}
/**
* {@inheritdoc}
*/
public function getPayloadLength() {
if ($this->_pay_len_def !== -1) {
return $this->_pay_len_def;
@ -151,6 +169,9 @@ class Frame implements FrameInterface {
return $this->getPayloadLength();
}
/**
* {@inheritdoc}
*/
public function getMaskingKey() {
if (!$this->isMasked()) {
return '';
@ -166,10 +187,16 @@ class Frame implements FrameInterface {
return substr($this->_data, $start, $length);
}
/**
* {@inheritdoc}
*/
public function getPayloadStartingByte() {
return 1 + $this->getNumPayloadBytes() + strlen($this->getMaskingKey());
}
/**
* {@inheritdoc}
*/
public function getPayload() {
if (!$this->isCoalesced()) {
throw new \UnderflowException('Can not return partial message');

View File

@ -13,10 +13,16 @@ class Message implements MessageInterface {
$this->_frames = new \SplDoublyLinkedList;
}
/**
* {@inheritdoc}
*/
public function __toString() {
return $this->getPayload();
}
/**
* {@inheritdoc}
*/
public function isCoalesced() {
if (count($this->_frames) == 0) {
return false;
@ -28,6 +34,7 @@ class Message implements MessageInterface {
}
/**
* {@inheritdoc}
* @todo Should I allow addFrame if the frame is not coalesced yet? I believe I'm assuming this class will only receive fully formed frame messages
* @todo Also, I should perhaps check the type...control frames (ping/pong/close) are not to be considered part of a message
*/
@ -35,6 +42,9 @@ class Message implements MessageInterface {
$this->_frames->push($fragment);
}
/**
* {@inheritdoc}
*/
public function getOpcode() {
if (count($this->_frames) == 0) {
throw new \UnderflowException('No frames have been added to this message');
@ -43,10 +53,25 @@ class Message implements MessageInterface {
return $this->_frames->bottom()->getOpcode();
}
/**
* {@inheritdoc}
*/
public function getPayloadLength() {
throw new \DomainException('Please sir, may I have some code? (' . __FUNCTION__ . ')');
$len = 0;
foreach ($this->_frames as $frame) {
try {
$len += $frame->getPayloadLength();
} catch (\UnderflowException $e) {
}
}
return $len;
}
/**
* {@inheritdoc}
*/
public function getPayload() {
if (!$this->isCoalesced()) {
throw new \UnderflowMessage('Message has not been put back together yet');