Saturday, May 21, 2011

Websocket Server (Blitz Max)

I am writing a server in blitzmax that can handle WebSocket traffic from a web browser.

I am having trouble with the security handshake.  I have gotten pretty far but need a little help.  I don't think the security key response I generate is correct.  So if anyone is feeling charitable...  If you do not use Blitz Max have a look anyways, its pretty easy to understand.  The problem isn't heavily language specific.


General Websocket info.
BlitzMax Reference (if you need it)

The handshake specification will change, but for right now chrome is using this spec: draft-ietf-hybi-thewebsocketprotocol-00

The abstract for processing the security handshake is on page 8.  I am unsure about the Big Endian comment.  Also, I am not sure if I am handling the 3rd Ascii key thing right.

My Blitz Max functions that process the security response:

'Function for Processing Websocket Keys
'Specification: -- draft-ietf-hybi-thewebsocketprotocol-00 --
'(will have To be kept up to date with spec)
'Also see Functions psk1() And psk3()
'-------------------------------------------------------------
Function process_security_key:String(key1:String,key2:String,key3:String)

    key1 = psk1(key1)
    key2 = psk1(key2)
    key3 = psk3(key3)
   
    response_key = key1 + key2 + key3
    response_key = md5:String(response_key)
   
    Return response_key

EndFunction 


'Auth 1 & 2
'(processes Keys 1 and 2)
'---------
Function psk1:String(key:String)

    Local slicer:String
    Local spacecounter:Int
       
    For Local i:Int=0 To key.length
   
        slicer = Left$( key,1 )
        key = Right( key,(key.length-1) )
   
        If slicer = " "
            spacecounter = spacecounter + 1
        EndIf
       
        For Local t:String=EachIn hd_arr
              If slicer = t
                key = key + t
                Trim(key)
            EndIf    
        Next
    Next
   
    Return ( Long(key:String) / Int(spacecounter) )

EndFunction

'Auth 3
'(processes Key 3)
'---------
Function psk3:String(key:String)

    Local k:String
   
    For Local p:Int=1 To key.length
        k = k + Asc(key)
        key = Right(key,key.length - 1)
    Next
   
    Return k
   
EndFunction

Examples of what I am receiving from my web client and what my blitz program is outputting 
(not sure if all ascii will show on blog) 

----------------- Server Started -----------------


-------------- New Client Connection --------------
 - IP:127.0.0.1
 - Port:50672

---------- Messaged Reclieved From Client: ----------
 - IP:127.0.0.1
 - Port:50672

-------- Recieved Message --------
GET / HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: localhost:1400
Origin: http://www.solid6ix.com
Sec-WebSocket-Key1: 376*69R~Bu05   J0y"~9  < . B3
Sec-WebSocket-Key2: 328 0 6  '4o k ^85  E4 5

øU D—Æ–Q

---------- Sent Message ----------
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://www.solid6ix.com
Sec-WebSocket-Location: /
a3417c94bd161719b8060fc4aec59f1c