/** * Build a response header * * @param $buffer * data to be used in response header * @return * response header */ static function getResponseHeaders($buffer = '', $uniqueOrigin = FALSE) { list($resource, $host, $origin, $strkey1, $strkey2, $data) = self::getRequestHeaders($buffer); if (!self::validOrigin($origin, $uniqueOrigin)) { self::console('Refusing connection from origin %s. Allowed origin(s): %s', array($origin, implode(', ', $uniqueOrigin))); return FALSE; } // find numbers $pattern = '/[^\\d]*/'; $replacement = ''; $numkey1 = preg_replace($pattern, $replacement, $strkey1); $numkey2 = preg_replace($pattern, $replacement, $strkey2); // find spaces $pattern = '/[^ ]*/'; $replacement = ''; $spaces1 = strlen(preg_replace($pattern, $replacement, $strkey1)); $spaces2 = strlen(preg_replace($pattern, $replacement, $strkey2)); if ($spaces1 == 0 || $spaces2 == 0 || $numkey1 % $spaces1 != 0 || $numkey2 % $spaces2 != 0) { WSHelpers::console('Handshake failed'); return FALSE; } $ctx = hash_init('md5'); hash_update($ctx, pack("N", $numkey1 / $spaces1)); hash_update($ctx, pack("N", $numkey2 / $spaces2)); hash_update($ctx, $data); $hash_data = hash_final($ctx, TRUE); return "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" . "Upgrade: WebSocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Origin: " . $origin . "\r\n" . "Sec-WebSocket-Location: ws://" . $host . $resource . "\r\n" . "\r\n" . $hash_data; }
/** * Shake hands with connecting user * * @param $user * The user object of the new user * @param $buffer * The received headers * @return * TRUE if successfull handshake, FALSE if not */ private final function doHandshake($user, $buffer) { WSHelpers::console("\nRequesting handshake for user %s", $user->id); if (!($upgrade = WSHelpers::getResponseHeaders($buffer, $this->config->uniqueOrigin))) { return FALSE; } socket_write($user->socket, $upgrade . chr(0), strlen($upgrade . chr(0))); $user->handshake = TRUE; WSHelpers::console('Done handshaking for user %s', $user->id); return TRUE; }