Ik probeer een Python library te schrijven voor (client-server) XMPP (Jabber) communicatie.
Ik heb aan de hand van een bestaande library (waarvan ik de code echter extreem ranzig en slecht leesbaar vind) en het meelezen met Trillian's XMPP-communicatie al een stukje geschreven. Nu heb ik echter een probleem met de Expat-parser wat ik totaal niet begrijp. Ik hoop dat iemand kan helpen.
Ik voer de de Expat-parser telkens een stukje XML. Dat begint gewoon met een XML prolog en de root-tag voor de sessie/het document (stream:stream), daarna ontvang ik een zooi features. Aan de hand daarvan stuur ik een starttls, die vervolgens wordt opgevolgd met een respons van proceed. Daar gaat het echter fout:
Ik snap alleen totaal niet waarom dit gebeurt! Dit werkt namelijk wel:
Er zijn echter behalve deze statements in mijn code geen interactie met de Expat parser! (Er zijn drie directe mogelijkheden: het creeeren, het afsluiten van de parser en het doorgeven van data; alledrie worden voorafgegaan door een print statement voor het debuggen. Natuurlijk heb ik ook twee handlers gedefinieerd, StartElementHandler en EndElementHandler, maar ik heb dat op de interpreter geprobeerd met twee versimpelde handlers en het werkte nog steeds prima.)
Heeft iemand enige clue waarom ik deze fout krijg?
Ik heb aan de hand van een bestaande library (waarvan ik de code echter extreem ranzig en slecht leesbaar vind) en het meelezen met Trillian's XMPP-communicatie al een stukje geschreven. Nu heb ik echter een probleem met de Expat-parser wat ik totaal niet begrijp. Ik hoop dat iemand kan helpen.
Ik voer de de Expat-parser telkens een stukje XML. Dat begint gewoon met een XML prolog en de root-tag voor de sessie/het document (stream:stream), daarna ontvang ik een zooi features. Aan de hand daarvan stuur ik een starttls, die vervolgens wordt opgevolgd met een respons van proceed. Daar gaat het echter fout:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| RESTARTING CONNECTION
INITIALIZING PARSER
OUTGOING: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xml:lang="en" version="1.0" xmlns="jabber:client" to="manuzhai.nl">
PARSING: '<?xml version=\'1.0\' encoding=\'UTF-8\'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="manuzhai.nl" id="adeba218" xml:lang="en" version="1.0"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms></stream:features>'
STANZA: <ns0:features xmlns:ns0="http://etherx.jabber.org/streams"><ns1:starttls xmlns:ns1="urn:ietf:params:xml:ns:xmpp-tls"><ns1:required /></ns1:starttls><ns1:mechanisms xmlns:ns1="urn:ietf:params:xml:ns:xmpp-sasl"><ns1:mechanism /><ns1:mechanism /><ns1:mechanism /></ns1:mechanisms></ns0:features>
OUTGOING: <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls" />
PARSING: '<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "session.py", line 70, in connect
self.start()
File "session.py", line 76, in start
self.send('<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xml:lang="en" version="1.0" xmlns="jabber:client" to="%s">' % self.jid.host)
File "session.py", line 102, in send
self.process()
File "session.py", line 82, in process
self.parser.feed(data)
File "session.py", line 21, in feed
self.parser.Parse(data, 0)
File "session.py", line 41, in _end
self.stream.handle(self.path.pop())
File "session.py", line 94, in handle
handler(stanza)
File "session.py", line 108, in features
self.checkTLS()
File "session.py", line 121, in checkTLS
self.send('<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls" />')
File "session.py", line 102, in send
self.process()
File "session.py", line 82, in process
self.parser.feed(data)
File "session.py", line 21, in feed
self.parser.Parse(data, 0)
xml.parsers.expat.ExpatError: xml declaration not at start of external entity: line 1, column 0 |
Ik snap alleen totaal niet waarom dit gebeurt! Dit werkt namelijk wel:
code:
1
2
3
| xp = expat.ParserCreate(namespace_separator = '}')
xp.Parse('<?xml version=\'1.0\' encoding=\'UTF-8\'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="manuzhai.nl" id="2fb8d964" xml:lang="en" version="1.0"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms></stream:features>', 0)
xp.Parse('<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>', 0) |
Er zijn echter behalve deze statements in mijn code geen interactie met de Expat parser! (Er zijn drie directe mogelijkheden: het creeeren, het afsluiten van de parser en het doorgeven van data; alledrie worden voorafgegaan door een print statement voor het debuggen. Natuurlijk heb ik ook twee handlers gedefinieerd, StartElementHandler en EndElementHandler, maar ik heb dat op de interpreter geprobeerd met twee versimpelde handlers en het werkte nog steeds prima.)
Heeft iemand enige clue waarom ik deze fout krijg?
Rustacean