86 lines
2.3 KiB
PHP
86 lines
2.3 KiB
PHP
<?php
|
|
namespace Ratchet\WebSocket\Version;
|
|
use Ratchet\WebSocket\Version\RFC6455\HandshakeVerifier;
|
|
use Guzzle\Http\Message\RequestInterface;
|
|
use Guzzle\Http\Message\Response;
|
|
|
|
/**
|
|
* @link http://tools.ietf.org/html/rfc6455
|
|
* @todo Unicode: return mb_convert_encoding(pack("N",$u), mb_internal_encoding(), 'UCS-4BE');
|
|
*/
|
|
class RFC6455 implements VersionInterface {
|
|
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
|
|
|
/**
|
|
* @var RFC6455\HandshakeVerifier
|
|
*/
|
|
protected $_verifier;
|
|
|
|
public function __construct() {
|
|
$this->_verifier = new HandshakeVerifier;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function isProtocol(RequestInterface $request) {
|
|
$version = (int)$request->getHeader('Sec-WebSocket-Version', -1);
|
|
|
|
return ($this->getVersionNumber() === $version);
|
|
}
|
|
|
|
public function getVersionNumber() {
|
|
return 13;
|
|
}
|
|
|
|
/**
|
|
* {@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) {
|
|
if (true !== $this->_verifier->verifyAll($request)) {
|
|
throw new \InvalidArgumentException('Invalid HTTP header');
|
|
}
|
|
|
|
$headers = array(
|
|
'Upgrade' => 'websocket'
|
|
, 'Connection' => 'Upgrade'
|
|
, 'Sec-WebSocket-Accept' => $this->sign($request->getHeader('Sec-WebSocket-Key'))
|
|
);
|
|
|
|
return new Response(101, $headers);
|
|
}
|
|
|
|
/**
|
|
* @return RFC6455\Message
|
|
*/
|
|
public function newMessage() {
|
|
return new RFC6455\Message;
|
|
}
|
|
|
|
/**
|
|
* @return RFC6455\Frame
|
|
*/
|
|
public function newFrame() {
|
|
return new RFC6455\Frame;
|
|
}
|
|
|
|
/**
|
|
* @todo This is needed when a client is created - needs re-write as missing parts of protocol
|
|
* @param string
|
|
* @return string
|
|
*/
|
|
public function frame($message, $mask = true) {
|
|
return RFC6455\Frame::create($message)->data;
|
|
}
|
|
|
|
/**
|
|
* Used when doing the handshake to encode the key, verifying client/server are speaking the same language
|
|
* @param string
|
|
* @return string
|
|
* @internal
|
|
*/
|
|
public function sign($key) {
|
|
return base64_encode(sha1($key . static::GUID, 1));
|
|
}
|
|
} |