#!/usr/bin/python #coding:utf-8 #本文件主要用于webSocket握手协议及消息处理 import hashlib, struct, base64 #WS握手开始,socket=socket对象 msg=消息体 def shake (conn,msg): headers = {} header, data = msg.split('\r\n\r\n', 1) for line in header.split('\r\n')[1:]: key, value = line.split(": ", 1) headers[key] = value if "Host" in headers:headers["Location"] = "ws://%s/" % headers["Host"] conn.attr['type'] = 'ws' #老版本的ws协议 目主要用于兼容IOS if headers.has_key('Sec-WebSocket-Key1'): key1 = headers["Sec-WebSocket-Key1"] key2 = headers["Sec-WebSocket-Key2"] key3 = data[:8] token = creatToken(key1, key2, key3) handshake = '\ HTTP/1.1 101 Web Socket Protocol Handshake\r\n\ Upgrade: WebSocket\r\n\ Connection: Upgrade\r\n\ Sec-WebSocket-Origin: %s\r\n\ Sec-WebSocket-Location: %s\r\n\r\n\ ' %(headers['Origin'], headers['Location']) conn.attr['newVersion'] = False conn.sendDo(handshake + token) #新版本ws协议 else: key = headers['Sec-WebSocket-Key'] token = creatToken2(key) handshake = '\ HTTP/1.1 101 Switching Protocols\r\n\ Upgrade: WebSocket\r\n\ Connection: Upgrade\r\n\ Sec-WebSocket-Accept: %s\r\n\r\n\ ' % (token) conn.attr['newVersion'] = True conn.sendDo(handshake) #格式化http协议发来的消息 def parse_httprecv_data(conn,_string,callBack): #TODO解密_string raw_str = _string callBack(raw_str) #WS收到消息时,格式化消息 def parse_recv_data(conn,_string,callBack): if not 'socket_BUFF' in conn.attr: conn.attr['socket_BUFF'] = '' msg = conn.attr['socket_BUFF'] + _string if 'newVersion' in conn.attr and conn.attr['newVersion']: code_length = ord(msg[1]) & 127 if code_length == 126: msgLen = struct.unpack('>H',msg[2:4])[0] masks = msg[4:8] msgTo = 8+msgLen data = msg[8:msgTo] elif code_length == 127: msgLen = struct.unpack('>I',msg[2:6])[0] masks = msg[10:14] msgTo = 14+msgLen data = msg[14:msgTo] else: msgLen = code_length masks = msg[2:6] msgTo = 6+msgLen data = msg[6:msgTo] #数据长度不够,等待 if len(data)> 8)) back_str.append(chr(data_length & 0xFF)) back_str = "".join(back_str) + raw_str ''' else: back_str = '\x00%s\xFF' % (raw_str) return back_str #老版本WS服务器握手信息 def creatToken( key1, key2, key3): num1 = int("".join([digit for digit in list(key1) if digit.isdigit()])) spaces1 = len([char for char in list(key1) if char == " "]) num2 = int("".join([digit for digit in list(key2) if digit.isdigit()])) spaces2 = len([char for char in list(key2) if char == " "]) combined = struct.pack(">II", num1/spaces1, num2/spaces2) + key3 return hashlib.md5(combined).digest() #新版本WS服务器握手信息 def creatToken2(key): key = key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' ser_key = hashlib.sha1(key).digest() return base64.b64encode(ser_key) if __name__=='__main__': print send_data("conn", "raw_str"*50000)