Esempio n. 1
0
async def test_client_connect_will_flag(broker, event_loop):
    conn_reader, conn_writer = await asyncio.open_connection("127.0.0.1",
                                                             1883,
                                                             loop=event_loop)
    reader = StreamReaderAdapter(conn_reader)
    writer = StreamWriterAdapter(conn_writer)

    vh = ConnectVariableHeader()
    payload = ConnectPayload()

    vh.keep_alive = 10
    vh.clean_session_flag = False
    vh.will_retain_flag = False
    vh.will_flag = True
    vh.will_qos = QOS_0
    payload.client_id = "test_id"
    payload.will_message = b"test"
    payload.will_topic = "/topic"
    connect = ConnectPacket(vh=vh, payload=payload)
    await connect.to_stream(writer)
    await ConnackPacket.from_stream(reader)

    await asyncio.sleep(0.1)

    disconnect = DisconnectPacket()
    await disconnect.to_stream(writer)

    await asyncio.sleep(0.1)
Esempio n. 2
0
async def test_client_publish_dup(broker, event_loop):
    conn_reader, conn_writer = await asyncio.open_connection("127.0.0.1",
                                                             1883,
                                                             loop=event_loop)
    reader = StreamReaderAdapter(conn_reader)
    writer = StreamWriterAdapter(conn_writer)

    vh = ConnectVariableHeader()
    payload = ConnectPayload()

    vh.keep_alive = 10
    vh.clean_session_flag = False
    vh.will_retain_flag = False
    payload.client_id = "test_id"
    connect = ConnectPacket(vh=vh, payload=payload)
    await connect.to_stream(writer)
    await ConnackPacket.from_stream(reader)

    publish_1 = PublishPacket.build("/test", b"data", 1, False, QOS_2, False)
    await publish_1.to_stream(writer)
    asyncio.ensure_future(PubrecPacket.from_stream(reader), loop=event_loop)

    await asyncio.sleep(2)

    publish_dup = PublishPacket.build("/test", b"data", 1, True, QOS_2, False)
    await publish_dup.to_stream(writer)
    await PubrecPacket.from_stream(reader)
    pubrel = PubrelPacket.build(1)
    await pubrel.to_stream(writer)
    await PubcompPacket.from_stream(reader)

    disconnect = DisconnectPacket()
    await disconnect.to_stream(writer)
Esempio n. 3
0
        async def test_coro():
            try:
                broker = Broker(
                    self._test_config, plugin_namespace="hbmqtt.test.plugins"
                )
                await broker.start()
                self.assertTrue(broker.transitions.is_started())

                conn_reader, conn_writer = await asyncio.open_connection(
                    "127.0.0.1", self._test_port, loop=self.loop
                )
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)

                vh = ConnectVariableHeader()
                payload = ConnectPayload()

                vh.keep_alive = 10
                vh.clean_session_flag = False
                vh.will_retain_flag = False
                payload.client_id = "test_id"
                connect = ConnectPacket(vh=vh, payload=payload)
                await connect.to_stream(writer)
                await ConnackPacket.from_stream(reader)

                publish_1 = PublishPacket.build(
                    "/test", b"data", 1, False, QOS_2, False
                )
                await publish_1.to_stream(writer)
                asyncio.ensure_future(PubrecPacket.from_stream(reader), loop=self.loop)

                await asyncio.sleep(2)

                publish_dup = PublishPacket.build(
                    "/test", b"data", 1, True, QOS_2, False
                )
                await publish_dup.to_stream(writer)
                await PubrecPacket.from_stream(reader)
                pubrel = PubrelPacket.build(1)
                await pubrel.to_stream(writer)
                await PubcompPacket.from_stream(reader)

                disconnect = DisconnectPacket()
                await disconnect.to_stream(writer)

                await asyncio.sleep(0.1)
                await broker.shutdown()
                future.set_result(True)
            except Exception as ae:
                future.set_exception(ae)
Esempio n. 4
0
        def test_coro():
            try:
                broker = Broker(test_config,
                                plugin_namespace="hbmqtt.test.plugins")
                yield from broker.start()
                self.assertTrue(broker.transitions.is_started())

                conn_reader, conn_writer = \
                    yield from asyncio.open_connection('127.0.0.1', 1883, loop=self.loop)
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)

                vh = ConnectVariableHeader()
                payload = ConnectPayload()

                vh.keep_alive = 10
                vh.clean_session_flag = False
                vh.will_retain_flag = False
                payload.client_id = 'test_id'
                connect = ConnectPacket(vh=vh, payload=payload)
                yield from connect.to_stream(writer)
                yield from ConnackPacket.from_stream(reader)

                publish_1 = PublishPacket.build('/test', b'data', 1, False,
                                                QOS_2, False)
                yield from publish_1.to_stream(writer)
                asyncio.ensure_future(PubrecPacket.from_stream(reader),
                                      loop=self.loop)

                yield from asyncio.sleep(2)

                publish_dup = PublishPacket.build('/test', b'data', 1, True,
                                                  QOS_2, False)
                yield from publish_dup.to_stream(writer)
                yield from PubrecPacket.from_stream(reader)
                pubrel = PubrelPacket.build(1)
                yield from pubrel.to_stream(writer)
                yield from PubcompPacket.from_stream(reader)

                disconnect = DisconnectPacket()
                yield from disconnect.to_stream(writer)

                yield from asyncio.sleep(0.1)
                yield from broker.shutdown()
                future.set_result(True)
            except Exception as ae:
                future.set_exception(ae)
Esempio n. 5
0
        async def test_coro():
            try:
                broker = Broker(
                    self._test_config, plugin_namespace="hbmqtt.test.plugins"
                )
                await broker.start()
                self.assertTrue(broker.transitions.is_started())

                conn_reader, conn_writer = await asyncio.open_connection(
                    "127.0.0.1", self._test_port, loop=self.loop
                )
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)

                vh = ConnectVariableHeader()
                payload = ConnectPayload()

                vh.keep_alive = 10
                vh.clean_session_flag = False
                vh.will_retain_flag = False
                vh.will_flag = True
                vh.will_qos = QOS_0
                payload.client_id = "test_id"
                payload.will_message = b"test"
                payload.will_topic = "/topic"
                connect = ConnectPacket(vh=vh, payload=payload)
                await connect.to_stream(writer)
                await ConnackPacket.from_stream(reader)

                await asyncio.sleep(0.1)

                disconnect = DisconnectPacket()
                await disconnect.to_stream(writer)

                await asyncio.sleep(0.1)
                await broker.shutdown()
                self.assertTrue(broker.transitions.is_stopped())
                self.assertDictEqual(broker._sessions, {})
                future.set_result(True)
            except Exception as ae:
                future.set_exception(ae)
Esempio n. 6
0
        def test_coro():
            try:
                broker = Broker(test_config,
                                plugin_namespace="hbmqtt.test.plugins")
                yield from broker.start()
                self.assertTrue(broker.transitions.is_started())

                conn_reader, conn_writer = \
                    yield from asyncio.open_connection('localhost', 1883, loop=self.loop)
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)

                vh = ConnectVariableHeader()
                payload = ConnectPayload()

                vh.keep_alive = 10
                vh.clean_session_flag = False
                vh.will_retain_flag = False
                vh.will_flag = True
                vh.will_qos = QOS_0
                payload.client_id = 'test_id'
                payload.will_message = b'test'
                payload.will_topic = '/topic'
                connect = ConnectPacket(vh=vh, payload=payload)
                yield from connect.to_stream(writer)
                yield from ConnackPacket.from_stream(reader)

                yield from asyncio.sleep(0.1)

                disconnect = DisconnectPacket()
                yield from disconnect.to_stream(writer)

                yield from asyncio.sleep(0.1)
                yield from broker.shutdown()
                self.assertTrue(broker.transitions.is_stopped())
                self.assertDictEqual(broker._sessions, {})
                future.set_result(True)
            except Exception as ae:
                future.set_exception(ae)
Esempio n. 7
0
def adapt(reader, writer):
    return StreamReaderAdapter(reader), StreamWriterAdapter(writer)
Esempio n. 8
0
    async def _connect_coro(self):
        kwargs = dict()

        # Decode URI attributes
        uri_attributes = urlparse(self.session.broker_uri)
        scheme = uri_attributes.scheme
        secure = True if scheme in ("mqtts", "wss") else False
        self.session.username = (self.session.username if self.session.username
                                 else uri_attributes.username)
        self.session.password = (self.session.password if self.session.password
                                 else uri_attributes.password)
        self.session.remote_address = uri_attributes.hostname
        self.session.remote_port = uri_attributes.port
        if scheme in ("mqtt", "mqtts") and not self.session.remote_port:
            self.session.remote_port = 8883 if scheme == "mqtts" else 1883
        if scheme in ("ws", "wss") and not self.session.remote_port:
            self.session.remote_port = 443 if scheme == "wss" else 80
        if scheme in ("ws", "wss"):
            # Rewrite URI to conform to https://tools.ietf.org/html/rfc6455#section-3
            uri = (
                scheme,
                self.session.remote_address + ":" +
                str(self.session.remote_port),
                uri_attributes[2],
                uri_attributes[3],
                uri_attributes[4],
                uri_attributes[5],
            )
            self.session.broker_uri = urlunparse(uri)
        # Init protocol handler
        # if not self._handler:
        self._handler = ClientProtocolHandler(self.plugins_manager,
                                              loop=self._loop)

        if secure:
            sc = ssl.create_default_context(
                ssl.Purpose.SERVER_AUTH,
                cafile=self.session.cafile,
                capath=self.session.capath,
                cadata=self.session.cadata,
            )
            if "certfile" in self.config and "keyfile" in self.config:
                sc.load_cert_chain(self.config["certfile"],
                                   self.config["keyfile"])
            if "check_hostname" in self.config and isinstance(
                    self.config["check_hostname"], bool):
                sc.check_hostname = self.config["check_hostname"]
            kwargs["ssl"] = sc

        try:
            reader = None
            writer = None
            self._connected_state.clear()
            # Open connection
            if scheme in ("mqtt", "mqtts"):
                conn_reader, conn_writer = await asyncio.open_connection(
                    self.session.remote_address,
                    self.session.remote_port,
                    loop=self._loop,
                    **kwargs)
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)
            elif scheme in ("ws", "wss"):
                websocket = await websockets.connect(
                    self.session.broker_uri,
                    subprotocols=["mqtt"],
                    loop=self._loop,
                    extra_headers=self.extra_headers,
                    **kwargs)
                reader = WebSocketsReader(websocket)
                writer = WebSocketsWriter(websocket)
            # Start MQTT protocol
            self._handler.attach(self.session, reader, writer)
            return_code = await self._handler.mqtt_connect()
            if return_code is not CONNECTION_ACCEPTED:
                self.session.transitions.disconnect()
                self.logger.warning("Connection rejected with code '%s'" %
                                    return_code)
                exc = ConnectException("Connection rejected by broker")
                exc.return_code = return_code
                raise exc
            else:
                # Handle MQTT protocol
                await self._handler.start()
                self.session.transitions.connect()
                self._connected_state.set()
                self.logger.debug(
                    "connected to %s:%s" %
                    (self.session.remote_address, self.session.remote_port))
            return return_code
        except InvalidURI as iuri:
            self.logger.warning("connection failed: invalid URI '%s'" %
                                self.session.broker_uri)
            self.session.transitions.disconnect()
            raise ConnectException(
                "connection failed: invalid URI '%s'" %
                self.session.broker_uri, iuri)
        except InvalidHandshake as ihs:
            self.logger.warning(
                "connection failed: invalid websocket handshake")
            self.session.transitions.disconnect()
            raise ConnectException(
                "connection failed: invalid websocket handshake", ihs)
        except (ProtocolHandlerException, ConnectionError, OSError) as e:
            self.logger.warning("MQTT connection failed: %r" % e)
            self.session.transitions.disconnect()
            raise ConnectException(e)
Esempio n. 9
0
    def _connect_coro(self):
        kwargs = dict()

        # Decode URI attributes
        uri_attributes = urlparse(self.session.broker_uri)
        scheme = uri_attributes.scheme
        secure = True if scheme in ('mqtts', 'wss') else False
        self.session.username = uri_attributes.username
        self.session.password = uri_attributes.password
        self.session.remote_address = uri_attributes.hostname
        self.session.remote_port = uri_attributes.port
        if scheme in ('mqtt', 'mqtts') and not self.session.remote_port:
            self.session.remote_port = 8883 if scheme == 'mqtts' else 1883
        if scheme in ('ws', 'wss') and not self.session.remote_port:
            self.session.remote_port = 443 if scheme == 'wss' else 80
        if scheme in ('ws', 'wss'):
            # Rewrite URI to conform to https://tools.ietf.org/html/rfc6455#section-3
            uri = (scheme, self.session.remote_address + ":" +
                   str(self.session.remote_port), uri_attributes[2],
                   uri_attributes[3], uri_attributes[4], uri_attributes[5])
            self.session.broker_uri = urlunparse(uri)
        # Init protocol handler
        #if not self._handler:
        self._handler = ClientProtocolHandler(self.plugins_manager,
                                              loop=self._loop)

        if secure:
            if self.session.cafile is None or self.session.cafile == '':
                self.logger.warning(
                    "TLS connection can't be estabilshed, no certificate file (.cert) given"
                )
                raise ClientException(
                    "TLS connection can't be estabilshed, no certificate file (.cert) given"
                )
            sc = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
                                            cafile=self.session.cafile,
                                            capath=self.session.capath,
                                            cadata=self.session.cadata)
            if 'certfile' in self.config and 'keyfile' in self.config:
                sc.load_cert_chain(self.config['certfile'],
                                   self.config['keyfile'])
            if 'check_hostname' in self.config and isinstance(
                    self.config['check_hostname'], bool):
                sc.check_hostname = self.config['check_hostname']
            kwargs['ssl'] = sc

        try:
            reader = None
            writer = None
            self._connected_state.clear()
            # Open connection
            if scheme in ('mqtt', 'mqtts'):
                conn_reader, conn_writer = \
                    yield from asyncio.open_connection(
                        self.session.remote_address,
                        self.session.remote_port, loop=self._loop, **kwargs)
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)
            elif scheme in ('ws', 'wss'):
                websocket = yield from websockets.connect(
                    self.session.broker_uri,
                    subprotocols=['mqtt'],
                    loop=self._loop,
                    **kwargs)
                reader = WebSocketsReader(websocket)
                writer = WebSocketsWriter(websocket)
            # Start MQTT protocol
            self._handler.attach(self.session, reader, writer)
            return_code = yield from self._handler.mqtt_connect()
            if return_code is not CONNECTION_ACCEPTED:
                self.session.transitions.disconnect()
                self.logger.warning("Connection rejected with code '%s'" %
                                    return_code)
                exc = ConnectException("Connection rejected by broker")
                exc.return_code = return_code
                raise exc
            else:
                # Handle MQTT protocol
                yield from self._handler.start()
                self.session.transitions.connect()
                self._connected_state.set()
                self.logger.debug(
                    "connected to %s:%s" %
                    (self.session.remote_address, self.session.remote_port))
            return return_code
        except InvalidURI as iuri:
            self.logger.warning("connection failed: invalid URI '%s'" %
                                self.session.broker_uri)
            self.session.transitions.disconnect()
            raise ConnectException(
                "connection failed: invalid URI '%s'" %
                self.session.broker_uri, iuri)
        except InvalidHandshake as ihs:
            self.logger.warning(
                "connection failed: invalid websocket handshake")
            self.session.transitions.disconnect()
            raise ConnectException(
                "connection failed: invalid websocket handshake", ihs)
        except (ProtocolHandlerException, ConnectionError, OSError) as e:
            self.logger.warning("MQTT connection failed: %r" % e)
            self.session.transitions.disconnect()
            raise ConnectException(e)
Esempio n. 10
0
    def _connect_coro(self):
        sc = None
        reader = None
        writer = None
        kwargs = dict()

        # Decode URI attributes
        uri_attributes = urlparse(self.session.broker_uri)
        scheme = uri_attributes.scheme
        self.session.username = uri_attributes.username
        self.session.password = uri_attributes.password
        self.session.remote_address = uri_attributes.hostname
        self.session.remote_port = uri_attributes.port
        if scheme in ('mqtt', 'mqtts') and not self.session.remote_port:
            self.session.remote_port = 8883 if scheme == 'mqtts' else 1883

        if scheme in ('mqtts', 'wss'):
            if self.session.cafile is None or self.session.cafile == '':
                self.logger.warn(
                    "TLS connection can't be estabilshed, no certificate file (.cert) given"
                )
                raise ClientException(
                    "TLS connection can't be estabilshed, no certificate file (.cert) given"
                )
            sc = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
                                            cafile=self.session.cafile,
                                            capath=self.session.capath,
                                            cadata=self.session.cadata)
            if 'certfile' in self.config and 'keyfile' in self.config:
                sc.load_cert_chain(self.config['certfile'],
                                   self.config['keyfile'])
            kwargs['ssl'] = sc

        # Open connection
        try:
            if scheme in ('mqtt', 'mqtts'):
                conn_reader, conn_writer = \
                    yield from asyncio.open_connection(self.session.remote_address, self.session.remote_port, **kwargs)
                reader = StreamReaderAdapter(conn_reader)
                writer = StreamWriterAdapter(conn_writer)
            elif scheme in ('ws', 'wss'):
                websocket = yield from websockets.connect(
                    self.session.broker_uri, subprotocols=['mqtt'], **kwargs)
                reader = WebSocketsReader(websocket)
                writer = WebSocketsWriter(websocket)
        except Exception as e:
            self.logger.warn("connection failed: %s" % e)
            self.session.transitions.disconnect()
            raise ConnectException("connection Failed: %s" % e)

        return_code = None
        try:
            connect_packet = self.build_connect_packet()
            yield from connect_packet.to_stream(writer)
            self.logger.debug(" -out-> " + repr(connect_packet))

            connack = yield from ConnackPacket.from_stream(reader)
            self.logger.debug(" <-in-- " + repr(connack))
            return_code = connack.variable_header.return_code
        except Exception as e:
            self.logger.warn("connection failed: %s" % e)
            self.session.transitions.disconnect()
            raise ClientException("connection Failed: %s" % e)

        if return_code is not CONNECTION_ACCEPTED:
            yield from self._handler.stop()
            self.session.transitions.disconnect()
            self.logger.warn("Connection rejected with code '%s'" %
                             return_code)
            exc = ConnectException("Connection rejected by broker")
            exc.return_code = return_code
            raise exc
        else:
            # Handle MQTT protocol
            self._handler = ClientProtocolHandler(reader,
                                                  writer,
                                                  loop=self._loop)
            self._handler.attach_to_session(self.session)
            yield from self._handler.start()
            self.session.transitions.connect()
            self.logger.debug(
                "connected to %s:%s" %
                (self.session.remote_address, self.session.remote_port))
Esempio n. 11
0
 def stream_connected(self, reader, writer, listener_name):
     yield from self.client_connected(listener_name, StreamReaderAdapter(reader), StreamWriterAdapter(writer))
Esempio n. 12
0
 async def stream_connected(self, reader, writer, listener_name):
     await self.client_connected(
         listener_name, StreamReaderAdapter(reader), StreamWriterAdapter(writer)
     )