Author Topic: websockets and woe - lugnut's mission to create html5 websockets - still broked  (Read 3371 times)

But here's my input: This is not going to work. It is perfectly possible for sha1 to output a 0x00 (NUL) byte. Collapsing the hex "00" is going to result in a NUL byte in the string, and we all know how Torque loves that. You'll end up getting a shortened form of the actual sha1 (cuts off the NUL byte and everything beyond it) which will output malformed base64.

This is true, but if he's going to encounter 00's then he can just do something like this:

Code: [Select]
function convertWebkey(%key)
{
%sha = sha1(%key);
%len = strLen(%sha);

for(%i = 0; %i < %len; %i += 2)
%str = %str SPC convertBase(getSubStr(%sha,%i,2),"0123456789ABCDEF","0123456789");

%str = trim(%str);
%b64 = base64Encode_Nulls(%str);

return %b64;
}

function base64Encode_Nulls(%str)
{
%base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

%len = getWordCount(%str);

for(%i = 0; %i < %len; %i++)
{
%ascii = getWord(%str,%i);
%bin   = convertBase(%ascii,"0123456789","01");

while(strLen(%bin) < 8)
%bin = "0" @ %bin;

%all = %all @ %bin;
}

%len = strLen(%all);

for(%i = 0; %i < %len; %i += 6)
{
%pack = getSubStr(%all,%i,6);

while(strLen(%pack) < 6)
%pack = %pack @ "0";

%dec = convertBase(%pack,"01","0123456789");
%new = %new @ getSubStr(%base64map,%dec,1);
}

while(strLen(%new) % 4 > 0)
%new = %new @ "=";

return %new;
}

I could make a php base 64 encoder for you to use with sha1, I have a website I can do that on.
there are default functions for this lol


so, i went with option d and made the following.

<?php
	
if(
$_GET["i"] !== "")
	
{
	
	
$_GET["i"] = $_GET["i"] . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
	
	
$i sha1($_GET["i"], true); // http://php.net/manual/en/function.sha1.php
	
	
$o base64_encode($i);
	
	
echo 
$o;
	
}
?>

Code: (ws.cs) [Select]
// websockets code

if(!isObject(WebSocketClients))
new SimSet(WebSocketClients);

function Webclient::startWSResponse(%this)
{
%this.http = new httpObject()
{
classes = "WebSocketHttp";
isDone = false;
};

// %this.http.get("zombiesinthebluzone.co.cc:80", "/websocket.php?i=" @ $_SERVERHTTP_Sec_WebSocket_Key);
%this.http.get("localhost:80", "/websocket.php?i=" @ $_SERVERHTTP_Sec_WebSocket_Key);

%this.sched = %this.schedule(50, checkWSResponse);
}

function Webclient::finishWSResponse(%this)
{
%rkey = %this.http.stuff;

%this.http.stuff = "";

%this.send("HTTP/1.1 101 Switching Protocols\r\n");
%this.send("Upgrade: websocket\r\n");
%this.send("Connection: Upgrade\r\n");
%this.send("Sec-WebSocket-Accept: " @ %rkey @ "\r\n");
%this.send("\r\n");

%this.isWebSocket = 1;

WebSocketClients.add(%this);
}

function Webclient::checkWSResponse(%this)
{
cancel(%this.sched);

if(%this.http.isDone)
{
%this.finishWSResponse();
}
else
{
%this.sched = %this.schedule(150, checkWSResponse);
}
}

package webSockets
{
function httpObject::onLine(%this, %line)
{
parent::onLine(%this, %line);

if(%this.classes !$= "WebSocketHttp")
return;

%this.stuff = %this.stuff @ %line;
%this.isDone = true;

}
};
activatePackage("webSockets");

some of the code is obviously formatted for local testing.
there was a major error where the system.. well, didn't work. however, in looking this over to post it might've found the error.


I edited the code with my final copy. It is fully functional, and the connections to the websocket is successful, no errors.
Websocket>server stuff will be handled via Webclient::onLine with an if() check to determine if %this.isWebSocket.
server>websocket stuff will probably be handled by looping through the objects in the WebSocketClients simset along with those little variables like methods. you know, %this.isStuff = blah;.

thanks for all your help, guys!

only problem i'm seeing is a super-duper long response time when calculating the response key
i mean, yeah it'll take longer than local processing, but we're talking like 2-3 seconds here, and this is all happening locally!
« Last Edit: August 30, 2012, 06:00:46 PM by Lugnut »

so, i went with option d and made the following.

-snip-

only problem i'm seeing is a super-duper long response time when calculating the response key
i mean, yeah it'll take longer than local processing, but we're talking like 2-3 seconds here, and this is all happening locally!

What was wrong with the last bit of code I posted? It should convert to the webkey just fine in Torque.
That way you don't have to deal with the extra delay every single time you want to output the key.

my apologies, I didn't try your method yet cause I was getting mine working

I'll try it soon and post results
« Last Edit: August 31, 2012, 12:28:26 AM by Lugnut »

okay so i put truce's latest code into web.cs and the dumb thing started loving working

no magical a, b, c, or d

rigged up a test webpage and simple processor and discovered the dumb little thing has custom headers on every message sent to server and to client

dammit
http://www.w3.org/TR/websockets/#the-websocket-interface

reading. will post results probably

it appears my problem is it converts messages to unicode?

Write WebSocket server code
Server code that handles sockets can be written in any server language. Whatever language you choose, you must write code that accepts WebSocket requests and processes them appropriately.
wow, no loving stuff microsoft


I can't find a definitive example of a simple 'hello world' exchange between client and server to brown townyze for the... syntax of the transaction, so i'll just boot up wireshark and try that way.
checked reddit before i went to all that trouble and found these. they'll probably be useful for anyone looking to figure this out after me.

http://www.reddit.com/r/websocket
http://updates.html5rocks.com/2012/05/Websocket-Frame-Inspection-now-in-Chrome-DevTools


it must be too late at night or something but i can't figure this stuff out.

the test webpage is here: 69.64.43.11:33580/websocket.tqs
latest code is nothing special
Code: (Webclient::finish()) [Select]
if($_SERVERHTTP_Connection $= "Upgrade" && $_SERVERHTTP_UPGRADE $= "websocket")
{
// recho("> Upgrading connection to websocket.");
echo("> Upgrading connection to websocket.");

%rkey = convertWebkey($_SERVERHTTP_Sec_WebSocket_Key @ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");

// recho("sending string " @ %rkey);
echo("sending string " @ %rkey);

%this.send("HTTP/1.1 101 Switching Protocols\r\n");
%this.send("Upgrade: websocket\r\n");
%this.send("Connection: Upgrade\r\n");
%this.send("Sec-WebSocket-Accept: " @ %rkey @ "\r\n");
%this.send("\r\n");

%this.isWebSocket = 1;

if(!isObject(WebSocketClients))
new SimSet(WebSocketClients);

WebSocketClients.add(%this);

return;
}
Code: (Webclient::onLine()) [Select]
function Webclient::onLine(%this,%line)
{
cancel(%this.timeout);

if(%this.isWebSocket)
{
echo("found websocket line");
%this.onWebSocketLine(%line);
return;
}
// more code after this, this is the relevant stuff and a little bit of bearings
Code: (Webclient::onWebSocketLine()) [Select]
function Webclient::onWebSocketLine(%this, %line)
{
echo("Websocket Received data:" @ %line);
%this.send("Echo:" SPC %line);
}


it appears there are special headers that are supposed to accompany every message
i haven't delved into the open source code of relevant projects yet, but that's next on my list unless someone can provide some insight.
« Last Edit: August 31, 2012, 03:10:40 AM by Lugnut »