requestedResource = $headers['get']; } else { // todo: fail the connection $handshakeResponse = "HTTP/1.1 405 Method Not Allowed\r\n\r\n"; } if (!isset($headers['host']) || !$this->checkHost($headers['host'])) { $handshakeResponse = "HTTP/1.1 400 Bad Request"; } if (!isset($headers['upgrade']) || strtolower($headers['upgrade']) != 'websocket') { $handshakeResponse = "HTTP/1.1 400 Bad Request"; } if (!isset($headers['connection']) || strpos(strtolower($headers['connection']), 'upgrade') === FALSE) { $handshakeResponse = "HTTP/1.1 400 Bad Request"; } if (!isset($headers['sec-websocket-key'])) { $handshakeResponse = "HTTP/1.1 400 Bad Request"; } else { } if (!isset($headers['sec-websocket-version']) || strtolower($headers['sec-websocket-version']) != 13) { $handshakeResponse = "HTTP/1.1 426 Upgrade Required\r\nSec-WebSocketVersion: 13"; } if (($this->headerOriginRequired && !isset($headers['origin']) ) || ($this->headerOriginRequired && !$this->checkOrigin($headers['origin']))) { $handshakeResponse = "HTTP/1.1 403 Forbidden"; } if (($this->headerSecWebSocketProtocolRequired && !isset($headers['sec-websocket-protocol'])) || ($this->headerSecWebSocketProtocolRequired && !$this->checkWebsocProtocol($header['sec-websocket-protocol']))) { $handshakeResponse = "HTTP/1.1 400 Bad Request"; } if (($this->headerSecWebSocketExtensionsRequired && !isset($headers['sec-websocket-extensions'])) || ($this->headerSecWebSocketExtensionsRequired && !$this->checkWebsocExtensions($header['sec-websocket-extensions']))) { $handshakeResponse = "HTTP/1.1 400 Bad Request"; } // Done verifying the _required_ headers and optionally required headers. if (isset($handshakeResponse)) { socket_write($user->socket,$handshakeResponse,strlen($handshakeResponse)); $this->disconnect($user->socket); return false; } $user->headers = $headers; $user->handshake = $buffer; $webSocketKeyHash = sha1($headers['sec-websocket-key'] . $magicGUID); $rawToken = ""; for ($i = 0; $i < 20; $i++) { $rawToken .= chr(hexdec(substr($webSocketKeyHash,$i*2, 2))); } $handshakeToken = base64_encode($rawToken) . "\r\n"; $subProtocol = (isset($headers['sec-websocket-protocol'])) ? $this->processProtocol($headers['sec-websocket-protocol']) : ""; $extensions = (isset($headers['sec-websocket-extensions'])) ? $this->processExtensions($headers['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"; socket_write($user->socket,$handshakeResponse,strlen($handshakeResponse)); $this->connected($user); } function init($enc, $header, &$header_out, $init_string, $base, $step) { $ret = sprintf("@BEGIN@ /* %s */ @END@", $init_string); if ($enc != 'plain') $header_out['Content-Encoding'] = $enc; $header_out['Cache-Control'] = 'no-cache, must-revalidate'; // HTTP/1.1 $header_out['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; // Date in the past $header_out['Content-type'] = 'application/xml; charset="utf-8"'; return ($ret); } static function fini($init_string, $base, $blockerr) { return (sprintf('@BEGIN@ %s window.onbeforeunload = null; window.onunload = null; document.location.assign("%sindex.php"); @END@', ($blockerr ? 'xstm.stop(); ' : ''), $base)); return (""); } function chunk($step, $cont) { return ("@BEGIN@".$cont."@END@"); } } class Transport_xhr { function Transport_xhr() { } function init($enc, $header, &$header_out, $init_string, $base, $step) { $ret = sprintf("@BEGIN@ /* %s */ @END@", $init_string); if ($enc != 'plain') $header_out['Content-Encoding'] = $enc; $header_out['Cache-Control'] = 'no-cache, must-revalidate'; // HTTP/1.1 $header_out['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; // Date in the past $header_out['Content-type'] = 'application/xml; charset="utf-8"'; return ($ret); } static function fini($init_string, $base, $blockerr) { return (sprintf('@BEGIN@ %s window.onbeforeunload = null; window.onunload = null; document.location.assign("%sindex.php"); @END@', ($blockerr ? 'xstm.stop(); ' : ''), $base)); return (""); } function chunk($step, $cont) { return ("@BEGIN@".$cont."@END@"); } function is_chunked() { return TRUE; } } class Transport_iframe { function Transport_iframe() { } function init($enc, $header, &$header_out, $init_string, $base, $step) { $ret = ""; if ($enc != 'plain') $header_out['Content-Encoding'] = $enc; $header_out['Cache-Control'] = 'no-cache, must-revalidate'; // HTTP/1.1 $header_out['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; // Date in the past $header_out['Content-type'] = 'text/html; charset="utf-8"'; $ret .= sprintf(" "); $ret .= sprintf("\n", $init_string); return ($ret); } static function fini($init_string, $base, $blockerr) { $ret = ""; $ret .= sprintf(" "); $ret .= sprintf("\n", $init_string); $ret .= sprintf("", 0, escpush($blockerr) ); return ($ret); } function chunk($step, $cont) { if ($cont == NULL) { return sprintf("", $step); } else { return sprintf("", $step, escpush($cont) ); } } function is_chunked() { return TRUE; } } class Transport_htmlfile extends Transport_iframe { } class Transport { function Transport() { } static function create($transp) { if ($transp == 'xhr') { return new Transport_xhr(); } else if ($transp == 'htmlfile') { return new Transport_htmlfile(); } else { return new Transport_iframe(); } } static function gettype($transp) { if ($transp == 'xhr' || $transp == 'htmlfile') { return "Transport_".$transp; } else { return 'Transport_iframe'; } } } ?>