def connect(self, loop=None): loop = loop or self.loop for addr in self.addrs: if addr['type'] == 'unix': to = addr.get('path') to = to or addr.get('tmpdir') to = to or addr.get('abstract') return aio.open_unix_connection(to, loop=loop) elif addr['type'] == 'launchd': env = addr.get('env') to = environ.get(env, None) return aio.open_unix_connection(to, loop=loop) elif addr['tcp'] == 'launchd': host = addr.get('host', '127.0.0.1') bind = addr.get('bind', None) port = addr.get('port', None) family = addr.get('family', None) return aio.open_connection( host=host, port=port, ssl= True if port == '443' else None, family=AF_INET6 if family == 'ipv6' else AF_INET, local_addr=bind ) raise Exception('UNKNOWN ADDRESS TYPE')
def test_pause_pipe_writer(self): """Test pausing and resuming writing to a socketpair""" data = 4*1024*1024*'*' rsock1, wsock1 = socket.socketpair() rsock2, wsock2 = socket.socketpair() reader1, writer1 = yield from asyncio.open_unix_connection(sock=rsock1) reader2, writer2 = yield from asyncio.open_unix_connection(sock=rsock2) with (yield from self.connect()) as conn: process = yield from conn.create_process(input=data) yield from asyncio.sleep(1) yield from process.redirect_stdout(wsock1) yield from process.redirect_stderr(wsock2) stdout_data, stderr_data = \ yield from asyncio.gather(reader1.read(), reader2.read()) writer1.close() writer2.close() yield from process.wait() self.assertEqual(stdout_data.decode(), data) self.assertEqual(stderr_data.decode(), data)
def prepare_stream(self): """Sets up an asyncio pipe from client to server Only called on PUT when path is to a file """ self.rsock, self.wsock = socket.socketpair() self.reader, _ = yield from asyncio.open_unix_connection(sock=self.rsock) _, self.writer = yield from asyncio.open_unix_connection(sock=self.wsock) self.stream = RequestStreamReader(self.request, self.reader) self.uploader = asyncio.async(self.provider.upload(self.stream, self.path))
def prepare_stream(self): if self.request.method in self.STREAM_METHODS: self.rsock, self.wsock = socket.socketpair() self.reader, _ = yield from asyncio.open_unix_connection(sock=self.rsock) _, self.writer = yield from asyncio.open_unix_connection(sock=self.wsock) self.stream = RequestStreamReader(self.request, self.reader) self.uploader = asyncio.async( self.provider.upload(self.stream, **self.arguments) ) else: self.stream = None
def talk(self): self.reader, self.writer = yield from \ asyncio.open_unix_connection(self.admin_sock) for cmd in iter(self.commands): logger.debug('sending cmd: {}'.format(cmd)) yield from self.send(cmd) yield from self.read()
def test_open_unix_connection_no_loop_ssl(self): with test_utils.run_test_unix_server(use_ssl=True) as httpd: conn_fut = asyncio.open_unix_connection( httpd.address, ssl=test_utils.dummy_ssl_context(), server_hostname="", loop=self.loop ) self._basetest_open_connection_no_loop_ssl(conn_fut)
def setup(clean_environment=True): """Return a tuple of address, socket for future use. clean_environment removes the variables from env to prevent children from inheriting it and doing something wrong. """ global sock, reader, writer, watchdog_sec, watchdog_task if clean_environment: address = os.environ.pop("NOTIFY_SOCKET", None) else: address = os.environ.get("NOTIFY_SOCKET", None) if not address or len(address) == 1 or address[0] not in ("@", "/"): raise RuntimeError('No suitable address found.') if address[0] == "@": address = "\0" + address[1:] sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM | socket.SOCK_CLOEXEC) sock.connect(address) reader, writer = base.loop.run_until_complete(asyncio.open_unix_connection(loop=base.loop, sock=sock)) """Return the time (in seconds) that we need to ping within.""" val = os.environ.get("WATCHDOG_USEC", None) if not val: watchdog_sec = None else: watchdog_sec = int(val) / 1000000 watchdog_task = base.loop.create_task(watchdog()) base.cleanup_tasks.append(base.loop.create_task(cleanup()))
def create_connection(address, *, db=None, password=None, encoding=None, loop=None): """Creates redis connection. Opens connection to Redis server specified by address argument. Address argument is similar to socket address argument, ie: * when address is a tuple it represents (host, port) pair; * when address is a str it represents unix domain socket path. (no other address formats supported) Encoding argument can be used to decode byte-replies to strings. By default no decoding is done. Return value is RedisConnection instance. This function is a coroutine. """ assert isinstance(address, (tuple, list, str)), "tuple or str expected" if isinstance(address, (list, tuple)): host, port = address reader, writer = yield from asyncio.open_connection( host, port, loop=loop) else: reader, writer = yield from asyncio.open_unix_connection( address, loop=loop) conn = RedisConnection(reader, writer, encoding=encoding, loop=loop) if password is not None: yield from conn.auth(password) if db is not None: yield from conn.select(db) return conn
def connect(self): # TODO: Set close callback # raise OperationalError(2006, # "MySQL server has gone away (%r)" % (e,)) try: if self._unix_socket and self._host in ("localhost", "127.0.0.1"): self._reader, self._writer = yield from asyncio.open_unix_connection(self._unix_socket, loop=self._loop) self.host_info = "Localhost via UNIX socket: " + self._unix_socket else: self._reader, self._writer = yield from asyncio.open_connection(self._host, self._port, loop=self._loop) self.host_info = "socket %s:%d" % (self._host, self._port) if self._no_delay: self._set_nodelay(True) yield from self._get_server_information() yield from self._request_authentication() self.connected_time = self._loop.time() if self.sql_mode is not None: yield from self.query("SET sql_mode=%s" % (self.sql_mode,)) if self.init_command is not None: yield from self.query(self.init_command) yield from self.commit() if self.autocommit_mode is not None: yield from self.autocommit(self.autocommit_mode) except OSError as e: self._reader, self._writer = None, None raise OperationalError(2003, "Can't connect to MySQL server on %r (%s)" % (self._host, e))
def open(self): device = self.settings['device'] # Get UNIX socket self.socket = self.comport_state.get_socket(self.settings['_id']) # Try to lock COM-port for write self.lock = self.comport_state.lock(device, ttl=self.ttl) while self.run and not self.lock: log.debug("COM-Port is locked, device={}".format(device)) try: yield from asyncio.sleep(1) self.lock = self.comport_state.lock(device, ttl=self.ttl) except: log.error("COM-Port is locked, device={}".format(device)) return None, None if not self.run: log.error("COM-Port is locked, device={}".format(device)) return None, None # Connect to socket stdout, stdin = yield from asyncio.open_unix_connection(path=self.socket) self.device = device self.writer = stdin return stdout, stdin
def connect(self): is_unix_socket = (self.options.family == getattr(socket, 'AF_UNIX', None)) if self.options.use_ssl: # TODO: cache at Pool level. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) if self.options.certfile is not None: ctx.load_cert_chain(self.options.certfile, self.options.keyfile) if self.options.ca_certs is not None: ctx.load_verify_locations(self.options.ca_certs) if self.options.cert_reqs is not None: ctx.verify_mode = self.options.cert_reqs if ctx.verify_mode in (ssl.CERT_OPTIONAL, ssl.CERT_REQUIRED): ctx.check_hostname = True else: ctx = None if is_unix_socket: path = self.options.address[0] reader, writer = yield from asyncio.open_unix_connection( path, loop=self.loop, ssl=ctx) else: host, port = self.options.address reader, writer = yield from asyncio.open_connection( host=host, port=port, ssl=ctx, loop=self.loop) sock = writer.transport.get_extra_info('socket') sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, self.options.socket_keepalive) self._reader, self._writer = reader, writer
def client(path): reader, writer = yield from asyncio.open_unix_connection(path, loop=self.loop) # send a line writer.write(b"hello world!\n") # read it back msgback = yield from reader.readline() writer.close() return msgback
def connect(self): """Connect to the SSH agent""" # pylint doesn't think open_unix_connection exists # pylint: disable=no-member self._reader, self._writer = \ yield from asyncio.open_unix_connection(self._agent_path, loop=self._loop)
def _check_local_unix_connection(self, listen_path): """Open a local connection and test if an input line is echoed back""" # pylint doesn't think open_unix_connection exists # pylint: disable=no-member reader, writer = yield from asyncio.open_unix_connection(listen_path) # pylint: enable=no-member yield from self._check_echo_line(reader, writer)
def open_connection(entrypoint): if entrypoint.startswith("unix://"): reader, writer = yield from asyncio.open_unix_connection( entrypoint.split("://")[1]) else: host_port = entrypoint.split("://")[1].split(":") reader, writer = yield from asyncio.open_connection(host_port[0], host_port[1]) return reader, writer
def open_connection(self): try: self._reader, self._writer = (yield from asyncio.wait_for( asyncio.open_unix_connection(path=self.unix_socket, loop=self._loop, limit=self._default_buffer_limit), loop=self._loop, timeout=self._connection_timeout)) except IOError as err: raise errors.InterfaceError( errno=2002, values=(self.get_address(), _strioerror(err))) except Exception as err: raise errors.InterfaceError(str(err))
def go(self): self.log("connection received") upstream_reader, upstream_writer = yield from asyncio.open_unix_connection(path=self._proxy_path) self.log("connected to upstream") loop.create_task(self.read_from_upstream(upstream_reader)) try: yield from SSHAgentConnection.read_messages_from_stream( self._client_reader, lambda mesg: self.message_from_client(upstream_writer, mesg)) self.log("disconnected") finally: upstream_writer.close()
def create_connection(address, *, db=None, password=None, ssl=None, encoding=None, loop=None): """Creates redis connection. Opens connection to Redis server specified by address argument. Address argument is similar to socket address argument, ie: * when address is a tuple it represents (host, port) pair; * when address is a str it represents unix domain socket path. (no other address formats supported) SSL argument is passed through to asyncio.create_connection. By default SSL/TLS is not used. Encoding argument can be used to decode byte-replies to strings. By default no decoding is done. Return value is RedisConnection instance. This function is a coroutine. """ assert isinstance(address, (tuple, list, str)), "tuple or str expected" if isinstance(address, (list, tuple)): host, port = address logger.debug("Creating tcp connection to %r", address) reader, writer = yield from asyncio.open_connection( host, port, ssl=ssl, loop=loop) sock = writer.transport.get_extra_info('socket') if sock is not None: sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) address = sock.getpeername() address = tuple(address[:2]) else: logger.debug("Creating unix connection to %r", address) reader, writer = yield from asyncio.open_unix_connection( address, ssl=ssl, loop=loop) sock = writer.transport.get_extra_info('socket') if sock is not None: address = sock.getpeername() conn = RedisConnection(reader, writer, encoding=encoding, address=address, loop=loop) try: if password is not None: yield from conn.auth(password) if db is not None: yield from conn.select(db) except Exception: conn.close() yield from conn.wait_closed() raise return conn
def _check_local_unix_connection(self, listen_path): """Open a local connection and test if an input line is echoed back""" # pylint doesn't think open_unix_connection exists # pylint: disable=no-member reader, writer = yield from asyncio.open_unix_connection(listen_path) # pylint: enable=no-member line = str(id(self)).encode('utf-8') + b'\n' writer.write(line) self.assertEqual(line, (yield from reader.readline())) writer.close()
def _setUp(self): self.r, self.w = yield from asyncio.open_unix_connection(self.path) self.conn = H2Connection() self.conn.initiate_connection() self.w.write(self.conn.data_to_send()) events = yield from self._expect_events(3) self.assertIsInstance(events[0], RemoteSettingsChanged) self.assertIsInstance(events[1], RemoteSettingsChanged) self.assertIsInstance(events[2], SettingsAcknowledged) self.assertIsInstance((yield from self.server.events.get()), RemoteSettingsChanged) self.assertIsInstance((yield from self.server.events.get()), SettingsAcknowledged) self.assertIsInstance((yield from self.server.events.get()), SettingsAcknowledged)
def open_agent(loop, agent_path): """Open a connection to ssh-agent""" if not loop: loop = asyncio.get_event_loop() if not agent_path: agent_path = os.environ.get("SSH_AUTH_SOCK", None) if not agent_path: raise OSError(errno.ENOENT, "Agent not found") return (yield from asyncio.open_unix_connection(agent_path, loop=loop))
def test_client(): def func(obj): print("obj:", obj) print("sys.prefix:", sys.prefix) print("sys.maxsize:", sys.maxsize) getrefcount = obj[-1] print("refcount:", getrefcount(None)) loop = asyncio.get_event_loop() import time time.sleep(1) reader, writer = loop.run_until_complete(asyncio.open_unix_connection("socket")) log.info("client: connected to server") with tap.Connection(reader, writer) as conn: log.info("client: sending object to server") m = {"foo": "bar"} t = (5435452652, m) l = [54325235, 9, t, 765376542, None, 9] g = generate_nothing() obj = (func, sys.stdout, l, (g, 1324, 5435432, t, None), sys.getrefcount) loop.run_until_complete(conn.send(obj)) log.info("client: sent object to server") log.info("client: sending object to server") l[0] = 777 m["foo"] = "bar2" m[1] = 2 m[False] = True loop.run_until_complete(conn.send(obj)) log.info("client: sent object to server") log.info("client: receiving object from server") obj2 = loop.run_until_complete(conn.receive()) log.info("client: received object from server") stdout2, l2 = obj2 l2[-1] = 11 print("loopback:", l2, file=stdout2) assert l is l2 log.info("client: connection closed")
def unix_server(loop): directory = tempfile.mkdtemp() try: domain_socket = os.path.join(directory, 'aiomanhole') (server,) = loop.run_until_complete(start_manhole(path=domain_socket, loop=loop)) yield loop.run_until_complete(asyncio.open_unix_connection(path=domain_socket, loop=loop)) server.close() loop.run_until_complete(server.wait_closed()) finally: shutil.rmtree(directory)
async def open_connection(self, host, port, local_addr, lbind): if self.reuse or self.ssh: if self.streams is None or self.streams.done() and (self.reuse and not self.handler): self.streams = asyncio.get_event_loop().create_future() else: if not self.streams.done(): await self.streams return self.streams.result() try: if self.direct: if host == 'tunnel': raise Exception('Unknown tunnel endpoint') local_addr = local_addr if lbind == 'in' else (lbind, 0) if lbind else None family = 0 if local_addr is None else socket.AF_INET6 if ':' in local_addr[0] else socket.AF_INET wait = asyncio.open_connection(host=host, port=port, local_addr=local_addr, family=family) elif self.ssh: try: import asyncssh for s in ('read_', 'read_n', 'read_until'): setattr(asyncssh.SSHReader, s, getattr(asyncio.StreamReader, s)) except Exception: raise Exception('Missing library: "pip3 install asyncssh"') username, password = self.auth.decode().split(':', 1) if password.startswith(':'): client_keys = [password[1:]] password = None else: client_keys = None local_addr = local_addr if self.lbind == 'in' else (self.lbind, 0) if self.lbind else None family = 0 if local_addr is None else socket.AF_INET6 if ':' in local_addr[0] else socket.AF_INET conn = await asyncssh.connect(host=self.host_name, port=self.port, local_addr=local_addr, family=family, x509_trusted_certs=None, known_hosts=None, username=username, password=password, client_keys=client_keys) if not self.streams.done(): self.streams.set_result((conn, None)) return conn, None elif self.backward: wait = self.backward.open_connection() elif self.unix: wait = asyncio.open_unix_connection(path=self.bind, ssl=self.sslclient, server_hostname='' if self.sslclient else None) else: local_addr = local_addr if self.lbind == 'in' else (self.lbind, 0) if self.lbind else None family = 0 if local_addr is None else socket.AF_INET6 if ':' in local_addr[0] else socket.AF_INET wait = asyncio.open_connection(host=self.host_name, port=self.port, ssl=self.sslclient, local_addr=local_addr, family=family) reader, writer = await asyncio.wait_for(wait, timeout=SOCKET_TIMEOUT) except Exception as ex: if self.reuse: self.streams.set_exception(ex) self.streams = None raise return reader, writer
def update_socket_relay(self, update_socket): logging.info("Starting bridge socket") glossia_socket = update_socket _, writer = yield from asyncio.open_unix_connection(glossia_socket, loop=self._loop) logging.info("Connected") socket_location = os.path.join('/shared', 'update.sock') yield from asyncio.start_unix_server( functools.partial(handle_relay, writer), socket_location, loop=self._loop ) uid = pwd.getpwnam('glossia').pw_uid gid = grp.getgrnam('glossia').gr_gid os.chown(socket_location, uid, gid) logging.info("Server started")
async def connect(address, *, loop=None, closed_listeners=None): """Open a connection to Disque server. """ address = parse_address(address, host='127.0.0.1', port=7711) if address.proto == 'tcp': host, port = address.address future = asyncio.open_connection(host=host, port=port, loop=loop) elif address.proto == 'unix': path = address.address future = asyncio.open_unix_connection(path=path, loop=loop) reader, writer = await future return Connection(reader, writer, loop=loop, closed_listeners=closed_listeners)
def handshake(self): if sys.platform == 'linux' or sys.platform == 'darwin': self.sock_reader, self.sock_writer = yield from asyncio.open_unix_connection( self.ipc_path, loop=self.loop) elif sys.platform == 'win32' or sys.platform == 'win64': self.sock_reader = asyncio.StreamReader(loop=self.loop) reader_protocol = asyncio.StreamReaderProtocol(self.sock_reader, loop=self.loop) try: self.sock_writer, _ = yield from self.loop.create_pipe_connection( lambda: reader_protocol, self.ipc_path) except FileNotFoundError: raise InvalidPipe self.send_data(0, {'v': 1, 'client_id': self.client_id}) data = yield from self.sock_reader.read(1024) code, length = struct.unpack('<ii', data[:8])
def test_pause_socketpair_reader(self): """Test pausing and resuming reading from a socketpair""" data = 4*1024*1024*'*' sock1, sock2 = socket.socketpair() _, writer = yield from asyncio.open_unix_connection(sock=sock1) writer.write(data.encode()) writer.close() with (yield from self.connect()) as conn: result = yield from conn.run('delay', stdin=sock2, stderr=asyncssh.DEVNULL) self.assertEqual(result.stdout, data)
def test_pause_pipe_reader(self): """Test pausing and resuming reading from a socketpair""" data = 4*1024*1024*'*' sock1, sock2 = socket.socketpair() _, writer = yield from asyncio.open_unix_connection(sock=sock1) writer.write(data.encode()) writer.close() with (yield from self.connect()) as conn: result = yield from conn.run('delay', stdin=sock2, stderr=asyncssh.DEVNULL) self.assertEqual(result.stdout, data)
async def open_connection(self, host, port, local_addr, lbind): if self.reuse or self.ssh: if self.streams is None or self.streams.done() and (self.reuse and not self.handler): self.streams = asyncio.get_event_loop().create_future() else: if not self.streams.done(): await self.streams return self.streams.result() try: local_addr = local_addr if self.lbind == 'in' else (self.lbind, 0) if self.lbind else \ local_addr if lbind == 'in' else (lbind, 0) if lbind else None family = 0 if local_addr is None else socket.AF_INET6 if ':' in local_addr[0] else socket.AF_INET if self.direct: if host == 'tunnel': raise Exception('Unknown tunnel endpoint') wait = asyncio.open_connection(host=host, port=port, local_addr=local_addr, family=family) elif self.ssh: try: import asyncssh for s in ('read_', 'read_n', 'read_until'): setattr(asyncssh.SSHReader, s, getattr(asyncio.StreamReader, s)) except Exception: raise Exception('Missing library: "pip3 install asyncssh"') username, password = self.auth.decode().split(':', 1) if password.startswith(':'): client_keys = [password[1:]] password = None else: client_keys = None conn = await asyncssh.connect(host=self.host_name, port=self.port, local_addr=local_addr, family=family, x509_trusted_certs=None, known_hosts=None, username=username, password=password, client_keys=client_keys) if not self.streams.done(): self.streams.set_result((conn, None)) return conn, None elif self.backward: wait = self.backward.open_connection() elif self.unix: wait = asyncio.open_unix_connection(path=self.bind, ssl=self.sslclient, server_hostname='' if self.sslclient else None) else: wait = asyncio.open_connection(host=self.host_name, port=self.port, ssl=self.sslclient, local_addr=local_addr, family=family) reader, writer = await asyncio.wait_for(wait, timeout=SOCKET_TIMEOUT) except Exception as ex: if self.reuse: self.streams.set_exception(ex) self.streams = None raise return reader, writer
async def open_connection(self, host, port, local_addr, lbind): if self.reuse: if self.streams is None or self.streams.done( ) and not self.handler: self.streams = asyncio.get_event_loop().create_future() else: if not self.streams.done(): await self.streams return self.streams.result() try: if self.direct: if host == 'tunnel': raise Exception('Unknown tunnel endpoint') local_addr = local_addr if lbind == 'in' else ( lbind, 0) if lbind else None family = 0 if local_addr is None else 30 if ':' in local_addr[ 0] else 2 wait = asyncio.open_connection(host=host, port=port, local_addr=local_addr, family=family) elif self.backward: wait = self.backward.open_connection() elif self.unix: wait = asyncio.open_unix_connection( path=self.bind, ssl=self.sslclient, server_hostname='' if self.sslclient else None) else: local_addr = local_addr if self.lbind == 'in' else ( self.lbind, 0) if self.lbind else None family = 0 if local_addr is None else 30 if ':' in local_addr[ 0] else 2 wait = asyncio.open_connection(host=self.host_name, port=self.port, ssl=self.sslclient, local_addr=local_addr, family=family) reader, writer = await asyncio.wait_for(wait, timeout=SOCKET_TIMEOUT) except Exception as ex: if self.reuse: self.streams.set_exception(ex) self.streams = None raise return reader, writer
def _create_new_conn(self): if self.size() < self._maxsize: if isinstance(self._unix, str) and os.path.exists(self._unix): reader, writer = yield from asyncio.open_unix_connection( path=self._unix, loop=self._loop) else: reader, writer = yield from asyncio.open_connection( self._host, self._port, loop=self._loop) if self.size() < self._maxsize: return _connection(reader, writer) else: reader.feed_eof() writer.close() return None else: return None
def _connect(self): # TODO: Set close callback # raise OperationalError(2006, # "MySQL server has gone away (%r)" % (e,)) try: if self._unix_socket and self._host in ('localhost', '127.0.0.1'): self._reader, self._writer = yield from \ asyncio.open_unix_connection(self._unix_socket, loop=self._loop) self.host_info = "Localhost via UNIX socket: " + \ self._unix_socket else: self._reader, self._writer = yield from \ asyncio.open_connection(self._host, self._port, loop=self._loop) self._set_keep_alive() self.host_info = "socket %s:%d" % (self._host, self._port) # do not set no delay in case of unix_socket if self._no_delay and not self._unix_socket: self._set_nodelay(True) self._next_seq_id = 0 yield from self._get_server_information() yield from self._request_authentication() self.connected_time = self._loop.time() if self.sql_mode is not None: yield from self.query("SET sql_mode=%s" % (self.sql_mode, )) if self.init_command is not None: yield from self.query(self.init_command) yield from self.commit() if self.autocommit_mode is not None: yield from self.autocommit(self.autocommit_mode) except Exception as e: if self._writer: self._writer.transport.close() self._reader = None self._writer = None raise OperationalError( 2003, "Can't connect to MySQL server on %r" % self._host) from e
def _setUp(self): self.r, self.w = yield from asyncio.open_unix_connection(self.path) config = H2Configuration(header_encoding='utf-8') self.conn = H2Connection(config=config) self.conn.initiate_connection() self.w.write(self.conn.data_to_send()) events = yield from self._expect_events(3) self.assertIsInstance(events[0], RemoteSettingsChanged) self.assertIsInstance(events[1], RemoteSettingsChanged) self.assertIsInstance(events[2], SettingsAcknowledged) self.assertIsInstance((yield from self.server.events.get()), RemoteSettingsChanged) self.assertIsInstance((yield from self.server.events.get()), SettingsAcknowledged) self.assertIsInstance((yield from self.server.events.get()), SettingsAcknowledged)
def create_connection(address, *, db=None, password=None, ssl=None, encoding=None, loop=None): """Creates redis connection. Opens connection to Redis server specified by address argument. Address argument is similar to socket address argument, ie: * when address is a tuple it represents (host, port) pair; * when address is a str it represents unix domain socket path. (no other address formats supported) SSL argument is passed through to asyncio.create_connection. By default SSL/TLS is not used. Encoding argument can be used to decode byte-replies to strings. By default no decoding is done. Return value is RedisConnection instance. This function is a coroutine. """ assert isinstance(address, (tuple, list, str)), "tuple or str expected" if isinstance(address, (list, tuple)): host, port = address logger.debug("Creating tcp connection to %r", address) reader, writer = yield from asyncio.open_connection( host, port, ssl=ssl, loop=loop) sock = writer.transport.get_extra_info('socket') if sock is not None: sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) else: logger.debug("Creating unix connection to %r", address) reader, writer = yield from asyncio.open_unix_connection( address, ssl=ssl, loop=loop) conn = RedisConnection(reader, writer, encoding=encoding, loop=loop) try: if password is not None: yield from conn.auth(password) if db is not None: yield from conn.select(db) except Exception: conn.close() yield from conn.wait_closed() raise return conn
def _get_events_reader(self, vm=None) -> (asyncio.StreamReader, callable): '''Make connection to qubesd and return stream to read events from :param vm: Specific VM for which events should be handled, use None to handle events from all VMs (and non-VM objects) :return stream to read events from and a cleanup function (call it to terminate qubesd connection)''' if vm is not None: dest = vm.name else: dest = 'dom0' if self.app.qubesd_connection_type == 'socket': reader, writer = yield from asyncio.open_unix_connection( qubesadmin.config.QUBESD_SOCKET) writer.write(b'dom0\0') # source writer.write(self._api_method.encode() + b'\0') # method writer.write(dest.encode('ascii') + b'\0') # dest writer.write(b'\0') # arg writer.write_eof() def cleanup_func(): '''Close connection to qubesd''' writer.close() elif self.app.qubesd_connection_type == 'qrexec': proc = yield from asyncio.create_subprocess_exec( 'qrexec-client-vm', dest, self._api_method, stdin=subprocess.PIPE, stdout=subprocess.PIPE) proc.stdin.write_eof() reader = proc.stdout def cleanup_func(): '''Close connection to qubesd''' try: proc.kill() except ProcessLookupError: pass else: raise NotImplementedError('Unsupported qubesd connection type: ' + self.app.qubesd_connection_type) return reader, cleanup_func
def _connect(self): # TODO: Set close callback # raise OperationalError(2006, # "MySQL server has gone away (%r)" % (e,)) try: if self._unix_socket and self._host in ('localhost', '127.0.0.1'): self._reader, self._writer = yield from \ asyncio.open_unix_connection(self._unix_socket, loop=self._loop) self.host_info = "Localhost via UNIX socket: " + \ self._unix_socket else: self._reader, self._writer = yield from \ asyncio.open_connection(self._host, self._port, loop=self._loop) self.host_info = "socket %s:%d" % (self._host, self._port) # do not set no delay in case of unix_socket if self._no_delay and not self._unix_socket: self._set_nodelay(True) self._next_seq_id = 0 yield from self._get_server_information() yield from self._request_authentication() self.connected_time = self._loop.time() if self.sql_mode is not None: yield from self.query("SET sql_mode=%s" % (self.sql_mode,)) if self.init_command is not None: yield from self.query(self.init_command) yield from self.commit() if self.autocommit_mode is not None: yield from self.autocommit(self.autocommit_mode) except Exception as e: if self._writer: self._writer.transport.close() self._reader = None self._writer = None raise OperationalError(2003, "Can't connect to MySQL server on %r" % self._host) from e
async def connect(self) -> None: if self.host.startswith('/'): self.reader, self.writer = await asyncio.wait_for( asyncio.open_unix_connection(path=self.host), timeout=self.options.pool_options.connect_timeout) else: self.reader, self.writer = await asyncio.wait_for( asyncio.open_connection(host=self.host, port=self.port), timeout=self.options.pool_options.connect_timeout) sock = self.writer.transport.get_extra_info('socket') sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, int(self.options.pool_options.socket_keepalive)) if self.host.startswith('/'): endpoint = self.host else: endpoint = '{}:{}'.format(self.host, self.port) logger.debug('Established connection to {}'.format(endpoint)) self.read_loop_task = asyncio.ensure_future(self.read_loop()) self.read_loop_task.add_done_callback(self._on_read_loop_task_done) is_master = await self.is_master( ignore_connected= True, # allow the request whilst __connected is not set yet ) self.is_mongos = is_master.server_type == SERVER_TYPE.Mongos self.max_wire_version = is_master.max_wire_version if is_master.max_bson_size: self.max_bson_size = is_master.max_bson_size if is_master.max_message_size: self.max_message_size = is_master.max_message_size if is_master.max_write_batch_size: self.max_write_batch_size = is_master.max_write_batch_size self.is_writable = is_master.is_writable self.slave_ok = not self.is_mongos and self.options.read_preference != ReadPreference.PRIMARY if self.options.credentials: await self._authenticate() # Notify waiters that connection has been established self.__connected.set()
async def open_uds_socket_stream( path: str, hostname: str, timeout: httpx.Timeout, ssl_context: ssl.SSLContext = None ) -> BaseSocketStream: async_library = sniffio.current_async_library() assert async_library == "asyncio" server_hostname = hostname if ssl_context else None try: stream_reader, stream_writer = await asyncio.wait_for( asyncio.open_unix_connection( path, ssl=ssl_context, server_hostname=server_hostname ), timeout.connect_timeout, ) except asyncio.TimeoutError: raise httpx.ConnectTimeout() return SocketStream(stream_reader=stream_reader, stream_writer=stream_writer)
def unix_socket_client(command, socketpath): reader, writer = yield from asyncio.open_unix_connection(socketpath) # command += "\n" # readline() in the other end! # read(1024) on the other end writer.write(command.encode()) data = yield from reader.read(-1) msg = data.decode() # If JSON, we might pretty-print: try: msg = json.loads(msg) # pprint.PrettyPrinter(indent=1, width=80, compact=True) pprint.pprint(msg, width=172, compact=True) except json.decoder.JSONDecodeError: print(msg) writer.close()
def client(loop, core_socket): reader, writer = loop.run_until_complete( asyncio.open_unix_connection(path=core_socket)) class CoreClient: def __init__(self, reader, writer): self.reader = reader self.writer = writer async def send_cmd(self, cmd, **kwargs): msg = {'cmd': cmd, **kwargs} raw_msg = ejson_dumps(msg).encode() self.writer.write(raw_msg) self.writer.write(b'\n') raw_resp = await self.reader.readline() return ejson_loads(raw_resp.decode()) yield CoreClient(reader, writer) writer.close()
def create_connection(address, *, db=None, password=None, encoding=None, loop=None): """Creates redis connection. Opens connection to Redis server specified by address argument. Address argument is similar to socket address argument, ie: * when address is a tuple it represents (host, port) pair; * when address is a str it represents unix domain socket path. (no other address formats supported) Encoding argument can be used to decode byte-replies to strings. By default no decoding is done. Return value is RedisConnection instance. This function is a coroutine. """ assert isinstance(address, (tuple, list, str)), "tuple or str expected" if isinstance(address, (list, tuple)): host, port = address reader, writer = yield from asyncio.open_connection(host, port, loop=loop) else: reader, writer = yield from asyncio.open_unix_connection(address, loop=loop) conn = RedisConnection(reader, writer, encoding=encoding, loop=loop) try: if password is not None: yield from conn.auth(password) if db is not None: yield from conn.select(db) except Exception: conn.close() yield from conn.wait_closed() raise return conn
async def async_send(self, msg: Any) -> Any: try: reader, writer = await asyncio.wait_for( asyncio.open_unix_connection(path=self.fname), timeout=3) except ConnectionRefusedError: raise IPCError("Could not open {}".format(self.fname)) send_data = _IPC.pack(msg, is_json=self.is_json) writer.write(send_data) writer.write_eof() try: read_data = await asyncio.wait_for(reader.read(), timeout=10) except asyncio.TimeoutError: raise IPCError("Server not responding") data, _ = _IPC.unpack(read_data, is_json=self.is_json) return data
async def open_uds_stream( self, path: str, hostname: typing.Optional[str], ssl_context: typing.Optional[ssl.SSLContext], timeout: Timeout, ) -> SocketStream: server_hostname = hostname if ssl_context else None try: stream_reader, stream_writer = await asyncio.wait_for( # type: ignore asyncio.open_unix_connection( path, ssl=ssl_context, server_hostname=server_hostname ), timeout.connect_timeout, ) except asyncio.TimeoutError: raise ConnectTimeout() return SocketStream(stream_reader=stream_reader, stream_writer=stream_writer)
async def open_uds_stream( self, path: str, hostname: bytes, ssl_context: Optional[SSLContext], timeout: TimeoutDict, ) -> AsyncSocketStream: host = hostname.decode("ascii") connect_timeout = timeout.get("connect") kwargs: dict = { "server_hostname": host } if ssl_context is not None else {} exc_map = {asyncio.TimeoutError: ConnectTimeout, OSError: ConnectError} with map_exceptions(exc_map): stream_reader, stream_writer = await asyncio.wait_for( asyncio.open_unix_connection(path, ssl=ssl_context, **kwargs), connect_timeout, ) return SocketStream(stream_reader=stream_reader, stream_writer=stream_writer)
def _wait_for_communication_container(self, path): # type: (str) -> Communicator r"""Wait for communication container to start. Assumption is that the communication container is accepting connections and will send a single b"PING\n" when connected. :raises: if unable to connect for COMMUNICATOR_WAIT_TIMEOUT seconds. """ for _ in range(COMMUNICATION_CONTAINER_TIMEOUT): try: reader, writer = yield from asyncio.open_unix_connection(path) line = (yield from reader.readline()).decode("utf-8") assert line.strip() == "PING" return Communicator(reader, writer) except: with suppress(Exception): writer.close() yield from writer.wait_closed() time.sleep(1) raise RuntimeError("Communication container is unreacheable.")
def create_connection(address, *, encoding=None, loop=None): """Creates GibsonConnection connection. Opens connection to Gibson server specified by address argument. :param address: ``str`` for unix socket path, or ``tuple`` for (host, port) tcp connection. :param encoding: this argument can be used to decode byte-replies to strings. By default no decoding is done. """ assert isinstance(address, (tuple, list, str)), "tuple or str expected" if isinstance(address, (list, tuple)): host, port = address reader, writer = yield from asyncio.open_connection( host, port, loop=loop) else: reader, writer = yield from asyncio.open_unix_connection( address, loop=loop) conn = GibsonConnection(reader, writer, address=address, encoding=encoding, loop=loop) return conn
def listen_client(loop): """ Create client to listen for lines of data""" reader, writer = yield from asyncio.open_unix_connection( path='/tmp/mys.sock', loop=loop) # uncomment following lines and remove # open_unix_connection line to use port # reader, writer = yield from asyncio.open_connection(host='127.0.0.1', # port=8877, # loop=loop) while True: data = yield from reader.readline() if data: cleaned = json.loads(data.decode()) print('Received: %s' % cleaned) # DO SOMETHING :) else: print('Close the socket') writer.close() return
def test_uds_server(event_loop, tmpdir): path = str(tmpdir / "test.uds") server = yield from start_console_server(path=path, banner='test') stream = io.StringIO() print_server(server, "test console", file=stream) expected = "The test console is being served on {}\n" assert stream.getvalue() == expected.format(path) address = server.sockets[0].getsockname() reader, writer = yield from asyncio.open_unix_connection(address) assert (yield from reader.readline()) == b'test\n' writer.write(b'1+1\n') assert (yield from reader.readline()) == b'>>> 2\n' writer.write_eof() assert (yield from reader.readline()) == b'>>> \n' writer.close() if compat.PY37: yield from writer.wait_closed() server.close() yield from server.wait_closed()
async def _do_connect(self, address: SocketAddrT, ssl: Optional[SSLContext] = None) -> None: """ Acting as the transport client, initiate a connection to a server. :param address: Address to connect to; UNIX socket path or TCP address/port. :param ssl: SSL context to use, if any. :raise OSError: For stream-related errors. """ assert self.runstate == Runstate.IDLE self._set_state(Runstate.CONNECTING) # Allow runstate watchers to witness 'CONNECTING' state; some # failures in the streaming layer are synchronous and will not # otherwise yield. await asyncio.sleep(0) self.logger.debug("Connecting to %s ...", address) if isinstance(address, tuple): connect = asyncio.open_connection( address[0], address[1], ssl=ssl, limit=self._limit, ) else: connect = asyncio.open_unix_connection( path=address, ssl=ssl, limit=self._limit, ) self._reader, self._writer = await connect self.logger.debug("Connected.")
async def server_run(self, handler): errwait = 0 while not self.closed: if self.uri.unix: wait = asyncio.open_unix_connection(path=self.uri.bind, ssl=self.uri.sslclient, server_hostname='' if self.uri.sslclient else None) else: wait = asyncio.open_connection(host=self.uri.host_name, port=self.uri.port, ssl=self.uri.sslclient, local_addr=(self.uri.lbind, 0) if self.uri.lbind else None) try: reader, writer = await asyncio.wait_for(wait, timeout=SOCKET_TIMEOUT) self.writer = writer data = await reader.read_() if data: reader._buffer[0:0] = data asyncio.ensure_future(handler(reader, writer)) errwait = 0 except Exception as ex: try: writer.close() except Exception: pass if not self.closed: await asyncio.sleep(errwait) errwait = errwait*1.3 + 0.1
async def send_command(self, cmd=None, kwargs=None): try: if kwargs is None: kwargs = {} self.logger.info(f'send_command {cmd} with kwargs {kwargs}') message = json.dumps({'cmd':cmd, 'kwargs':kwargs}).encode() message = Structures.MSG_4_STRUCT.pack(len(message)) + message reader, writer = await asyncio.wait_for(asyncio.open_unix_connection(path=self.connector.uds_path_commander), timeout=self.ASYNC_TIMEOUT) writer.write(message) try: await asyncio.wait_for(writer.drain(), timeout=self.ASYNC_TIMEOUT) except Exception: self.logger.exception('send_command writer drain') next_length_bytes = await reader.readexactly(Structures.MSG_4_STRUCT.size) next_length = Structures.MSG_4_STRUCT.unpack(next_length_bytes)[0] response = await asyncio.wait_for(reader.readexactly(next_length), timeout=self.ASYNC_TIMEOUT) writer.close() self.logger.info(f'send_command got response {response}') except Exception as exc: self.logger.exception('send_command') response = str(exc).encode() return response
def test_open_unix_connection(self): with test_utils.run_test_unix_server() as httpd: conn_fut = asyncio.open_unix_connection(httpd.address, loop=self.loop) self._basetest_open_connection(conn_fut)
def __init__(self, path): self.reader, self.writer = asyncio.open_unix_connection(path)
def create_connection(port=None, path=None): if port: return asyncio.open_connection('localhost', port=port) else: return asyncio.open_unix_connection(path=path)
def wait_open_connection(self, host, port, local_addr, family): if self.unix: return asyncio.open_unix_connection(path=self.bind) else: return asyncio.open_connection(host=self.host_name, port=self.port, local_addr=local_addr, family=family)
def connect_bus(infos, *, allowed_methods=_supported_methods, factory=ConnectionFactory, loop=None, **kws): """Accepts a sequence/generator of dictionaries describing possible bus endpoints. Tries to connect to each until one succeeds. A coroutine :returns: Connection """ for info in infos: R, W = None, None try: _log.debug('Trying bus %s', info) if 'unix:abstract' in info: R, W = yield from asyncio.open_unix_connection('\0'+info['unix:abstract'], loop=loop) elif 'unix:path' in info: R, W = yield from asyncio.open_unix_connection(info['unix:path'], loop=loop) else: _log.debug('No supported transport: %s', info) continue #TODO: transports not yet handled # 'nonce-tcp:host=xxx,port=...,family=...,noncefile=' # 'tcp:host=xxx,port=...,family=...' # 'unixexec:path=...,arg0=...,...' # start authentication phase W.write(b'\0AUTH\r\n') L = yield from R.readline() if not L.startswith(b'REJECTED'): raise RuntimeError('Bad auth phase (not dbus?)') methods = set(L.decode('ascii').strip().split(' ')[1:]) ok = False _log.debug('Advertised auth methods: %s', methods) methods.intersection_update(allowed_methods) _log.debug('Proceed with methods: %s', methods) if not ok and 'EXTERNAL' in methods: _log.debug('Attempt EXTERNAL') W.write(b'AUTH EXTERNAL '+hexencode(str(os.getuid()).encode('ascii'))+b'\r\n') L = yield from R.readline() if L.startswith(b'OK'): ok = True _log.debug('EXTERNAL accepted') elif L.startswith(b'REJECTED'): _log.debug('EXTERNAL rejected: %s', L) else: raise RuntimeError('EXTERNAL incomplete: %s'%L) # TODO: not working if not ok and 'ANONYMOUS' in methods: _log.debug('Attempt ANONYMOUS') W.write(b'AUTH ANONYMOUS'+hexencode(b'Nemo')+b'\r\n') if L.startswith(b'OK'): ok = True _log.debug('ANONYMOUS accepted') elif L.startswith(b'REJECTED'): _log.debug('ANONYMOUS rejected: %s', L) else: raise RuntimeError('ANONYMOUS incomplete: %s'%L) if not ok: _log.debug('No supported auth method') continue else: # TODO: NEGOTIATE_UNIX_FD W.write(b'BEGIN\r\n') _log.debug('Authenticated with bus %s', info) conn = factory(W, R, info, loop=loop, **kws) except: if W is not None: W.close() _log.exception("Can't attach to %s", info) continue # Connection now has responsibility for call R.close() try: yield from conn.setup() except: conn.close() raise return conn raise RuntimeError('No Bus')
async def setup_connection(self): connection = asyncio.open_unix_connection(self._socket) reader, writer = await connection self._writer = writer self.start_read_loop(reader)
async def send_message(self, message_type=None, destination_id=None, request_id=None, response_id=None, data=None, data_is_json=True, binary=None, await_response=False, with_file=None, wait_for_ack=False, message_type_publish=None, await_response_timeout=None): #, reuse_uds_connection=True): try: if data_is_json: data = json.dumps(data) #, ensure_ascii=False) if not self.is_server and not destination_id: destination_id = str(self.server_sockaddr) self.logger.debug(f'send_message of type {message_type}, destination_id {destination_id}, ' f'request_id {request_id}, response_id {response_id}') message_bytes = self.pack_message(data=data, message_type=message_type, source_id=self.source_id, destination_id=destination_id, request_id=request_id, response_id=response_id, binary=binary, await_response=await_response, with_file=with_file, wait_for_ack=wait_for_ack, message_type_publish=message_type_publish) send_message_lock_internally_acquired = False if self.uds_path_send_preserve_socket and not await_response: #try to reuse connection to uds if not self.reader_writer_uds_path_send: #either there is really no reader_writer_uds_path_send, or the send_message_lock is currently #locked by another send_message which is #in the process of creating a reader_writer_uds_path_send. #In such a case, we wait for send_message_lock, and check again if reader_writer_uds_path_send exists. try: await asyncio.wait_for(self.send_message_lock.acquire(), self.ASYNC_TIMEOUT) except asyncio.CancelledError: raise except asyncio.TimeoutError: self.logger.warning('send_message could not acquire send_message_lock') return False else: #reader_writer_uds_path_send may have changed during wait_for(self.send_message_lock.acquire()) : #checking again if reader_writer_uds_path_send exists if self.reader_writer_uds_path_send: #a new check reader_writer_uds_path_send has just been created by another send_message task : use it ! try: self.send_message_lock.release() except Exception: self.logger.exception('send_message_lock release') else: #we acquired send_message_lock, and there is no reader_writer_uds_path_send : #we set send_message_lock_internally_acquired #to prevent waiting a second time for send_message_lock in the following send_message_lock_internally_acquired = True if self.reader_writer_uds_path_send: try: reader, writer = self.reader_writer_uds_path_send writer.write(message_bytes[:Structures.MSG_4_STRUCT.size]) writer.write(message_bytes[Structures.MSG_4_STRUCT.size:]) await writer.drain() self.logger.debug('send_message reusing existing connection') return True except Exception: #now we need to create a new connection self.reader_writer_uds_path_send = None self.logger.exception('send_message uds_path_send_preserve_socket') try: writer.close() except Exception: pass self.logger.debug('send_message creating new connection') try: #in case send_message is called as a task, we need the send_message_lock when #creating a new connection to uds_path_send_to_connector #otherwise the order of messages can be messed up. #And also the shared reader_writer_uds_path_send mechanism can be messed up if not send_message_lock_internally_acquired: await asyncio.wait_for(self.send_message_lock.acquire(), self.ASYNC_TIMEOUT) reader, writer = await asyncio.wait_for(asyncio.open_unix_connection(path=self.uds_path_send_to_connector, limit=self.MAX_SOCKET_BUFFER_SIZE), timeout=self.ASYNC_TIMEOUT) if self.uds_path_send_preserve_socket and not await_response: self.reader_writer_uds_path_send = reader, writer except asyncio.CancelledError: raise except Exception as exc: #ConnectionRefusedError: or TimeoutError self.logger.warning(f'send_message could not connect to {self.uds_path_send_to_connector} : {exc}') return False finally: try: if self.send_message_lock.locked(): self.send_message_lock.release() except Exception: self.logger.exception('send_message_lock release') writer.write(message_bytes[:Structures.MSG_4_STRUCT.size]) writer.write(message_bytes[Structures.MSG_4_STRUCT.size:]) try: await asyncio.wait_for(writer.drain(), timeout=self.ASYNC_TIMEOUT) except asyncio.CancelledError: raise except Exception: self.logger.exception('send_message writer drain') #beware to not lock the await_response recv_message with send_message_lock if await_response: if await_response_timeout is not None: try: the_response = await asyncio.wait_for(self.recv_message(reader, writer), timeout=await_response_timeout) except asyncio.TimeoutError: self.logger.warning(f'send_message : await_response_timeout error ({await_response_timeout} s)') writer.close() return False else: the_response = await self.recv_message(reader, writer) self.logger.debug('send_message finished sending') if await_response: writer.close() return the_response return True except asyncio.CancelledError: self.logger.warning('send_message : CancelledError') raise except asyncio.IncompleteReadError: self.logger.warning('send_message : peer disconnected') return False except ConnectionResetError as exc: self.logger.warning('ConnectionResetError : '+str(exc)) except Exception as exc: self.logger.exception('send_data') return False