*
*/
+/*
+ * test: SO x Browser
+ * Values: Y: works, N: not works, @: continuous download,
+ * D: continuous download after first reload
+ *
+ * Stream IFRAME:
+ *
+ * Iframe| IW | FF | Ch | Op | Ko | IE
+ * ------+----+----+----+----+----+----
+ * Lnx | D | | @ | | @ | x
+ * Win | x | D | @ | @ | | D
+ * Mac | x | | | | |
+ *
+ *
+ * XHR | IW | FF | Ch | Op | Ko | IE
+ * ------+----+----+----+----+----+----
+ * Lnx | Y | | ^D | | Y | x
+ * Win | x | Y | Y | | | N
+ * Mac | x | | | | |
+ *
+ *
+ * HtmlFl| IW | FF | Ch | Op | Ko | IE
+ * ------+----+----+----+----+----+----
+ * Lnx | N | | | | N |
+ * Win | x | N | N | | | Y* (* seems delay between click and load of a new page)
+ * Mac | x | | | | |
+ *
+ *
+ */
+
+
class Transport_template {
function Transport_template() {
}
- function init($enc, &$header_out, $init_string, $base, $step)
+ // return string value is appended to the content of the returned page
+ function init($enc, $header, &$header_out, $init_string, $base, $step)
{
}
}
}
+class Transport_websocket {
+ $magicGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+ function Transport_websocket() {
+ }
+
+ protected function doHandshake($user, $buffer) {
+ $magicGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ $headers = array();
+ $lines = explode("\n",$buffer);
+ foreach ($lines as $line) {
+ if (strpos($line,":") !== false) {
+ $header = explode(":",$line,2);
+ $headers[strtolower(trim($header[0]))] = trim($header[1]);
+ } else if (stripos($line,"get ") !== false) {
+ preg_match("/GET (.*) HTTP/i", $buffer, $reqResource);
+ $headers['get'] = trim($reqResource[1]);
+ }
+ }
+ if (isset($headers['get'])) {
+ $user->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_out, $init_string, $base, $step)
+ function init($enc, $header, &$header_out, $init_string, $base, $step)
{
$ret = sprintf("@BEGIN@ /* %s */ @END@", $init_string);
if ($enc != 'plain')
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 Transport_iframe() {
}
- function init($enc, &$header_out, $init_string, $base, $step)
+ function init($enc, $header, &$header_out, $init_string, $base, $step)
{
$ret = "";
if ($step > 0)
$ret .= sprintf("last_clean = %d;\n", ($step-1));
$ret .= sprintf("
-window.onload = function () { if (xynt_streaming != \"ready\") { xynt_streaming.transp.stopped = true; } };
+window.onload = function () { try { if (xynt_streaming != \"ready\") { xynt_streaming.transp.stopped = true; } } catch(e) { /* console.log(\"catcha\"); */ } };
</script>
</head>
<body>");
<script type=\"text/javascript\">
var xynt_streaming = \"ready\";", $base, $base);
$ret .= sprintf("
-window.onload = function () { if (xynt_streaming != \"ready\") { xynt_streaming.reload(); } };
+window.onload = function () { try { if (xynt_streaming != \"ready\") { xynt_streaming.reload(); } } catch(e) { /* console.log(\"catcha\"); */ } };
</script>
</head>
<body>");
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';
+ }
+ }
+}
?>
\ No newline at end of file