Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszm-rc committed Oct 23, 2015
1 parent 30e8fac commit 07f22a3
Show file tree
Hide file tree
Showing 8 changed files with 480 additions and 254 deletions.
18 changes: 0 additions & 18 deletions bin/Server.php

This file was deleted.

44 changes: 0 additions & 44 deletions server/MessageHandler.php

This file was deleted.

187 changes: 11 additions & 176 deletions src/WebSocket/Client/WebSocketConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use React\Socket\Connection;
use WebSocket\Client\WebSocketClientInterface;
use WebSocket\Exception\ConnectionException;
use \WebSocket\Request\Request;

/**
* Oparty na eventLoop z ReactPHP klient WebSocket.
Expand Down Expand Up @@ -49,7 +50,7 @@ class WebSocketConnection {
* @param string $path
* @param null|string $origin
*/
public function __construct(WebSocketClientInterface $client, LoopInterface &$loop, $host = '127.0.0.1', $port = 8080, $path = '/', $origin = null) {
public function __construct(WebSocketClientInterface &$client, LoopInterface &$loop, $host = '127.0.0.1', $port = 8080, $path = '/', $origin = null) {
$this->setLoop($loop);
$this->setHost($host);
$this->setPort($port);
Expand Down Expand Up @@ -78,8 +79,8 @@ public function connect() {
}
$this->setSocket(new Connection($client, $this->getLoop()));
$this->getSocket()->on('data', function ($data) use ($root) {
$data = $root->parseIncomingRaw($data);
$root->parseData($data);
$data2 = Request::parseIncomingRaw($data);
$root->parseData($data2);
});

$this->getSocket()->write($this->createHeader());
Expand Down Expand Up @@ -145,10 +146,11 @@ private function sendData($data, $type = 'text', $masked = true) {
$this->disconnect();
return;
}

if (is_array($data)) {
$data = json_encode($data);
}
return $this->getSocket()->write($this->hybi10Encode($data));
return $this->getSocket()->write(Request::hybi10Encode($data));
}

/**
Expand All @@ -157,22 +159,18 @@ private function sendData($data, $type = 'text', $masked = true) {
* @param $response
*/
private function parseData($response) {

if (!$this->connected && isset($response['Sec-Websocket-Accept'])) {
if (base64_encode(pack('H*', sha1($this->key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))) === $response['Sec-Websocket-Accept']) {
if (base64_encode(pack('H*', sha1($this->key . Request::GUID))) === $response['Sec-Websocket-Accept']) {
$this->getClient()->onConnect();
$this->connected = true;
}
}

if ($this->connected && !empty($response['content'])) {
$content = trim($response['content']);
if (preg_match('/(\{.*\})/', $content, $match)) {
$content = json_decode($match[1], true);
if (is_array($content)) {
unset($response['status']);
unset($response['content']);
$this->receiveData($content, $response);
}
$content = Request::getMessage($response, false);
if (is_array($content)) {
$this->receiveData($content, $response);
}
}
}
Expand Down Expand Up @@ -202,40 +200,6 @@ private function createHeader() {
"Sec-WebSocket-Version: 13" . "\r\n" . "\r\n";
}

/**
* Parse raw incoming data
*
* @param $header
* @return array
*/
private function parseIncomingRaw($header) {
$retval = array ();
$content = "";
$fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header));
foreach ($fields as $field) {
if (preg_match('/([^:]+): (.+)/m', $field, $match)) {
$match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', function ($matches) {
return strtoupper($matches[0]);
}, strtolower(trim($match[1])));
if (isset($retval[$match[1]])) {
$retval[$match[1]] = array ($retval[$match[1]], $match[2]);
}
else {
$retval[$match[1]] = trim($match[2]);
}
}
else if (preg_match('!HTTP/1\.\d (\d)* .!', $field)) {
$retval["status"] = $field;
}
else {
$content .= $field . "\r\n";
}
}
$retval['content'] = $content;

return $retval;
}

/**
* Generate token
*
Expand Down Expand Up @@ -412,133 +376,4 @@ public function getLoop() {
return $this->loop;
}

/**
* @param $payload
* @param string $type
* @param bool $masked
* @return bool|string
*/
private function hybi10Encode($payload, $type = 'text', $masked = true) {
$frameHead = array ();
$frame = '';
$payloadLength = strlen($payload);

switch ($type) {
case 'text':
// first byte indicates FIN, Text-Frame (10000001):
$frameHead[0] = 129;
break;

case 'close':
// first byte indicates FIN, Close Frame(10001000):
$frameHead[0] = 136;
break;

case 'ping':
// first byte indicates FIN, Ping frame (10001001):
$frameHead[0] = 137;
break;

case 'pong':
// first byte indicates FIN, Pong frame (10001010):
$frameHead[0] = 138;
break;
}

// set mask and payload length (using 1, 3 or 9 bytes)
if ($payloadLength > 65535) {
$payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8);
$frameHead[1] = ($masked === true)?255:127;
for ($i = 0; $i < 8; $i++) {
$frameHead[$i + 2] = bindec($payloadLengthBin[$i]);
}

// most significant bit MUST be 0 (close connection if frame too big)
if ($frameHead[2] > 127) {
$this->close(1004);
return false;
}
}
elseif ($payloadLength > 125) {
$payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8);
$frameHead[1] = ($masked === true)?254:126;
$frameHead[2] = bindec($payloadLengthBin[0]);
$frameHead[3] = bindec($payloadLengthBin[1]);
}
else {
$frameHead[1] = ($masked === true)?$payloadLength + 128:$payloadLength;
}

// convert frame-head to string:
foreach (array_keys($frameHead) as $i) {
$frameHead[$i] = chr($frameHead[$i]);
}

if ($masked === true) {
// generate a random mask:
$mask = array ();
for ($i = 0; $i < 4; $i++) {
$mask[$i] = chr(rand(0, 255));
}

$frameHead = array_merge($frameHead, $mask);
}
$frame = implode('', $frameHead);
// append payload to frame:
for ($i = 0; $i < $payloadLength; $i++) {
$frame .= ($masked === true)?$payload[$i] ^ $mask[$i % 4]:$payload[$i];
}

return $frame;
}

/**
* @param $data
* @return null|string
*/
private function hybi10Decode($data) {
if (empty($data)) {
return null;
}

$bytes = $data;
$dataLength = '';
$mask = '';
$coded_data = '';
$decodedData = '';
$secondByte = sprintf('%08b', ord($bytes[1]));
$masked = ($secondByte[0] == '1')?true:false;
$dataLength = ($masked === true)?ord($bytes[1]) & 127:ord($bytes[1]);

if ($masked === true) {
if ($dataLength === 126) {
$mask = substr($bytes, 4, 4);
$coded_data = substr($bytes, 8);
}
elseif ($dataLength === 127) {
$mask = substr($bytes, 10, 4);
$coded_data = substr($bytes, 14);
}
else {
$mask = substr($bytes, 2, 4);
$coded_data = substr($bytes, 6);
}
for ($i = 0; $i < strlen($coded_data); $i++) {
$decodedData .= $coded_data[$i] ^ $mask[$i % 4];
}
}
else {
if ($dataLength === 126) {
$decodedData = substr($bytes, 4);
}
elseif ($dataLength === 127) {
$decodedData = substr($bytes, 10);
}
else {
$decodedData = substr($bytes, 2);
}
}
return $decodedData;
}

}
Loading

0 comments on commit 07f22a3

Please sign in to comment.