diff --git a/.gitignore b/.gitignore index f025940..6e528f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp *~ *.pyc +build diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..5c1b0dd --- /dev/null +++ b/example/index.html @@ -0,0 +1,20 @@ + + + + Web Socket Example + + + + +
+
+ + + diff --git a/example/test.py b/example/test.py index ecec000..6976ad5 100644 --- a/example/test.py +++ b/example/test.py @@ -4,7 +4,7 @@ class myClass: def __init__(self): self.msg = '' - def _onRecieve(self, msg): + def onReceive(self, msg): print 'Msg printed from my Custom Class ' print msg #return "Response", 1 # if I want to send something to the server diff --git a/simpleWSpy/server/WebSocketServer.py b/simpleWSpy/server/WebSocketServer.py index f3df1bb..74a9e6a 100644 --- a/simpleWSpy/server/WebSocketServer.py +++ b/simpleWSpy/server/WebSocketServer.py @@ -3,15 +3,15 @@ class WebSocket: - # initiatin the connection ... - def __init__(self, aConnection): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.bind(aConnection) - self.sock.listen(1) - self.conn = None - self.addr = None - self.stream = '' - self.header = '\ + # initiatin the connection ... + def __init__(self, aConnection): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.bind(aConnection) + self.sock.listen(1) + self.conn = None + self.addr = None + self.stream = '' + self.header = '\ HTTP/1.1 101 Web Socket Protocol Handshake\r\n\ Upgrade: WebSocket\r\n\ Connection: Upgrade\r\n\ @@ -20,85 +20,129 @@ def __init__(self, aConnection): ' % aConnection - # Sending messages : - def sendMSG(self, aMsg): - self.conn.send(aMsg) - - # Receiving message , the default size is 1024 - def recvMSG(self, aSize = 1024): - self.stream = self.conn.recv(aSize) - return self.stream - - # Execute the handshake protocole. - def genAcceptKey(self, aClientWSHeader): - headerInfos = aClientWSHeader.split('\r\n') - body = aClientWSHeader.split('\r\n\r\n')[1] - key = '' - cc = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' - # Extracting the request handshake key from the header - for hi in headerInfos: - if hi.startswith('Sec-WebSocket-Key:'): - key = hi[19:] - else: - continue - - # Generating the handshake key to tell client that we accept it's request - import hashlib - import base64 - sha = hashlib.sha1() - sha.update(key+cc) - hashed = sha.digest() - return base64.b64encode(hashed) - - # Executing the handshake protocol. - def handShake(self, clientWSHeader): + # Sending messages : + def sendMSG(self, aMsg): + self.conn.send(aMsg) + + # Receiving message , the default size is 1024 + def recvMSG(self, aSize = 1024): + self.stream = self.conn.recv(aSize) + return self.stream + + # Execute the handshake protocole. + def genAcceptKey(self, aClientWSHeader): + headerInfos = aClientWSHeader.split('\r\n') + body = aClientWSHeader.split('\r\n\r\n')[1] + key = '' + cc = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' + # Extracting the request handshake key from the header + for hi in headerInfos: + if hi.startswith('Sec-WebSocket-Key:'): + key = hi[19:] + else: + continue + + # Generating the handshake key to tell client that we accept it's request + import hashlib + import base64 + sha = hashlib.sha1() + sha.update(key+cc) + hashed = sha.digest() + return base64.b64encode(hashed) + + # Executing the handshake protocol. + def handShake(self, clientWSHeader): #clientWSHeader = self.recvMSG(4094) - serverWSHeader = self.header - serverWSHeader += 'Sec-WebSocket-Accept:'+ str(self.genAcceptKey(clientWSHeader)) + '\r\n\r\n' - self.sendMSG(serverWSHeader) - - # Decode the stream: - def decodeStream(self): - encodedStream = self.stream - # convert the string into numeric values - byteStream = [ord(char) for char in encodedStream] - # decode the data length: - dLength = byteStream[1] & 127 - iFirstMask = 2 #default index fist mask - if dLength == 126: # 2 bytes are used for length - iFirstMask = 4 - elif dLength == 127: # 8 bytes are used for length - iFirstMask = 10 - - masks = [m for m in byteStream[iFirstMask: iFirstMask+4]] - iFirstDataByte = iFirstMask + 4 - decodedStream = [] - i = iFirstDataByte - j = 0 - - while i < len(byteStream): - decodedStream.append(chr(byteStream[i] ^ masks[j % 4])) - i += 1 - j += 1 - - return ''.join(decodedStream) + serverWSHeader = self.header + serverWSHeader += 'Sec-WebSocket-Accept:'+ str(self.genAcceptKey(clientWSHeader)) + '\r\n\r\n' + self.sendMSG(serverWSHeader) + + # Decode the stream: + def decodeStream(self): + encodedStream = self.stream + # convert the string into numeric values + byteStream = [ord(char) for char in encodedStream] + # decode the data length: + dLength = byteStream[1] & 127 + iFirstMask = 2 #default index fist mask + if dLength == 126: # 2 bytes are used for length + iFirstMask = 4 + elif dLength == 127: # 8 bytes are used for length + iFirstMask = 10 + + masks = [m for m in byteStream[iFirstMask: iFirstMask+4]] + iFirstDataByte = iFirstMask + 4 + decodedStream = [] + i = iFirstDataByte + j = 0 + + while i < len(byteStream): + decodedStream.append(chr(byteStream[i] ^ masks[j % 4])) + i += 1 + j += 1 + + return ''.join(decodedStream) + def encodeStream(self, aMsg): + decodedStream = aMsg + dLength = len(decodedStream) + + frame = [] + frame.append(129) + + if dLength <= 125: + frame.append(dLength) + elif dLength >= 126 and dLength <= 65535: + frame.append(126) + frame.append((dLength >> 8 ) & 255) + frame.append(dLength & 255) + else: + frame.append(127) + frame.append((dLength >> 56) & 255) + frame.append((dLength >> 48) & 255) + frame.append((dLength >> 40) & 255) + frame.append((dLength >> 32) & 255) + frame.append((dLength >> 24) & 255) + frame.append((dLength >> 16) & 255) + frame.append((dLength >> 8) & 255) + frame.append(dLength & 255) + + + i = 0 + while i < dLength: + frame.append(ord(decodedStream[i])) + i = i+1 + + buffer = [ chr(byte) for byte in frame] + return ''.join(buffer) + - # Serve forever ... - def serve_forever(self, aCustomClass, aSize = 1024): - while True: - self.conn, self.addr = self.sock.accept() - msg = self.recvMSG(4096) - if(msg): - self.handShake(msg) - print 'Accepted !' - while True: - msg = self.recvMSG(aSize) - if(msg): - msgToSend, wantToSend = aCustomClass._onRecieve(self.decodeStream()) - if(wantToSend): - continue #Send is not supported yet +# Serve forever ... + def serve_forever(self, aCustomClass, aSize = 1024): + self.conn, self.addr = self.sock.accept() + while True: + msg = self.recvMSG(4096) + if(msg): + self.handShake(msg) + print 'Connection established with client : %s:%d' % self.addr + while True: + msg = self.recvMSG(aSize) + if(msg): + msgToSend, wantToSend = aCustomClass.onReceive(self.decodeStream()) + if(wantToSend): + bff = self.encodeStream(msgToSend) + self.sendMSG(bff+'\r\n') + # Client disconnected + elif (not msg): + break + break + + # We close the actual connection and get ready for a new one. + self.conn.close() + self.serve_forever(aCustomClass, aSize) + +