Ejemplo n.º 1
0
    def test_decode(self):
        """Tests the decode function."""

        data = (
            ('\xf8\x01\xfc\x03foo',
             '<foo />'),

            ('\xf8\x03\x01\x38\x8a',
             '<stream:stream from="s.whatsapp.net">'),

            ('\xf8\x08]\xa0\xfa\xfc\x0b12345678912\x8a\xa2\x1bC\xfc\x0c' +
                '1343064803-1\xf8\x02\xf8\x04\xba\xbdO\xf8\x01\xf8\x01\x8c' +
                '\xf8\x02\x16\xfc\x04Okay',
             '<message to="*****@*****.**" type="chat" ' +
                'id="1343064803-1"><x xmlns="jabber:x:event"><server /></x>' +
                '<body>Okay</body></message>')
        )


        for o, r in data:
            d = funxmpp.decode(o)

            self.assertEqual(d, r,
                "Encoding incorrect:\n%s\n%s" % (repr(d), repr(r)))
Ejemplo n.º 2
0
    def test_both(self):
        """Sees if a encode followed by a decode results in the same data."""

        data = ['<foo x="y"><poke name="stuff" /><another thing="yay" />' +
                    '<body>bar</body></foo>',

                '<message from="*****@*****.**" ' +
                             'id="1339831077-7" ' +
                             'type="chat" ' +
                             't="1339848755">' +
                    '<notify xmlns="urn:xmpp:whatsapp" ' +
                            'name="Koen" />' +
                    '<request xmlns="urn:xmpp:receipts" />' +
                    '<body>Hello</body>' +
                '</message>',

                '<iq from="*****@*****.**" id="1" type="error">' +
                    '<error code="404" type="cancel">' +
                    '<item-not-found ' +
                        'xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />' +
                    '</error></iq>']

        for t in data:
            self.assertEqual(t, funxmpp.decode(funxmpp.encode(t)))
Ejemplo n.º 3
0
    def recv_and_handle(self, return_single=False, parse_buffer_only=False):
        """Receives some data from the server and then tries to parse as much
        messages in the buffer as possible.

        The receiving part of this function will block until there is data to be
        read. Any received data is appended to the current buffer, and then
        we try to extract as many messages from the buffer as possible. For each
        parsed message, the corresponding handler is called.

        It is possible to circumvent the standard behaviour in two ways. You
        probably never need to to that, it is only used internally in special
        situations.

        The return_single flag circumvents the handler part of the the function.
        Any found message is immediately returned. If no messages were found,
        None is returned.

        The parse_buffer_only argument specifies whether the socket should
        receive new data from the server. This can be usefull after a call with
        return_single enabled, to handle the remaining messages in the
        buffer."""

        if not self.is_connected:
            raise Exception("Not connected.")

        if not parse_buffer_only:
            r = self.socket.recv(1024)
            if not r:
                self.disconnect()
                return

            self.buffer += r

        # Smallest message possible has a length of 5 (2 for length, 1 for f8,
        # 1 for f8 lenth, 1 for f8 tagname)
        while len(self.buffer) >= 5:
            msglen = struct.unpack('!H', self.buffer[:2])[0]
            if len(self.buffer) - 2 < msglen:
                return

            msg = self.buffer[2:msglen+2]
            self.buffer = self.buffer[msglen+2:]

            if len(msg) == 0:
                print "BUFCRASH:", msglen, repr(self.buffer)
                self.buf = ''
                return

            try:
                parsed = funxmpp.decode(msg)
                print ' < ', parsed
            except Exception as e:
                print 'Crash in funxmpp.decode', repr(msg), e

            # Stream start needs some special care
            if parsed.split(' ')[0] == '<stream:stream':
                parsed = parsed[:-1] + ' />'

            # Define the stream prefix namespace thing when needed
            if parsed.startswith('<stream:'):
                parsed = re.sub(r'^<stream:([^> ]*)',
                                r'<stream:\1 xmlns:stream="' +
                                    'http://etherx.jabber.org/streams"',
                                parsed)

            xml = ET.fromstring(parsed)

            if return_single:
                return xml

            self._call_handler(xml)