- set close frame
This commit is contained in:
47
websocket.py
47
websocket.py
@@ -32,6 +32,20 @@ import logging
|
|||||||
|
|
||||||
VERSION = 13
|
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()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
class WebSocketException(Exception):
|
class WebSocketException(Exception):
|
||||||
@@ -190,6 +204,7 @@ class ABNF(object):
|
|||||||
def create_frame(data, opcode):
|
def create_frame(data, opcode):
|
||||||
if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode):
|
if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode):
|
||||||
data = data.encode("utf-8")
|
data = data.encode("utf-8")
|
||||||
|
# mask must be set if send data from client
|
||||||
return ABNF(1, 0, 0, 0, opcode, 1, data)
|
return ABNF(1, 0, 0, 0, opcode, 1, data)
|
||||||
|
|
||||||
def format(self):
|
def format(self):
|
||||||
@@ -405,17 +420,25 @@ class WebSocket(object):
|
|||||||
"""
|
"""
|
||||||
Receive utf-8 string data from the server.
|
Receive utf-8 string data from the server.
|
||||||
"""
|
"""
|
||||||
|
opcode, data = self.recv_data()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def recv_data(self):
|
||||||
while True:
|
while True:
|
||||||
frame = self.recv_frame()
|
frame = self.recv_frame()
|
||||||
if frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY):
|
if frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY):
|
||||||
return frame.data
|
return (frame.opcode, frame.data)
|
||||||
elif frame.opcode == ABNF.OPCODE_CLOSE:
|
elif frame.opcode == ABNF.OPCODE_CLOSE:
|
||||||
|
self.send_close()
|
||||||
return None
|
return None
|
||||||
elif frame.opcode == ABNF.OPCODE_PING:
|
elif frame.opcode == ABNF.OPCODE_PING:
|
||||||
self.pong("Hi!")
|
self.pong("Hi!")
|
||||||
|
|
||||||
|
|
||||||
def recv_frame(self):
|
def recv_frame(self):
|
||||||
header_bytes = self._recv(2)
|
header_bytes = self._recv(2)
|
||||||
|
if not header_bytes:
|
||||||
|
return None
|
||||||
b1 = ord(header_bytes[0])
|
b1 = ord(header_bytes[0])
|
||||||
fin = b1 >> 7 & 1
|
fin = b1 >> 7 & 1
|
||||||
rsv1 = b1 >> 6 & 1
|
rsv1 = b1 >> 6 & 1
|
||||||
@@ -443,20 +466,30 @@ class WebSocket(object):
|
|||||||
frame = ABNF(fin, rsv1, rsv2, rsv3, opcode, mask, data)
|
frame = ABNF(fin, rsv1, rsv2, rsv3, opcode, mask, data)
|
||||||
return frame
|
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
|
Close Websocket object
|
||||||
"""
|
"""
|
||||||
if self.connected:
|
if self.connected:
|
||||||
|
if status < 0 or status > ABNF.LENGTH_16:
|
||||||
|
raise ValueError("code is invalid range")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.send("bye", ABNF.OPCODE_CLOSE)
|
self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE)
|
||||||
timeout = self.sock.gettimeout()
|
timeout = self.sock.gettimeout()
|
||||||
self.sock.settimeout(1)
|
self.sock.settimeout(3)
|
||||||
try:
|
try:
|
||||||
result = self._recv(2)
|
frame = self.recv_frame()
|
||||||
if result != "\xff\x00":
|
print repr(frame.data)
|
||||||
logger.error("bad closing Handshake")
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
|
logger.error("close status: " + repr(frame.data))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.sock.settimeout(timeout)
|
self.sock.settimeout(timeout)
|
||||||
|
Reference in New Issue
Block a user