/**
  * Gets the correct messagetype value, based on the current connection object
  * @param \System\Web\Websocket\Connection The connection object
  * @param int The requested messagetype
  * @return int The messagetype value
  */
 public static function getMessageType(\System\Web\Websocket\Connection $connection, $messageType)
 {
     switch ($messageType) {
         case self::TYPE_TEXT:
             return $connection->isSendingContinuous() ? 0 : self::TYPE_TEXT;
         case self::TYPE_BINARY:
             return $connection->isSendingContinuous() ? 0 : self::TYPE_BINARY;
         default:
             return $messageType;
     }
 }
Exemple #2
0
 /**
  * Performs the handshake between the client and the server. Also checks if
  * the client is allowed to connect based on its credentials and properties
  * @param \System\Web\Websocket\Connection The connection to initiate
  * @param string The buffer
  */
 private function doHandshake(\System\Web\Websocket\Connection $connection, $buffer)
 {
     $requestHeaders = array();
     $lines = explode("\n", $buffer);
     foreach ($lines as $line) {
         //the response to send to the client
         $response = '';
         if (strpos($line, ':') !== false) {
             $headerLine = explode(':', $line, 2);
             $requestHeaders[strtolower(trim($headerLine[0]))] = trim($headerLine[1]);
         } elseif (stripos($line, 'get') !== false) {
             preg_match("/GET (.*) HTTP/i", $buffer, $requestResource);
             $requestHeaders['get'] = trim($requestResource[1]);
         }
     }
     if (isset($requestHeaders['get'])) {
         $connection->setRequestedResource($requestHeaders['get']);
     } else {
         $response = self::HTTP_METHOD_NOT_ALLOWED;
     }
     if (!isset($requestHeaders['host']) || !$this->hostAllowed($requestHeaders['host'])) {
         $response = self::HTTP_BAD_REQUEST;
     }
     if (!isset($requestHeaders['upgrade']) || strtolower($requestHeaders['upgrade']) != 'websocket') {
         $response = self::HTTP_BAD_REQUEST;
     }
     if (!isset($requestHeaders['connection']) || strpos(strtolower($requestHeaders['connection']), 'upgrade') === false) {
         $response = self::HTTP_BAD_REQUEST;
     }
     if (!isset($requestHeaders['sec-websocket-key'])) {
         $response = self::HTTP_BAD_REQUEST;
     }
     if (!isset($requestHeaders['sec-websocket-version']) || strtolower($requestHeaders['sec-websocket-version']) != 13) {
         $response = self::HTTP_UPGRADE_REQUIRED;
     }
     if ($this->getHeaderOriginRequired() && !isset($requestHeaders['origin']) || $this->getHeaderOriginRequired() && !$this->originAllowed($requestHeaders['origin'])) {
         $response = self::HTTP_FORBIDDEN;
     }
     if ($this->getHeaderSecWebSocketProtocolRequired() && !isset($requestHeaders['sec-websocket-protocol']) || $this->getHeaderSecWebSocketProtocolRequired() && !$this->websocketProtocolAllowed($requestHeaders['sec-websocket-protocol'])) {
         $response = "HTTP/1.1 400 Bad Request";
     }
     if ($this->getHeaderSecWebSocketExtensionsRequired() && !isset($requestHeaders['sec-websocket-extensions']) || $this->getHeaderSecWebSocketExtensionsRequired() && !$this->websocketExtensionsAllowed($requestHeaders['sec-websocket-extensions'])) {
         $response = "HTTP/1.1 400 Bad Request";
     }
     if (!empty($response)) {
         if (@socket_write($connection->getSocket(), $response, strlen($response)) === false) {
             $this->handleSocketError(false);
         }
         $this->disconnect($connection->getSocket());
         return;
     }
     $connection->setHeaders($requestHeaders);
     $connection->setHandshake($buffer);
     $websocketKeyHash = sha1($requestHeaders['sec-websocket-key'] . self::WEBSOCKET_GUID);
     $rawToken = '';
     for ($i = 0; $i < 20; $i++) {
         $rawToken .= chr(hexdec(substr($websocketKeyHash, $i * 2, 2)));
     }
     $handshakeToken = base64_encode($rawToken) . "\r\n";
     $subProtocol = isset($requestHeaders['sec-websocket-protocol']) ? $this->processProtocol($requestHeaders['sec-websocket-protocol']) : "";
     $extensions = isset($requestHeaders['sec-websocket-extensions']) ? $this->processExtensions($requestHeaders['sec-websocket-extensions']) : "";
     $handshakeResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {$handshakeToken}{$subProtocol}{$extensions}\r\n";
     if (@socket_write($connection->getSocket(), $handshakeResponse, strlen($handshakeResponse)) === false) {
         $this->handleSocketError(false);
         $this->disconnect($connection->getSocket());
     } else {
         $onConnectedEvent = new \System\Web\Websocket\Event\OnConnectedEvent();
         $onConnectedEvent->setServer($this);
         $onConnectedEvent->setConnection($connection);
         $onConnectedEvent->raise();
     }
 }