示例#1
0
    def websocket_to_django(self):
        try:
            while 1:
                if self.zmodemOO:
                    self.zmodemOO = False
                    x = self.channel.recv(2)
                    if not len(x):
                        return
                    if x == b'OO':
                        self.websocker.send(bytes_data=x)
                        continue
                    else:
                        x += self.channel.recv(4096)
                else:
                    x = self.channel.recv(4096)
                    if not len(x):
                        return

                if self.zmodem:
                    if zmodemszend in x or zmodemrzend in x:
                        self.zmodem = False
                        if zmodemszend in x:
                            self.zmodemOO = True
                    self.websocker.send(bytes_data=x)
                else:
                    if zmodemszstart in x or zmodemrzstart in x:
                        self.zmodem = True
                        self.websocker.send(bytes_data=x)
                    else:
                        try:
                            data = x.decode('utf-8')
                        except UnicodeDecodeError:  # utf-8中文占3个字符,可能会被截断,需要拼接
                            try:
                                x += self.channel.recv(1)
                                data = x.decode('utf-8')
                            except UnicodeDecodeError:
                                try:
                                    x += self.channel.recv(1)
                                    data = x.decode('utf-8')
                                except UnicodeDecodeError:
                                    print(traceback.format_exc())
                                    data = x.decode('utf-8', 'ignore')  # 拼接2次后还是报错则证明结果是乱码,强制转换

                        self.message['status'] = 0
                        self.message['message'] = data
                        self.res += data
                        message = json.dumps(self.message)
                        if self.websocker.send_flag == 0:
                            self.websocker.send(message)
                        elif self.websocker.send_flag == 1:
                            async_to_sync(self.websocker.channel_layer.group_send)(self.websocker.group, {
                                "type": "chat.message",
                                "text": message,
                            })

                        delay = round(time.time() - self.start_time, 6)
                        self.res_asciinema.append(json.dumps([delay, 'o', data]))

                        # 指定条结果或者指定秒数或者占用指定内存就保存一次
                        if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \
                                sys.getsizeof(self.res_asciinema) > 20971752:
                            tmp = list(self.res_asciinema)
                            self.res_asciinema = []
                            self.last_save_time = time.time()
                            save_res(self.res_file, tmp)

                        if self.tab_mode:
                            tmp = data.split(' ')
                            # tab 只返回一个命令时匹配
                            # print(tmp)
                            if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '':
                                self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(b'\x07', b'').decode()
                            elif len(tmp) == 1 and tmp[0].encode() != b'\x07':  # \x07 蜂鸣声
                                self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(b'\x07', b'').decode()
                            self.tab_mode = False
                        if self.history_mode:   # 不完善,只支持向上翻一个历史命令
                            if data.strip() != '':
                                self.cmd_tmp = data
                            self.history_mode = False
        except socket.timeout:
            self.message['status'] = 1
            self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!'
            message = json.dumps(self.message)
            if self.websocker.send_flag == 0:
                self.websocker.send(message)
            elif self.websocker.send_flag == 1:
                async_to_sync(self.websocker.channel_layer.group_send)(self.websocker.group, {
                    "type": "chat.message",
                    "text": message,
                })
            self.close(send_message=False)
        except Exception:
            self.close()
示例#2
0
文件: ssh.py 项目: Lancger/devops-1
    def websocket_to_django(self):
        try:
            while 1:
                if self.zmodemOO:
                    self.zmodemOO = False
                    x = self.channel.recv(2)
                    if not len(x):
                        return
                    if x == b'OO':
                        self.websocker.send(bytes_data=x)
                        continue
                    else:
                        x += self.channel.recv(BufferSize)
                else:
                    x = self.channel.recv(BufferSize)
                    if not len(x):
                        return

                if self.zmodem:
                    if zmodemszend in x or zmodemrzend in x:
                        self.zmodem = False
                        if zmodemszend in x:
                            self.zmodemOO = True
                    if zmodemcancel in x:
                        self.zmodem = False
                        self.channel.send('\n')
                    self.websocker.send(bytes_data=x)
                else:
                    if zmodemszstart in x or zmodemrzstart in x or zmodemrzestart in x or zmodemrzsstart in x \
                            or zmodemrzesstart in x:
                        self.zmodem = True
                        self.websocker.send(bytes_data=x)
                    else:
                        try:
                            data = x.decode('utf-8')
                        except UnicodeDecodeError:  # utf-8中文占3个字符,可能会被截断,需要拼接
                            try:
                                x += self.channel.recv(1)
                                data = x.decode('utf-8')
                            except UnicodeDecodeError:
                                try:
                                    x += self.channel.recv(1)
                                    data = x.decode('utf-8')
                                except UnicodeDecodeError:
                                    logger.error(traceback.format_exc())
                                    data = x.decode(
                                        'utf-8',
                                        'ignore')  # 拼接2次后还是报错则证明结果是乱码,强制转换
                        self.message['status'] = 0
                        self.message['message'] = data
                        self.res += data
                        message = json.dumps(self.message)
                        if self.websocker.send_flag == 0:
                            self.websocker.send(message)
                        elif self.websocker.send_flag == 1:
                            async_to_sync(
                                self.websocker.channel_layer.group_send)(
                                    self.websocker.group, {
                                        "type": "chat.message",
                                        "text": message,
                                    })

                        delay = round(time.time() - self.start_time, 6)
                        self.res_asciinema.append(
                            json.dumps([delay, 'o', data]))

                        # 指定条结果或者指定秒数或者占用指定内存就保存一次
                        if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \
                                sys.getsizeof(self.res_asciinema) > 20971752:
                            tmp = list(self.res_asciinema)
                            self.res_asciinema = []
                            self.last_save_time = time.time()
                            save_res(self.res_file, tmp)

                        if self.enter:
                            self.enter = False
                            if not data.startswith(
                                    "\r\n"):  # 回车后结果不以\r\n开头的肯定不是命令
                                self.cmd_tmp = ''
                            else:
                                if re.match(
                                        rb'^\r\n\s+\x1b.*$', x
                                ):  # 终端为 xterm,linux 等显示颜色类型时在 vi 编辑模式下回车
                                    self.cmd_tmp = ''
                                # elif x == b'\r\n':     # todo 正常模式下 vi 文件会返回 \r\n ,终端为 dumb 类型时在 vi 编辑模式下回车也会返回 \r\n,
                                #     self.cmd_tmp = ''
                                else:  # 记录真正命令, rl 不支持中文命令
                                    cmd_time = time.strftime(
                                        "%Y-%m-%d %H:%M:%S",
                                        time.localtime(int(time.time())))
                                    cmd = self.rl.process_line(
                                        self.cmd_tmp.encode("utf-8"))
                                    if cmd is None:  # 有可能 rl 库会返回 None,重试一次
                                        mp_readline.TESTING = True
                                        self.rl = mp_readline.MpReadline()
                                        cmd = self.rl.process_line(
                                            self.cmd_tmp.encode("utf-8"))

                                    if cmd:
                                        self.cmd += cmd_time + "\t" + remove_control_chars(
                                            cmd) + '\n'
                                    else:
                                        if cmd is None:
                                            logger.error(
                                                "recv from server: {} \nerror command: {}"
                                                .format(
                                                    x,
                                                    self.cmd_tmp.encode(
                                                        "utf-8")))
                                            self.cmd += cmd_time + "\t" + remove_control_chars(
                                                self.cmd_tmp) + '\n'
                                    self.cmd_tmp = ''
                        else:
                            if self.tab_mode:  # todo 兼容有问题
                                self.tab_mode = False
                                if x == b'\x07':
                                    pass

                                tmp = data.split(' ')
                                # tab 只返回一个命令时匹配
                                if len(tmp) == 2 and tmp[
                                        1] == '' and tmp[0] != '':
                                    self.cmd_tmp = self.cmd_tmp + tmp[
                                        0].encode().replace(b'\x07',
                                                            b'').decode()
                                elif len(tmp) == 1 and tmp[0].encode(
                                ) != b'\x07':  # \x07 蜂鸣声
                                    self.cmd_tmp = self.cmd_tmp + tmp[
                                        0].encode().replace(b'\x07',
                                                            b'').decode()

                            # 多次上下箭头查找历史命令返回数据中可能会包含 \x1b[1P 导致 rl 无法解析命令,具体原因没有深究
                            if self.history_mode:
                                self.history_mode = False
                                if x != b'' and x != b'\x07':
                                    x = re.sub(rb'\x1b\[\d+P', b'', x)
                                    self.cmd_tmp += x.decode("utf-8")

                            if self.ctrl_c:  # 取消命令
                                self.ctrl_c = False
                                # if x == b'^C\r\n':
                                if re.match(rb'^\^C\r\n[\s\S]*$',
                                            x) or re.match(
                                                rb'^\r\n[\s\S]*$', x):
                                    self.cmd_tmp = ""
                            if self.ctrl_z:
                                self.ctrl_z = False
                                if re.match(
                                        rb'^[\s\S]*\[\d+\]\+\s+Stopped\s+\S+[\s\S]*$',
                                        x):
                                    self.cmd_tmp = ""
        except socket.timeout:
            self.message['status'] = 1
            self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!'
            message = json.dumps(self.message)
            if self.websocker.send_flag == 0:
                self.websocker.send(message)
            elif self.websocker.send_flag == 1:
                async_to_sync(self.websocker.channel_layer.group_send)(
                    self.websocker.group, {
                        "type": "chat.message",
                        "text": message,
                    })
            self.close(send_message=False)
        except Exception:
            logger.info(traceback.format_exc())
            self.close()
示例#3
0
    def websocket_to_django(self):
        try:
            while True:
                data = ''
                # read_very_eager 方法读取时会是无限循环,性能比较低
                # data = self.tn.read_very_eager().decode('utf-8')
                # if not len(data):
                #     continue

                # expect 使用正则匹配所有返回内容,还可以实现超时无返回内容断开连接
                try:
                    if len(self._buffer) >= 1:
                        data = self._buffer[:4096]
                        self._buffer = self._buffer[4096:]
                    else:
                        x, y, z = self.tn.expect([br'[\s\S]+'],
                                                 timeout=terminal_exipry_time)
                        self._buffer += z
                        data = self._buffer[:4096]  # 一次最多截取4096个字符
                        self._buffer = self._buffer[4096:]
                    data = data.decode('utf-8')
                except UnicodeDecodeError:  # utf-8中文占3个字符,可能会被截断,需要拼接
                    try:
                        if len(self._buffer) >= 1:
                            data += self._buffer[:1]
                            self._buffer = self._buffer[1:]
                        else:
                            x, y, z = self.tn.expect(
                                [br'[\s\S]+'], timeout=terminal_exipry_time)
                            if len(z) > 1:
                                self._buffer += z
                                data += self._buffer[:1]
                                self._buffer = self._buffer[1:]
                            else:
                                data += z
                        data = data.decode('utf-8')
                    except UnicodeDecodeError:
                        try:
                            if len(self._buffer) >= 1:
                                data += self._buffer[:1]
                                self._buffer = self._buffer[1:]
                            else:
                                x, y, z = self.tn.expect(
                                    [br'[\s\S]+'],
                                    timeout=terminal_exipry_time)
                                if len(z) > 1:
                                    self._buffer += z
                                    data += self._buffer[:1]
                                    self._buffer = self._buffer[1:]
                                else:
                                    data += z
                            data = data.decode('utf-8')
                        except UnicodeDecodeError:
                            print(traceback.format_exc())
                            data = data.decode(
                                'utf-8', 'ignore')  # 拼接2次后还是报错则证明结果是乱码,强制转换

                if not len(data):
                    raise socket.timeout
                self.message['status'] = 0
                self.message['message'] = data
                self.res += data
                message = json.dumps(self.message)
                if self.websocker.send_flag == 0:
                    self.websocker.send(message)
                elif self.websocker.send_flag == 1:
                    async_to_sync(self.websocker.channel_layer.group_send)(
                        self.websocker.group, {
                            "type": "chat.message",
                            "text": message,
                        })

                delay = round(time.time() - self.start_time, 6)
                self.res_asciinema.append(json.dumps([delay, 'o', data]))
                # 指定条结果或者指定秒数或者占用指定大小内存就保存一次
                if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \
                        sys.getsizeof(self.res_asciinema) > 2097152:
                    tmp = list(self.res_asciinema)
                    self.res_asciinema = []
                    self.last_save_time = time.time()
                    save_res(self.res_file, tmp)

                if self.tab_mode:
                    tmp = data.split(' ')
                    # tab 只返回一个命令时匹配
                    # print(tmp)
                    if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '':
                        self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(
                            b'\x07', b'').decode()
                    elif len(tmp
                             ) == 1 and tmp[0].encode() != b'\x07':  # \x07 蜂鸣声
                        self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(
                            b'\x07', b'').decode()
                    self.tab_mode = False
                if self.history_mode:  # 不完善,只支持向上翻一个历史命令
                    # print(data)
                    if data.strip() != '':
                        self.cmd_tmp = data
                    self.history_mode = False
        except socket.timeout:
            self.message['status'] = 1
            self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!'
            message = json.dumps(self.message)
            if self.websocker.send_flag == 0:
                self.websocker.send(message)
            elif self.websocker.send_flag == 1:
                async_to_sync(self.websocker.channel_layer.group_send)(
                    self.websocker.group, {
                        "type": "chat.message",
                        "text": message,
                    })
            self.close(send_message=False)
        except Exception:
            print(traceback.format_exc())
            self.close()
示例#4
0
    def websocket_to_django(self):
        try:
            while 1:
                # read_very_eager 方法读取时会是无限循环,性能比较低
                # data = self.tn.read_very_eager().decode('utf-8')
                # if not len(data):
                #     continue

                # expect 使用正则匹配所有返回内容,还可以实现超时无返回内容断开连接
                if len(self._buffer) >= 1:
                    x = self._buffer[:BufferSize]
                    self._buffer = self._buffer[BufferSize:]
                else:
                    n, y, z = self.tn.expect([br'[\s\S]+'],
                                             timeout=terminal_exipry_time)
                    self._buffer += z
                    x = self._buffer[:BufferSize]  # 一次最多截取 BufferSize 个字符
                    self._buffer = self._buffer[BufferSize:]
                if not len(x):
                    raise socket.timeout

                try:
                    data = x.decode('utf-8')
                except UnicodeDecodeError:  # utf-8中文占3个字符,可能会被截断,需要拼接
                    try:
                        if len(self._buffer) >= 1:
                            x += self._buffer[:1]
                            self._buffer = self._buffer[1:]
                        else:
                            n, y, z = self.tn.expect(
                                [br'[\s\S]+'], timeout=terminal_exipry_time)
                            if len(z) > 1:
                                self._buffer += z
                                x += self._buffer[:1]
                                self._buffer = self._buffer[1:]
                            else:
                                x += z
                        data = x.decode('utf-8')
                    except UnicodeDecodeError:
                        try:
                            if len(self._buffer) >= 1:
                                x += self._buffer[:1]
                                self._buffer = self._buffer[1:]
                            else:
                                n, y, z = self.tn.expect(
                                    [br'[\s\S]+'],
                                    timeout=terminal_exipry_time)
                                if len(z) > 1:
                                    self._buffer += z
                                    x += self._buffer[:1]
                                    self._buffer = self._buffer[1:]
                                else:
                                    x += z
                            data = x.decode('utf-8')
                        except UnicodeDecodeError:
                            data = x.decode('utf-8',
                                            'ignore')  # 拼接2次后还是报错则证明结果是乱码,强制转换
                self.message['status'] = 0
                self.message['message'] = data
                self.res += data
                message = json.dumps(self.message)
                if self.websocker.send_flag == 0:
                    self.websocker.send(message)
                elif self.websocker.send_flag == 1:
                    async_to_sync(self.websocker.channel_layer.group_send)(
                        self.websocker.group, {
                            "type": "chat.message",
                            "text": message,
                        })

                delay = round(time.time() - self.start_time, 6)
                self.res_asciinema.append(json.dumps([delay, 'o', data]))
                # 指定条结果或者指定秒数或者占用指定大小内存就保存一次
                if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \
                        sys.getsizeof(self.res_asciinema) > 2097152:
                    tmp = list(self.res_asciinema)
                    self.res_asciinema = []
                    self.last_save_time = time.time()
                    save_res(self.res_file, tmp)

                if self.enter:
                    self.enter = False
                    if not data.startswith("\r\n"):  # 回车后结果不以\r\n开头的肯定不是命令
                        self.cmd_tmp = ''
                    else:
                        if re.match(rb'^\r\n\s+\x1b.*$',
                                    x):  # 终端为 xterm,linux 等显示颜色类型时在 vi 编辑模式下回车
                            self.cmd_tmp = ''
                        # elif x == b'\r\n':     # todo 正常模式下 vi 文件会返回 \r\n ,终端为 dumb 类型时在 vi 编辑模式下回车也会返回 \r\n,
                        #     self.cmd_tmp = ''
                        else:  # 记录真正命令, rl 不支持中文命令
                            cmd_time = time.strftime(
                                "%Y-%m-%d %H:%M:%S",
                                time.localtime(int(time.time())))
                            cmd = self.rl.process_line(
                                self.cmd_tmp.encode("utf-8"))
                            if not cmd:  # 有可能 rl 库会返回 None,重试一次
                                mp_readline.TESTING = True
                                self.rl = mp_readline.MpReadline()
                                cmd = self.rl.process_line(
                                    self.cmd_tmp.encode("utf-8"))

                            if cmd:
                                self.cmd += cmd_time + "\t" + remove_control_chars(
                                    cmd) + '\n'
                            else:
                                logger.error(
                                    "recv from server: {} \nerror command: {}".
                                    format(x, self.cmd_tmp.encode("utf-8")))
                                self.cmd += cmd_time + "\t" + remove_control_chars(
                                    self.cmd_tmp) + '\n'
                            self.cmd_tmp = ''
                else:
                    if self.tab_mode:  # todo 兼容有问题
                        self.tab_mode = False
                        tmp = data.split(' ')
                        # tab 只返回一个命令时匹配
                        # print(tmp)
                        if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '':
                            self.cmd_tmp = self.cmd_tmp + tmp[0].encode(
                            ).replace(b'\x07', b'').decode()
                        elif len(tmp) == 1 and tmp[0].encode(
                        ) != b'\x07':  # \x07 蜂鸣声
                            self.cmd_tmp = self.cmd_tmp + tmp[0].encode(
                            ).replace(b'\x07', b'').decode()

                    # 多次上下箭头查找历史命令返回数据中可能会包含 \x1b[1P 导致 rl 无法解析命令,具体原因没有深究
                    if self.history_mode:
                        self.history_mode = False
                        if x != b'' and x != b'\x07':
                            x = re.sub(rb'\x1b\[\d+P', b'', x)
                            self.cmd_tmp += x.decode("utf-8")

                    if self.ctrl_c:  # 取消命令
                        self.ctrl_c = False
                        # if x == b'^C\r\n':
                        if re.match(rb'^\^C\r\n[\s\S]*$', x) or re.match(
                                rb'^\r\n[\s\S]*$', x):
                            self.cmd_tmp = ""
                    if self.ctrl_z:
                        self.ctrl_z = False
                        if re.match(
                                rb'^[\s\S]*\[\d+\]\+\s+Stopped\s+\S+[\s\S]*$',
                                x):
                            self.cmd_tmp = ""
        except socket.timeout:
            self.message['status'] = 1
            self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!'
            message = json.dumps(self.message)
            if self.websocker.send_flag == 0:
                self.websocker.send(message)
            elif self.websocker.send_flag == 1:
                async_to_sync(self.websocker.channel_layer.group_send)(
                    self.websocker.group, {
                        "type": "chat.message",
                        "text": message,
                    })
            self.close(send_message=False)
        except Exception:
            logger.error(traceback.format_exc())
            self.close()