def ws_control_frame(self, opcode, data): if opcode in (PING, CLOSE): rcode = PONG if opcode == PING else CLOSE if opcode == CLOSE: self.ws_close_received = True self.stop_reading = True if data: try: close_code = unpack_from(b'!H', data)[0] except struct_error: data = pack(b'!H', PROTOCOL_ERROR) + b'close frame data must be atleast two bytes' else: try: utf8_decode(data[2:]) except ValueError: data = pack(b'!H', PROTOCOL_ERROR) + b'close frame data must be valid UTF-8' else: if close_code < 1000 or close_code in RESERVED_CLOSE_CODES or (1011 < close_code < 3000): data = pack(b'!H', PROTOCOL_ERROR) + b'close code reserved' else: close_code = NORMAL_CLOSE data = pack(b'!H', close_code) f = ReadOnlyFileBuffer(create_frame(1, rcode, data)) f.is_close_frame = opcode == CLOSE with self.cf_lock: self.control_frames.append(f) elif opcode == PONG: try: self.websocket_handler.handle_websocket_pong(self.websocket_connection_id, data) except Exception: self.log.exception('Error in PONG handler:') self.set_ws_state()
def __call__(self, data): ans, self.state, self.codep = utf8_decode(data, self.state, self.codep) return ans