Esempio n. 1
0
 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')
Esempio n. 2
0
    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)
Esempio n. 3
0
    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))
Esempio n. 4
0
    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
Esempio n. 5
0
 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()
Esempio n. 6
0
    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)
Esempio n. 7
0
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()))
Esempio n. 8
0
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
Esempio n. 9
0
    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))
Esempio n. 10
0
    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
Esempio n. 11
0
    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
Esempio n. 12
0
 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
Esempio n. 13
0
    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)
Esempio n. 14
0
    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)
Esempio n. 15
0
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))
Esempio n. 17
0
 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()
Esempio n. 18
0
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
Esempio n. 19
0
    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()
Esempio n. 20
0
    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)
Esempio n. 21
0
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))
Esempio n. 22
0
File: test.py Progetto: tsavola/tap
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")
Esempio n. 23
0
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)
Esempio n. 24
0
 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
Esempio n. 25
0
 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")
Esempio n. 26
0
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)
Esempio n. 27
0
 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])
Esempio n. 28
0
    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)
Esempio n. 29
0
    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)
Esempio n. 30
0
 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
Esempio n. 31
0
 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
Esempio n. 32
0
    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
Esempio n. 33
0
    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
Esempio n. 34
0
    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)
Esempio n. 35
0
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
Esempio n. 36
0
    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
Esempio n. 37
0
    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
Esempio n. 38
0
    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)
Esempio n. 40
0
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()
Esempio n. 41
0
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()
Esempio n. 42
0
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
Esempio n. 43
0
    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
Esempio n. 44
0
    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)
Esempio n. 45
0
 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.")
Esempio n. 47
0
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
Esempio n. 48
0
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
Esempio n. 49
0
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()
Esempio n. 50
0
    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.")
Esempio n. 51
0
 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
Esempio n. 52
0
 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
Esempio n. 53
0
 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
Esempio n. 54
0
 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)
Esempio n. 55
0
 def __init__(self, path):
   self.reader, self.writer = asyncio.open_unix_connection(path)
Esempio n. 56
0
def create_connection(port=None, path=None):
    if port:
        return asyncio.open_connection('localhost', port=port)

    else:
        return asyncio.open_unix_connection(path=path)
Esempio n. 57
0
 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)
Esempio n. 58
0
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)
Esempio n. 60
0
    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