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)
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)
def ws_connected(self, websocket, uri, listener_name): yield from self.client_connected(listener_name, WebSocketsReader(websocket), WebSocketsWriter(websocket))
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))
async def ws_connected(self, websocket, uri, listener_name): await self.client_connected( listener_name, WebSocketsReader(websocket), WebSocketsWriter(websocket) )