source: sandbox/jabberit_messenger/trophy/strophejs/examples/attach/boshclient.py @ 2271

Revision 2271, 5.0 KB checked in by alexandrecorreia, 14 years ago (diff)

Ticket #986 - Reimplementar interface mais leve para o IM, sem a necessidades de plugins adicionais.

  • Property svn:executable set to *
Line 
1import sys, os
2import httplib, urllib
3import random, binascii
4from urlparse import urlparse
5
6from punjab.httpb import HttpbParse
7
8from twisted.words.xish import domish
9from twisted.words.protocols.jabber import jid
10
11TLS_XMLNS = 'urn:ietf:params:xml:ns:xmpp-tls'
12SASL_XMLNS = 'urn:ietf:params:xml:ns:xmpp-sasl'
13BIND_XMLNS = 'urn:ietf:params:xml:ns:xmpp-bind'
14SESSION_XMLNS = 'urn:ietf:params:xml:ns:xmpp-session'
15
16
17class BOSHClient:
18    def __init__(self, jabberid, password, bosh_service):
19        self.rid = random.randint(0, 10000000)
20        self.jabberid = jid.internJID(jabberid)
21        self.password = password
22
23        self.authid = None
24        self.sid = None
25        self.logged_in = False
26        self.headers = {"Content-type": "text/xml",
27                        "Accept": "text/xml"}
28
29        self.bosh_service = urlparse(bosh_service)
30       
31    def buildBody(self, child=None):
32        """Build a BOSH body.
33        """
34       
35        body = domish.Element(("http://jabber.org/protocol/httpbind", "body"))
36        body['content'] = 'text/xml; charset=utf-8'
37        self.rid = self.rid + 1
38        body['rid'] = str(self.rid)
39        body['sid'] = str(self.sid)
40        body['xml:lang'] = 'en'
41     
42        if child is not None:
43            body.addChild(child)
44
45        return body
46       
47    def sendBody(self, body):
48        """Send the body.
49        """
50
51        parser = HttpbParse(True)
52
53        # start new session
54        conn = httplib.HTTPConnection(self.bosh_service.netloc)
55        conn.request("POST", self.bosh_service.path,
56                     body.toXml(), self.headers)
57
58        response = conn.getresponse()
59        data = ''
60        if response.status == 200:
61            data = response.read()
62        conn.close()
63
64        return parser.parse(data)
65
66    def startSessionAndAuth(self, hold='1', wait='70'):
67        # Create a session
68        # create body
69        body = domish.Element(("http://jabber.org/protocol/httpbind", "body"))
70
71        body['content'] = 'text/xml; charset=utf-8'
72        body['hold'] = hold
73        body['rid'] = str(self.rid)
74        body['to'] = self.jabberid.host
75        body['wait'] = wait
76        body['window'] = '5'
77        body['xml:lang'] = 'en'
78
79
80        retb, elems = self.sendBody(body)
81        if type(retb) != str and retb.hasAttribute('authid') and \
82                retb.hasAttribute('sid'):
83            self.authid = retb['authid']
84            self.sid = retb['sid']
85
86            # go ahead and auth
87            auth = domish.Element((SASL_XMLNS, 'auth'))
88            auth['mechanism'] = 'PLAIN'
89           
90            # TODO: add authzid
91            if auth['mechanism'] == 'PLAIN':
92                auth_str = ""
93                auth_str += "\000"
94                auth_str += self.jabberid.user.encode('utf-8')
95                auth_str += "\000"
96                try:
97                    auth_str += self.password.encode('utf-8').strip()
98                except UnicodeDecodeError:
99                    auth_str += self.password.decode('latin1') \
100                        .encode('utf-8').strip()
101                       
102                auth.addContent(binascii.b2a_base64(auth_str))
103               
104                retb, elems = self.sendBody(self.buildBody(auth))
105                if len(elems) == 0:
106                    # poll for data
107                    retb, elems = self.sendBody(self.buildBody())
108
109                if len(elems) > 0:
110                    if elems[0].name == 'success':
111                        retb, elems = self.sendBody(self.buildBody())
112                       
113                        if elems[0].firstChildElement().name == 'bind':
114                            iq = domish.Element(('jabber:client', 'iq'))
115                            iq['type'] = 'set'
116                            iq.addUniqueId()
117                            iq.addElement('bind')
118                            iq.bind['xmlns'] = BIND_XMLNS
119                            if self.jabberid.resource:
120                                iq.bind.addElement('resource')
121                                iq.bind.resource.addContent(
122                                    self.jabberid.resource)
123
124                            retb, elems = self.sendBody(self.buildBody(iq))
125                            if type(retb) != str and retb.name == 'body':
126                                # send session
127                                iq = domish.Element(('jabber:client', 'iq'))
128                                iq['type'] = 'set'
129                                iq.addUniqueId()
130                                iq.addElement('session')
131                                iq.session['xmlns'] = SESSION_XMLNS
132
133                                retb, elems = self.sendBody(self.buildBody(iq))
134
135                                # did not bind, TODO - add a retry?
136                                if type(retb) != str and retb.name == 'body':
137                                    self.logged_in = True
138                                    # bump up the rid, punjab already
139                                    # received self.rid
140                                    self.rid += 1
141
142
143if __name__ == '__main__':
144    USERNAME = sys.argv[1]
145    PASSWORD = sys.argv[2]
146    SERVICE = sys.argv[3]
147
148    c = BOSHClient(USERNAME, PASSWORD, SERVICE)
149    c.startSessionAndAuth()
150
151    print c.logged_in
152   
Note: See TracBrowser for help on using the repository browser.