diff options
author | mathieui <mathieui@mathieui.net> | 2015-09-23 23:14:26 +0200 |
---|---|---|
committer | mathieui <mathieui@mathieui.net> | 2015-10-02 19:00:19 +0200 |
commit | acc52fd935b7e74919ad748f3a630596f66c62af (patch) | |
tree | 2d8988c57a63b9cec11c4bf03240a427df9632f8 /slixmpp/plugins/xep_0138.py | |
parent | e42d651d7ed56375523f91076295fc5f388a8de0 (diff) | |
parent | 4305eddb4f634803423cd53d193125a63b00769a (diff) | |
download | slixmpp-acc52fd935b7e74919ad748f3a630596f66c62af.tar.gz slixmpp-acc52fd935b7e74919ad748f3a630596f66c62af.tar.bz2 slixmpp-acc52fd935b7e74919ad748f3a630596f66c62af.tar.xz slixmpp-acc52fd935b7e74919ad748f3a630596f66c62af.zip |
Merge branch 'develop' of https://github.com/fritzy/SleekXMPP into sleek-merge
Conflicts:
README.rst
examples/IoT_TestDevice.py
examples/disco_browser.py
setup.py
sleekxmpp/jid.py
sleekxmpp/plugins/google/auth/stanza.py
sleekxmpp/plugins/google/gmail/notifications.py
sleekxmpp/plugins/google/nosave/stanza.py
sleekxmpp/plugins/google/settings/settings.py
sleekxmpp/thirdparty/__init__.py
sleekxmpp/thirdparty/socks.py
sleekxmpp/thirdparty/statemachine.py
sleekxmpp/util/__init__.py
sleekxmpp/xmlstream/xmlstream.py
slixmpp/basexmpp.py
slixmpp/plugins/xep_0004/stanza/form.py
slixmpp/plugins/xep_0009/rpc.py
slixmpp/plugins/xep_0050/adhoc.py
slixmpp/plugins/xep_0065/proxy.py
slixmpp/plugins/xep_0084/stanza.py
slixmpp/plugins/xep_0202/time.py
slixmpp/plugins/xep_0323/sensordata.py
slixmpp/plugins/xep_0325/control.py
slixmpp/plugins/xep_0325/stanza/control.py
slixmpp/roster/single.py
slixmpp/stanza/atom.py
slixmpp/stanza/rootstanza.py
slixmpp/test/slixtest.py
slixmpp/util/sasl/mechanisms.py
slixmpp/version.py
slixmpp/xmlstream/stanzabase.py
tests/test_stanza_xep_0323.py
tests/test_stanza_xep_0325.py
tests/test_stream_xep_0323.py
tests/test_stream_xep_0325.py
Diffstat (limited to 'slixmpp/plugins/xep_0138.py')
-rw-r--r-- | slixmpp/plugins/xep_0138.py | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/slixmpp/plugins/xep_0138.py b/slixmpp/plugins/xep_0138.py new file mode 100644 index 00000000..049060cf --- /dev/null +++ b/slixmpp/plugins/xep_0138.py @@ -0,0 +1,145 @@ +""" + slixmpp: The Slick XMPP Library + Copyright (C) 2011 Nathanael C. Fritz + This file is part of slixmpp. + + See the file LICENSE for copying permission. +""" + +import logging +import zlib + + +from slixmpp.stanza import StreamFeatures +from slixmpp.xmlstream import RestartStream, register_stanza_plugin, ElementBase, StanzaBase +from slixmpp.xmlstream.matcher import * +from slixmpp.xmlstream.handler import * +from slixmpp.plugins import BasePlugin, register_plugin + +log = logging.getLogger(__name__) + + +class Compression(ElementBase): + name = 'compression' + namespace = 'http://jabber.org/features/compress' + interfaces = set(('methods',)) + plugin_attrib = 'compression' + plugin_tag_map = {} + plugin_attrib_map = {} + + def get_methods(self): + methods = [] + for method in self.xml.findall('{%s}method' % self.namespace): + methods.append(method.text) + return methods + + +class Compress(StanzaBase): + name = 'compress' + namespace = 'http://jabber.org/protocol/compress' + interfaces = set(('method',)) + sub_interfaces = interfaces + plugin_attrib = 'compress' + plugin_tag_map = {} + plugin_attrib_map = {} + + def setup(self, xml): + StanzaBase.setup(self, xml) + self.xml.tag = self.tag_name() + + +class Compressed(StanzaBase): + name = 'compressed' + namespace = 'http://jabber.org/protocol/compress' + interfaces = set() + plugin_tag_map = {} + plugin_attrib_map = {} + + def setup(self, xml): + StanzaBase.setup(self, xml) + self.xml.tag = self.tag_name() + + + + +class ZlibSocket(object): + + def __init__(self, socketobj): + self.__socket = socketobj + self.compressor = zlib.compressobj() + self.decompressor = zlib.decompressobj(zlib.MAX_WBITS) + + def __getattr__(self, name): + return getattr(self.__socket, name) + + def send(self, data): + sentlen = len(data) + data = self.compressor.compress(data) + data += self.compressor.flush(zlib.Z_SYNC_FLUSH) + log.debug(b'>>> (compressed)' + (data.encode("hex"))) + #return self.__socket.send(data) + sentactuallen = self.__socket.send(data) + assert(sentactuallen == len(data)) + + return sentlen + + def recv(self, *args, **kwargs): + data = self.__socket.recv(*args, **kwargs) + log.debug(b'<<< (compressed)' + data.encode("hex")) + return self.decompressor.decompress(self.decompressor.unconsumed_tail + data) + + +class XEP_0138(BasePlugin): + """ + XEP-0138: Compression + """ + name = "xep_0138" + description = "XEP-0138: Compression" + dependencies = set(["xep_0030"]) + + def plugin_init(self): + self.xep = '0138' + self.description = 'Stream Compression (Generic)' + + self.compression_methods = {'zlib': True} + + register_stanza_plugin(StreamFeatures, Compression) + self.xmpp.register_stanza(Compress) + self.xmpp.register_stanza(Compressed) + + self.xmpp.register_handler( + Callback('Compressed', + StanzaPath('compressed'), + self._handle_compressed, + instream=True)) + + self.xmpp.register_feature('compression', + self._handle_compression, + restart=True, + order=self.config.get('order', 5)) + + def register_compression_method(self, name, handler): + self.compression_methods[name] = handler + + def _handle_compression(self, features): + for method in features['compression']['methods']: + if method in self.compression_methods: + log.info('Attempting to use %s compression' % method) + c = Compress(self.xmpp) + c['method'] = method + c.send(now=True) + return True + return False + + def _handle_compressed(self, stanza): + self.xmpp.features.add('compression') + log.debug('Stream Compressed!') + compressed_socket = ZlibSocket(self.xmpp.socket) + self.xmpp.set_socket(compressed_socket) + raise RestartStream() + + def _handle_failure(self, stanza): + pass + +xep_0138 = XEP_0138 +register_plugin(XEP_0138) |