diff options
author | liris <liris.pp@gmail.com> | 2012-01-16 10:03:51 +0900 |
---|---|---|
committer | liris <liris.pp@gmail.com> | 2012-01-16 10:03:51 +0900 |
commit | aedebb7ebc4856a6e9eeb103216bbdadef81f12a (patch) | |
tree | 67904edfb224671f88bdbae193f6227d2ba6ce2c | |
parent | 0e4f65853484e734acd2ee228fd21ff03803d857 (diff) | |
download | websocket-client-aedebb7ebc4856a6e9eeb103216bbdadef81f12a.tar.gz |
- set close frame
-rw-r--r-- | websocket.py | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/websocket.py b/websocket.py index bb7d675..cc3cf8f 100644 --- a/websocket.py +++ b/websocket.py @@ -32,6 +32,20 @@ import logging VERSION = 13 +STATUS_NORMAL = 1000 +STATUS_GOING_AWAY = 1001 +STATUS_PROTOCOL_ERROR = 1002 +STATUS_UNSUPPORTED_DATA_TYPE = 1003 +STATUS_STATUS_NOT_AVAILABLE = 1005 +STATUS_ABNORMAL_CLOSED = 1006 +STATUS_INVALID_PAYLOAD = 1007 +STATUS_POLICY_VIOLATION = 1008 +STATUS_MESSAGE_TOO_BIG = 1009 +STATUS_INVALID_EXTENSION = 1010 +STATUS_UNEXPECT_CONDITION = 1011 +STATUS_TLS_HANDSHAKE_ERROR = 1015 + + logger = logging.getLogger() class WebSocketException(Exception): @@ -190,6 +204,7 @@ class ABNF(object): def create_frame(data, opcode): if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode): data = data.encode("utf-8") + # mask must be set if send data from client return ABNF(1, 0, 0, 0, opcode, 1, data) def format(self): @@ -405,17 +420,25 @@ class WebSocket(object): """ Receive utf-8 string data from the server. """ + opcode, data = self.recv_data() + return data + + def recv_data(self): while True: frame = self.recv_frame() if frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY): - return frame.data + return (frame.opcode, frame.data) elif frame.opcode == ABNF.OPCODE_CLOSE: + self.send_close() return None elif frame.opcode == ABNF.OPCODE_PING: self.pong("Hi!") + def recv_frame(self): header_bytes = self._recv(2) + if not header_bytes: + return None b1 = ord(header_bytes[0]) fin = b1 >> 7 & 1 rsv1 = b1 >> 6 & 1 @@ -443,20 +466,30 @@ class WebSocket(object): frame = ABNF(fin, rsv1, rsv2, rsv3, opcode, mask, data) return frame + def send_close(self, status = STATUS_NORMAL, reason = ""): + if status < 0 or status > ABNF.LENGTH_16: + raise ValueError("code is invalid range") + self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE) + - def close(self): + + def close(self, status = STATUS_NORMAL, reason = ""): """ Close Websocket object """ if self.connected: + if status < 0 or status > ABNF.LENGTH_16: + raise ValueError("code is invalid range") + try: - self.send("bye", ABNF.OPCODE_CLOSE) + self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE) timeout = self.sock.gettimeout() - self.sock.settimeout(1) + self.sock.settimeout(3) try: - result = self._recv(2) - if result != "\xff\x00": - logger.error("bad closing Handshake") + frame = self.recv_frame() + print repr(frame.data) + if logger.isEnabledFor(logging.DEBUG): + logger.error("close status: " + repr(frame.data)) except: pass self.sock.settimeout(timeout) |