diff options
author | mathieui <mathieui@mathieui.net> | 2014-05-08 01:37:52 +0200 |
---|---|---|
committer | mathieui <mathieui@mathieui.net> | 2014-05-08 01:37:52 +0200 |
commit | 916416a019c398a484b6a436ee908808780263f9 (patch) | |
tree | 6de5b51968e8113b18251e8dee4131cd681860d9 /src/fixes.py | |
parent | 9786592b80f7ddcfefa967ea910f38ba3c02b0b4 (diff) | |
download | poezio-916416a019c398a484b6a436ee908808780263f9.tar.gz poezio-916416a019c398a484b6a436ee908808780263f9.tar.bz2 poezio-916416a019c398a484b6a436ee908808780263f9.tar.xz poezio-916416a019c398a484b6a436ee908808780263f9.zip |
Add an ugly fix to avoid endless disco#info queries with each message (with receipts)
We need to check if the remote entity supports 0184, but if it doesn’t
support disco#info, then we will get an iq type="error" and nothing
will be cached, leading to disco#info queries being sent each time.
Keep a cache valid 2 hours of the JIDs which replied with an error.
TODO: check that this the kind of time period we want.
Diffstat (limited to 'src/fixes.py')
-rw-r--r-- | src/fixes.py | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/src/fixes.py b/src/fixes.py index 75ac6343..cb992e88 100644 --- a/src/fixes.py +++ b/src/fixes.py @@ -5,12 +5,15 @@ upstream. TODO: Check that they are fixed and remove those hacks """ - from sleekxmpp.stanza import Message from sleekxmpp.xmlstream import ET import logging +# used to avoid doing numerous useless disco#info requests +# especially with message receipts +IQ_ERRORS = set() + log = logging.getLogger(__name__) def has_identity(xmpp, jid, identity): @@ -96,3 +99,89 @@ def _filter_add_receipt_request(self, stanza): stanza['request_receipt'] = True return stanza + +def xep_30_supports(self, jid, node, ifrom, data): + """ + Check if a JID supports a given feature. + + The data parameter may provide: + feature -- The feature to check for support. + local -- If true, then the query is for a JID/node + combination handled by this Sleek instance and + no stanzas need to be sent. + Otherwise, a disco stanza must be sent to the + remove JID to retrieve the info. + cached -- If true, then look for the disco info data from + the local cache system. If no results are found, + send the query as usual. The self.use_cache + setting must be set to true for this option to + be useful. If set to false, then the cache will + be skipped, even if a result has already been + cached. Defaults to false. + """ + feature = data.get('feature', None) + + data = {'local': data.get('local', False), + 'cached': data.get('cached', True)} + + if not feature or jid.full in IQ_ERRORS: + return False + + try: + info = self.disco.get_info(jid=jid, node=node, + ifrom=ifrom, **data) + info = self.disco._wrap(ifrom, jid, info, True) + features = info['disco_info']['features'] + return feature in features + except: + IQ_ERRORS.add(jid.full) + log.debug('%s added to the list of entities that do' + 'not honor disco#info', jid.full) + return False + +def xep_115_supports(self, jid, node, ifrom, data): + """ + Check if a JID supports a given feature. + + The data parameter may provide: + feature -- The feature to check for support. + local -- If true, then the query is for a JID/node + combination handled by this Sleek instance and + no stanzas need to be sent. + Otherwise, a disco stanza must be sent to the + remove JID to retrieve the info. + cached -- If true, then look for the disco info data from + the local cache system. If no results are found, + send the query as usual. The self.use_cache + setting must be set to true for this option to + be useful. If set to false, then the cache will + be skipped, even if a result has already been + cached. Defaults to false. + """ + feature = data.get('feature', None) + + data = {'local': data.get('local', False), + 'cached': data.get('cached', True)} + + if not feature or jid.full in IQ_ERRORS: + return False + + if node in (None, ''): + info = self.caps.get_caps(jid) + if info and feature in info['features']: + return True + + try: + info = self.disco.get_info(jid=jid, node=node, + ifrom=ifrom, **data) + info = self.disco._wrap(ifrom, jid, info, True) + return feature in info['disco_info']['features'] + except: + IQ_ERRORS.add(jid.full) + log.debug('%s added to the list of entities that do' + 'not honor disco#info', jid.full) + return False + +def reset_iq_errors(): + "reset the iq error cache" + IQ_ERRORS.clear() |