def test_basic_io(self): p1, p2 = PipeStream.create_pair() p1.write(BYTES_LITERAL("hello")) assert p2.poll(0) assert p2.read(5) == BYTES_LITERAL("hello") assert not p2.poll(0) p2.write(BYTES_LITERAL("world")) assert p1.poll(0) assert p1.read(5) == BYTES_LITERAL("world") assert not p1.poll(0) p1.close() p2.close()
def __init__(self, remote_machine, server_class="rpyc.utils.server.ThreadedServer", extra_setup="", python_executable=None): self.proc = None self.tun = None self.remote_machine = remote_machine self._tmpdir_ctx = None rpyc_root = local.path(rpyc.__file__).up() self._tmpdir_ctx = remote_machine.tempdir() tmp = self._tmpdir_ctx.__enter__() copy(rpyc_root, tmp / "rpyc") script = (tmp / "deployed-rpyc.py") modname, clsname = server_class.rsplit(".", 1) script.write( SERVER_SCRIPT.replace("$MODULE$", modname).replace( "$SERVER$", clsname).replace("$EXTRA_SETUP$", extra_setup)) if python_executable: cmd = remote_machine[python_executable] else: major = sys.version_info[0] minor = sys.version_info[1] cmd = None for opt in [ "python%s.%s" % (major, minor), "python%s" % (major, ) ]: try: cmd = remote_machine[opt] except CommandNotFound: pass else: break if not cmd: cmd = remote_machine.python self.proc = cmd.popen(script, new_session=True) line = "" try: line = self.proc.stdout.readline() self.remote_port = int(line.strip()) except Exception: try: self.proc.terminate() except Exception: pass stdout, stderr = self.proc.communicate() raise ProcessExecutionError(self.proc.argv, self.proc.returncode, BYTES_LITERAL(line) + stdout, stderr) if hasattr(remote_machine, "connect_sock"): # Paramiko: use connect_sock() instead of tunnels self.local_port = None else: self.local_port = rpyc.utils.factory._get_free_port() self.tun = remote_machine.tunnel(self.local_port, self.remote_port)
def __init__(self, host, user, keyfile, python_executable='~/anaconda3/bin/python'): self.remote_machine = _get_machine(host, user, keyfile) self._kill_py() self.py = self.remote_machine[python_executable] self.proc = self.py.popen(['-m', 'bnb.remote.server'], new_session=True) self.local_port = None line = "" try: logger.debug(f'Waiting for the line') line = self.proc.stdout.readline() self.remote_port = int(line.strip()) except Exception: stdout, stderr = self.proc.communicate() self.close() raise ProcessExecutionError(self.proc.argv, self.proc.returncode, BYTES_LITERAL(line) + stdout, stderr)
def read(self, count): try: if self.poll_read: win32file.GetOverlappedResult(self.incoming, self.read_overlapped, 1) data = [self.poll_buffer[:]] self.poll_read = False count -= 1 else: data = [] while count > 0: hr, buf = win32file.ReadFile(self.incoming, win32file.AllocateReadBuffer(int(min(self.MAX_IO_CHUNK, count))), self.read_overlapped) n = win32file.GetOverlappedResult(self.incoming, self.read_overlapped, 1) count -= n data.append(buf[:n]) except TypeError: ex = sys.exc_info()[1] if not self.closed: raise raise EOFError(ex) except win32file.error: ex = sys.exc_info()[1] self.close() raise EOFError(ex) return BYTES_LITERAL("").join(data)
def _poll_read(self, timeout=None): if not self.client_side: return self.upstream.wait(timeout) self.sock.settimeout(timeout) try: buf, addr = self.sock.recvfrom(self.MAX_IO_CHUNK) except socket.timeout: self.total_timeout += timeout if self.total_timeout > 300: self.sock.close( ) # too much inactivity, disconnect to let it reconnect return False except socket.error: ex = sys.exc_info()[1] if get_exc_errno(ex) in (errno.EAGAIN, errno.EWOULDBLOCK): # windows just has to be a b**ch return True self.close() raise EOFError(ex) if not buf: self.close() raise EOFError("connection closed by peer") self.buf_in.write(BYTES_LITERAL(buf)) self.total_timeout = 0 return True
def _dump_int(obj, stream): if obj in IMM_INTS: stream.append(IMM_INTS[obj]) else: obj = BYTES_LITERAL(str(obj)) lenobj = len(obj) if lenobj < 256: stream.append(TAG_INT_L1 + I1.pack(lenobj) + obj) else: stream.append(TAG_INT_L4 + I4.pack(lenobj) + obj)
def dump(obj): """Converts (dumps) the given object to a byte-string representation :param obj: any :func:`dumpable` object :returns: a byte-string representation of the object """ stream = [] _dump(obj, stream) return BYTES_LITERAL("").join(stream)
def close(self): """closes (terminates) the SSH tunnel""" if not self.is_open(): return self.proc.stdin.write(BYTES_LITERAL("foo\n\n\n")) self.proc.stdin.close() self.proc.stdout.close() self.proc.stderr.close() try: self.proc.kill() except AttributeError: os.kill(self.proc.pid, signal.SIGTERM) self.proc.wait() self.proc = None
def __init__(self, sshctx, loc_host, loc_port, rem_host, rem_port): self.loc_host = loc_host self.loc_port = loc_port self.rem_host = rem_host self.rem_port = rem_port self.sshctx = sshctx self.proc = sshctx.popen("python", "-u", "-c", self.PROGRAM, L="[%s]:%s:[%s]:%s" % (loc_host, loc_port, rem_host, rem_port)) banner = self.proc.stdout.readline().strip() if banner != BYTES_LITERAL("ready"): raise ValueError("tunnel failed", banner)
def test_unicode(self): self.conn.modules.sys.path.append(u"../你好") self.assertEqual(self.conn.modules.sys.path.pop(-1), u"../你好") # self.conn.execute("x = '111'") self.assertEqual(self.conn.namespace["x"], '111') self.conn.execute(u"x = u'你好'") print(self.conn.eval("type(x)")) self.assertEqual(self.conn.namespace["x"], u'你好') from rpyc.lib.compat import BYTES_LITERAL self.conn.execute("x = u'你好'.encode('utf-8')") print(self.conn.eval("type(x)")) self.assertEqual(self.conn.namespace["x"], BYTES_LITERAL('你好'))
def _read(self): try: buf = self.sock.recv(self.MAX_IO_CHUNK) except socket.timeout: return except socket.error: ex = sys.exc_info()[1] if get_exc_errno(ex) in retry_errnos: # windows just has to be a bitch return self.close() raise EOFError(ex) if not buf: self.close() raise EOFError("connection closed by peer") self.buf_in.write(BYTES_LITERAL(buf))
def read(self, count): try: data = [] while count > 0: dummy, buf = win32file.ReadFile(self.incoming, int(min(self.MAX_IO_CHUNK, count))) count -= len(buf) data.append(buf) except TypeError: ex = sys.exc_info()[1] if not self.closed: raise raise EOFError(ex) except win32file.error: ex = sys.exc_info()[1] self.close() raise EOFError(ex) return BYTES_LITERAL("").join(data)
def read(self, count): data = [] try: while count > 0: buf = os.read(self.incoming.fileno(), min(self.MAX_IO_CHUNK, count)) if not buf: raise EOFError("connection closed by peer") data.append(buf) count -= len(buf) except EOFError: self.close() raise except EnvironmentError: ex = sys.exc_info()[1] self.close() raise EOFError(ex) return BYTES_LITERAL("").join(data)
def _read(self): try: buf = self.sock.recv(self.MAX_IO_CHUNK) except socket.timeout: return except socket.error: ex = sys.exc_info()[1] if get_exc_errno(ex) in (errno.EAGAIN, errno.EWOULDBLOCK): # windows just has to be a b**ch # edit: some politeness please ;) return self.close() raise EOFError(ex) if not buf: self.close() raise EOFError("connection closed by peer") self.buf_in.write(BYTES_LITERAL(buf))
def read(self, count): data = [] while count > 0: try: buf = self.sock.recv(min(self.MAX_IO_CHUNK, count)) except socket.timeout: continue except socket.error: ex = sys.exc_info()[1] if get_exc_errno(ex) in retry_errnos: # windows just has to be a bitch continue self.close() raise EOFError(ex) if not buf: self.close() raise EOFError("connection closed by peer") data.append(buf) count -= len(buf) return BYTES_LITERAL("").join(data)
class Channel(object): """Channel implementation. Note: In order to avoid problems with all sorts of line-buffered transports, we deliberately add ``\\n`` at the end of each frame. """ COMPRESSION_THRESHOLD = 3000 COMPRESSION_LEVEL = 1 FRAME_HEADER = Struct("!LB") FLUSHER = BYTES_LITERAL( "\n") # cause any line-buffered layers below us to flush __slots__ = ["stream", "compress"] def __init__(self, stream, compress=True): self.stream = stream if not zlib: compress = False self.compress = compress def close(self): """closes the channel and underlying stream""" self.stream.close() @property def closed(self): """indicates whether the underlying stream has been closed""" return self.stream.closed def fileno(self): """returns the file descriptor of the underlying stream""" return self.stream.fileno() def poll(self, timeout): """polls the underlying steam for data, waiting up to *timeout* seconds""" return self.stream.poll(timeout) def recv(self): """Receives the next packet (or *frame*) from the underlying stream. This method will block until the packet has been read completely :returns: string of data """ header = self.stream.read(self.FRAME_HEADER.size) length, compressed = self.FRAME_HEADER.unpack(header) data = self.stream.read(length + len(self.FLUSHER))[:-len(self.FLUSHER)] if compressed: data = zlib.decompress(data) return data def send(self, data): """Sends the given string of data as a packet over the underlying stream. Blocks until the packet has been sent. :param data: the byte string to send as a packet """ if self.compress and len(data) > self.COMPRESSION_THRESHOLD: compressed = 1 data = zlib.compress(data, self.COMPRESSION_LEVEL) else: compressed = 0 header = self.FRAME_HEADER.pack(len(data), compressed) buf = header + data + self.FLUSHER self.stream.write(buf)
def _load_empty_str(stream): return BYTES_LITERAL("")
>>> x = ("he", 7, u"llo", 8, (), 900, None, True, Ellipsis, 18.2, 18.2j + 13, ... slice(1,2,3), frozenset([5,6,7]), NotImplemented) >>> dumpable(x) True >>> y = dump(x) >>> y.encode("hex") '140e0b686557080c6c6c6f580216033930300003061840323333333333331b402a000000000000403233333333333319125152531a1255565705' >>> z = load(y) >>> x == z True """ from rpyc.lib.compat import Struct, BytesIO, is_py3k, BYTES_LITERAL # singletons TAG_NONE = BYTES_LITERAL("\x00") TAG_EMPTY_STR = BYTES_LITERAL("\x01") TAG_EMPTY_TUPLE = BYTES_LITERAL("\x02") TAG_TRUE = BYTES_LITERAL("\x03") TAG_FALSE = BYTES_LITERAL("\x04") TAG_NOT_IMPLEMENTED = BYTES_LITERAL("\x05") TAG_ELLIPSIS = BYTES_LITERAL("\x06") # types TAG_UNICODE = BYTES_LITERAL("\x08") TAG_LONG = BYTES_LITERAL("\x09") TAG_STR1 = BYTES_LITERAL("\x0a") TAG_STR2 = BYTES_LITERAL("\x0b") TAG_STR3 = BYTES_LITERAL("\x0c") TAG_STR4 = BYTES_LITERAL("\x0d") TAG_STR_L1 = BYTES_LITERAL("\x0e") TAG_STR_L4 = BYTES_LITERAL("\x0f")