diff --git a/src/calibre/srv/tests/web_sockets.py b/src/calibre/srv/tests/web_sockets.py index d4f6cea6d5..d4a84196e6 100644 --- a/src/calibre/srv/tests/web_sockets.py +++ b/src/calibre/srv/tests/web_sockets.py @@ -228,7 +228,7 @@ class WebSocketTest(BaseTest): with WSTestServer(EchoHandler) as server: simple_test = partial(self.simple_test, server) - for q in ('', '*' * 125, '*' * 126, '*' * 127, '*' * 128, '*' * 65535, '*' * 65536): + for q in ('', '*' * 125, '*' * 126, '*' * 127, '*' * 128, '*' * 65535, '*' * 65536, "Hello-µ@ßöäüàá-UTF-8!!"): simple_test([q], [q]) for q in (b'', b'\xfe' * 125, b'\xfe' * 126, b'\xfe' * 127, b'\xfe' * 128, b'\xfe' * 65535, b'\xfe' * 65536): simple_test([q], [q]) @@ -242,7 +242,7 @@ class WebSocketTest(BaseTest): for payload in (b'', b'pong'): simple_test([(PONG, payload)], []) - fragments = 'frag1 frag2'.split() + fragments = 'Hello-µ@ßöä üàá-UTF-8!!'.split() with server.silence_log: for rsv in xrange(1, 7): @@ -287,3 +287,10 @@ class WebSocketTest(BaseTest): {'opcode':TEXT, 'fin':0}, {'opcode':CONTINUATION, 'fin':0}, {'opcode':CONTINUATION},], ['']) simple_test([ {'opcode':TEXT, 'fin':0}, {'opcode':CONTINUATION, 'fin':0, 'payload':'x'}, {'opcode':CONTINUATION},], ['x']) + + byte_data = "Hello-µ@ßöäüàá-UTF-8!!".encode('utf-8') + frags = [] + for i, b in enumerate(byte_data): + frags.append({'opcode':(TEXT if i == 0 else CONTINUATION), 'fin':1 if i == len(byte_data)-1 else 0, 'payload':b}) + simple_test(frags, [byte_data.decode('utf-8')]) + diff --git a/src/calibre/srv/web_socket.py b/src/calibre/srv/web_socket.py index e1ec3803d5..87a56602cf 100644 --- a/src/calibre/srv/web_socket.py +++ b/src/calibre/srv/web_socket.py @@ -326,17 +326,17 @@ class WebSocketConnection(HTTPConnection): self.websocket_close(PROTOCOL_ERROR, 'Continuation frame with non-zero opcode') return message_finished = frame_finished and is_final_frame_of_message - if message_finished: - self.current_recv_opcode = None - if opcode == TEXT: + if self.current_recv_opcode == TEXT: if message_starting: self.frag_decoder.reset() try: data = self.frag_decoder.decode(data, final=message_finished) except ValueError: self.frag_decoder.reset() + self.log.error('Client sent undecodeable UTF-8') return self.websocket_close(INCONSISTENT_DATA, 'Not valid UTF-8') if message_finished: + self.current_recv_opcode = None self.frag_decoder.reset() try: self.handle_websocket_data(data, message_starting, message_finished)