def connect(self, address=tuple(), use_ssl=False, force_starttls=True, disable_starttls=False): """Connect to the XMPP server. When no address is given, a SRV lookup for the server will be attempted. If that fails, the server user in the JID will be used. :param address: A tuple containing the server's host and port. :param reattempt: If ``True``, repeat attempting to connect if an error occurs. Defaults to ``True``. :param use_tls: Indicates if TLS should be used for the connection. Defaults to ``True``. :param use_ssl: Indicates if the older SSL connection method should be used. Defaults to ``False``. """ # If an address was provided, disable using DNS SRV lookup; # otherwise, use the domain from the client JID with the standard # XMPP client port and allow SRV lookup. if address: self.dns_service = None else: address = (self.boundjid.host, 5222) self.dns_service = 'xmpp-client' return XMLStream.connect(self, address[0], address[1], use_ssl=use_ssl, force_starttls=force_starttls, disable_starttls=disable_starttls)
def connect(self, host=None, port=None, use_ssl=False, use_tls=False, reattempt=True): """Connect to the server. Setting ``reattempt`` to ``True`` will cause connection attempts to be made every second until a successful connection is established. :param host: The name of the desired server for the connection. Defaults to :attr:`server_host`. :param port: Port to connect to on the server. Defauts to :attr:`server_port`. :param use_ssl: Flag indicating if SSL should be used by connecting directly to a port using SSL. :param use_tls: Flag indicating if TLS should be used, allowing for connecting to a port without using SSL immediately and later upgrading the connection. :param reattempt: Flag indicating if the socket should reconnect after disconnections. """ if host is None: host = self.server_host if port is None: port = self.server_port self.server_name = self.boundjid.host if use_tls: log.info("XEP-0114 components can not use TLS") log.debug("Connecting to %s:%s", host, port) return XMLStream.connect(self, host=host, port=port, use_ssl=use_ssl, use_tls=False, reattempt=reattempt)
def connect(self, address=tuple(), use_ssl=False, force_starttls=True, disable_starttls=False): """Connect to the XMPP server. When no address is given, a SRV lookup for the server will be attempted. If that fails, the server user in the JID will be used. :param address: A tuple containing the server's host and port. :param use_tls: Indicates if TLS should be used for the connection. Defaults to ``True``. :param use_ssl: Indicates if the older SSL connection method should be used. Defaults to ``False``. """ # If an address was provided, disable using DNS SRV lookup; # otherwise, use the domain from the client JID with the standard # XMPP client port and allow SRV lookup. if address: self.dns_service = None else: address = (self.boundjid.host, 5222) self.dns_service = 'xmpp-client' return XMLStream.connect(self, address[0], address[1], use_ssl=use_ssl, force_starttls=force_starttls, disable_starttls=disable_starttls)
def connect(self, host=None, port=None, use_ssl=False): """Connect to the server. :param host: The name of the desired server for the connection. Defaults to :attr:`server_host`. :param port: Port to connect to on the server. Defauts to :attr:`server_port`. :param use_ssl: Flag indicating if SSL should be used by connecting directly to a port using SSL. """ if host is None: host = self.server_host if port is None: port = self.server_port self.server_name = self.boundjid.host log.debug("Connecting to %s:%s", host, port) return XMLStream.connect(self, host=host, port=port, use_ssl=use_ssl)
def __init__(self, jid='', default_ns='jabber:client', **kwargs): XMLStream.__init__(self, **kwargs) self.default_ns = default_ns self.stream_ns = 'http://etherx.jabber.org/streams' self.namespace_map[self.stream_ns] = 'stream' #: An identifier for the stream as given by the server. self.stream_id = None #: The JabberID (JID) requested for this connection. self.requested_jid = JID(jid) #: The JabberID (JID) used by this connection, #: as set after session binding. This may even be a #: different bare JID than what was requested. self.boundjid = JID(jid) self._expected_server_name = self.boundjid.host self._redirect_attempts = 0 #: The maximum number of consecutive see-other-host #: redirections that will be followed before quitting. self.max_redirects = 5 self.session_bind_event = asyncio.Event() #: A dictionary mapping plugin names to plugins. self.plugin = PluginManager(self) #: Configuration options for whitelisted plugins. #: If a plugin is registered without any configuration, #: and there is an entry here, it will be used. self.plugin_config = {} #: A list of plugins that will be loaded if #: :meth:`register_plugins` is called. self.plugin_whitelist = [] #: The main roster object. This roster supports multiple #: owner JIDs, as in the case for components. For clients #: which only have a single JID, see :attr:`client_roster`. self.roster = roster.Roster(self) self.roster.add(self.boundjid) #: The single roster for the bound JID. This is the #: equivalent of:: #: #: self.roster[self.boundjid.bare] self.client_roster = self.roster[self.boundjid] #: The distinction between clients and components can be #: important, primarily for choosing how to handle the #: ``'to'`` and ``'from'`` JIDs of stanzas. self.is_component = False #: Messages may optionally be tagged with ID values. Setting #: :attr:`use_message_ids` to `True` will assign all outgoing #: messages an ID. Some plugin features require enabling #: this option. self.use_message_ids = False #: Presence updates may optionally be tagged with ID values. #: Setting :attr:`use_message_ids` to `True` will assign all #: outgoing messages an ID. self.use_presence_ids = False #: The API registry is a way to process callbacks based on #: JID+node combinations. Each callback in the registry is #: marked with: #: #: - An API name, e.g. xep_0030 #: - The name of an action, e.g. get_info #: - The JID that will be affected #: - The node that will be affected #: #: API handlers with no JID or node will act as global handlers, #: while those with a JID and no node will service all nodes #: for a JID, and handlers with both a JID and node will be #: used only for that specific combination. The handler that #: provides the most specificity will be used. self.api = APIRegistry(self) #: Flag indicating that the initial presence broadcast has #: been sent. Until this happens, some servers may not #: behave as expected when sending stanzas. self.sentpresence = False #: A reference to :mod:`slixmpp.stanza` to make accessing #: stanza classes easier. self.stanza = stanza self.register_handler( Callback('IM', MatchXPath('{%s}message/{%s}body' % (self.default_ns, self.default_ns)), self._handle_message)) self.register_handler( Callback('IMError', MatchXPath('{%s}message/{%s}error' % (self.default_ns, self.default_ns)), self._handle_message_error)) self.register_handler( Callback('Presence', MatchXPath("{%s}presence" % self.default_ns), self._handle_presence)) self.register_handler( Callback('Stream Error', MatchXPath("{%s}error" % self.stream_ns), self._handle_stream_error)) self.add_event_handler('session_start', self._handle_session_start) self.add_event_handler('disconnected', self._handle_disconnected) self.add_event_handler('presence_available', self._handle_available) self.add_event_handler('presence_dnd', self._handle_available) self.add_event_handler('presence_xa', self._handle_available) self.add_event_handler('presence_chat', self._handle_available) self.add_event_handler('presence_away', self._handle_available) self.add_event_handler('presence_unavailable', self._handle_unavailable) self.add_event_handler('presence_subscribe', self._handle_subscribe) self.add_event_handler('presence_subscribed', self._handle_subscribed) self.add_event_handler('presence_unsubscribe', self._handle_unsubscribe) self.add_event_handler('presence_unsubscribed', self._handle_unsubscribed) self.add_event_handler('roster_subscription_request', self._handle_new_subscription) # Set up the XML stream with XMPP's root stanzas. self.register_stanza(Message) self.register_stanza(Iq) self.register_stanza(Presence) self.register_stanza(StreamError) # Initialize a few default stanza plugins. register_stanza_plugin(Iq, Roster)
def process(self, *, forever=True, timeout=None): self.init_plugins() XMLStream.process(self, forever=forever, timeout=timeout)
def __init__(self, jid='', default_ns='jabber:client', **kwargs): XMLStream.__init__(self, **kwargs) self.default_ns = default_ns self.stream_ns = 'http://etherx.jabber.org/streams' self.namespace_map[self.stream_ns] = 'stream' #: An identifier for the stream as given by the server. self.stream_id = None #: The JabberID (JID) requested for this connection. self.requested_jid = JID(jid) #: The JabberID (JID) used by this connection, #: as set after session binding. This may even be a #: different bare JID than what was requested. self.boundjid = JID(jid) self._expected_server_name = self.boundjid.host self._redirect_attempts = 0 #: The maximum number of consecutive see-other-host #: redirections that will be followed before quitting. self.max_redirects = 5 self.session_bind_event = asyncio.Event() #: A dictionary mapping plugin names to plugins. self.plugin = PluginManager(self) #: Configuration options for whitelisted plugins. #: If a plugin is registered without any configuration, #: and there is an entry here, it will be used. self.plugin_config = {} #: A list of plugins that will be loaded if #: :meth:`register_plugins` is called. self.plugin_whitelist = [] #: The main roster object. This roster supports multiple #: owner JIDs, as in the case for components. For clients #: which only have a single JID, see :attr:`client_roster`. self.roster = roster.Roster(self) self.roster.add(self.boundjid) #: The single roster for the bound JID. This is the #: equivalent of:: #: #: self.roster[self.boundjid.bare] self.client_roster = self.roster[self.boundjid] #: The distinction between clients and components can be #: important, primarily for choosing how to handle the #: ``'to'`` and ``'from'`` JIDs of stanzas. self.is_component = False #: Messages may optionally be tagged with ID values. Setting #: :attr:`use_message_ids` to `True` will assign all outgoing #: messages an ID. Some plugin features require enabling #: this option. self.use_message_ids = True #: Presence updates may optionally be tagged with ID values. #: Setting :attr:`use_message_ids` to `True` will assign all #: outgoing messages an ID. self.use_presence_ids = True #: XEP-0359 <origin-id/> tag that gets added to <message/> stanzas. self.use_origin_id = True #: The API registry is a way to process callbacks based on #: JID+node combinations. Each callback in the registry is #: marked with: #: #: - An API name, e.g. xep_0030 #: - The name of an action, e.g. get_info #: - The JID that will be affected #: - The node that will be affected #: #: API handlers with no JID or node will act as global handlers, #: while those with a JID and no node will service all nodes #: for a JID, and handlers with both a JID and node will be #: used only for that specific combination. The handler that #: provides the most specificity will be used. self.api = APIRegistry(self) #: Flag indicating that the initial presence broadcast has #: been sent. Until this happens, some servers may not #: behave as expected when sending stanzas. self.sentpresence = False #: A reference to :mod:`slixmpp.stanza` to make accessing #: stanza classes easier. self.stanza = stanza self.register_handler( Callback( 'IM', MatchXPath('{%s}message/{%s}body' % (self.default_ns, self.default_ns)), self._handle_message)) self.register_handler( Callback( 'IMError', MatchXPath('{%s}message/{%s}error' % (self.default_ns, self.default_ns)), self._handle_message_error)) self.register_handler( Callback('Presence', MatchXPath("{%s}presence" % self.default_ns), self._handle_presence)) self.register_handler( Callback('Stream Error', MatchXPath("{%s}error" % self.stream_ns), self._handle_stream_error)) self.add_event_handler('session_start', self._handle_session_start) self.add_event_handler('disconnected', self._handle_disconnected) self.add_event_handler('presence_available', self._handle_available) self.add_event_handler('presence_dnd', self._handle_available) self.add_event_handler('presence_xa', self._handle_available) self.add_event_handler('presence_chat', self._handle_available) self.add_event_handler('presence_away', self._handle_available) self.add_event_handler('presence_unavailable', self._handle_unavailable) self.add_event_handler('presence_subscribe', self._handle_subscribe) self.add_event_handler('presence_subscribed', self._handle_subscribed) self.add_event_handler('presence_unsubscribe', self._handle_unsubscribe) self.add_event_handler('presence_unsubscribed', self._handle_unsubscribed) self.add_event_handler('roster_subscription_request', self._handle_new_subscription) # Set up the XML stream with XMPP's root stanzas. self.register_stanza(Message) self.register_stanza(Iq) self.register_stanza(Presence) self.register_stanza(StreamError) # Initialize a few default stanza plugins. register_stanza_plugin(Iq, Roster)
def __init__(self): # BaseXMPP does way too much crap in its __init__, # we'll have to skip it and do stuff ourselves XMLStream.__init__(self) self.default_ns = 'jabber:client' self.stream_ns = 'http://etherx.jabber.org/streams' self.namespace_map[self.stream_ns] = 'stream' self.requested_jid = JID() self.boundjid = JID() self.session_bind_event = asyncio.Event() self.plugin = PluginManager(self) self.plugin_config = {} self.is_component = True self.use_message_ids = False self.use_presence_ids = False self.api = APIRegistry(self) self.register_stanza(Iq) self.register_stanza(StreamError) self.authenticated = True # keep slixmpp's xep_0078 from doing stupid stuff # And now for our own initialization... self.logger_extra = {'sid': '', 'jid': ''} self.logger = logging.LoggerAdapter( logging.getLogger('xmppserver.stream'), self.logger_extra) self.ipc_logger = logging.LoggerAdapter( logging.getLogger('xmppserver.ipc'), self.logger_extra) self.web_user = None self.bound_user = None self.host = settings.DOMAIN self.kicked = False self._auth_hook = None self._roster_hook = None self._session_hook = None self.version = None self.default_lang = 'en' self.recv_task = None self.channel_name = None self.group_name = None self.channel_layer = get_channel_layer('xmppserver') self.register_plugin('xep_0086') # legacy error codes self.features = Features(self) self.disco = Disco(self) self.auth = Auth(self) self.registration = Registration(self) self.ping = Ping(self) # we only need the following components # after the client has authenticated. self.roster = None self.presence = None self.messaging = None self.register_handler( Callback('Remote Iq', RemoteStanzaPath('iq'), self._handle_iq)) self.logger.debug('Creating stream')