Skip to content

Commit 0ed0b7e

Browse files
author
chenyan
committed
continuation_frames_support
1 parent ae6ee7f commit 0ed0b7e

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

websocket_server/websocket_server.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ def __init__(self, port, host='127.0.0.1', loglevel=logging.WARNING):
124124
self.port = self.socket.getsockname()[1]
125125

126126
def _message_received_(self, handler, msg):
127-
self.message_received(self.handler_to_client(handler), self, msg)
127+
self.message_received(self.handler_to_client(handler), self, msg.decode())
128128

129129
def _ping_received_(self, handler, msg):
130-
handler.send_pong(msg)
130+
handler.send_pong(msg.decode())
131131

132132
def _pong_received_(self, handler, msg):
133133
pass
@@ -172,6 +172,8 @@ def setup(self):
172172
self.keep_alive = True
173173
self.handshake_done = False
174174
self.valid_client = False
175+
self.fragment_opcode = 0
176+
self.fragment_payload_buf = bytearray()
175177

176178
def handle(self):
177179
while self.keep_alive:
@@ -214,34 +216,46 @@ def read_next_message(self):
214216
logger.warn("Client must always be masked.")
215217
self.keep_alive = 0
216218
return
217-
if opcode == OPCODE_CONTINUATION:
218-
logger.warn("Continuation frames are not supported.")
219-
return
220-
elif opcode == OPCODE_BINARY:
219+
if opcode == OPCODE_BINARY:
221220
logger.warn("Binary frames are not supported.")
222221
return
223-
elif opcode == OPCODE_TEXT:
224-
opcode_handler = self.server._message_received_
225-
elif opcode == OPCODE_PING:
226-
opcode_handler = self.server._ping_received_
227-
elif opcode == OPCODE_PONG:
228-
opcode_handler = self.server._pong_received_
229-
else:
230-
logger.warn("Unknown opcode %#x." % opcode)
231-
self.keep_alive = 0
232-
return
233222

234223
if payload_length == 126:
235224
payload_length = struct.unpack(">H", self.rfile.read(2))[0]
236225
elif payload_length == 127:
237226
payload_length = struct.unpack(">Q", self.rfile.read(8))[0]
238227

239228
masks = self.read_bytes(4)
240-
message_bytes = bytearray()
229+
payload = bytearray()
241230
for message_byte in self.read_bytes(payload_length):
242-
message_byte ^= masks[len(message_bytes) % 4]
243-
message_bytes.append(message_byte)
244-
opcode_handler(self, message_bytes.decode('utf8'))
231+
message_byte ^= masks[len(payload) % 4]
232+
payload.append(message_byte)
233+
234+
if fin and opcode != OPCODE_CONTINUATION: # simple msg
235+
if opcode == OPCODE_PING:
236+
self.server._ping_received_(self, payload)
237+
elif opcode == OPCODE_PONG:
238+
self.server._pong_received_(self, payload)
239+
elif opcode == OPCODE_TEXT:
240+
self.server._message_received_(self, payload)
241+
return
242+
243+
if not fin and opcode: # fragment msg start
244+
self.fragment_opcode = opcode
245+
self.fragment_payload_buf = payload
246+
return
247+
248+
# "not opcode" is the same as "opcode == OPCODE_CONTINUATION"
249+
if not fin and not opcode: # fragment msg ing
250+
self.fragment_payload_buf.extend(payload)
251+
return
252+
253+
if fin and opcode == OPCODE_CONTINUATION: # fragment msg end
254+
if self.fragment_opcode == OPCODE_TEXT:
255+
self.server._message_received_(self, self.fragment_payload_buf + payload)
256+
elif self.fragment_opcode == OPCODE_BINARY:
257+
pass
258+
return
245259

246260
def send_message(self, message):
247261
self.send_text(message)

0 commit comments

Comments
 (0)