home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / pyxmpp / streambase.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  19.6 KB  |  754 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. __revision__ = '$Id: streambase.py 700 2010-04-03 15:34:59Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import libxml2
  7. import socket
  8. import os
  9. import time
  10. import random
  11. import threading
  12. import errno
  13. import logging
  14. from pyxmpp import xmlextra
  15. from pyxmpp.expdict import ExpiringDictionary
  16. from pyxmpp.utils import to_utf8
  17. from pyxmpp.stanza import Stanza
  18. from pyxmpp.error import StreamErrorNode
  19. from pyxmpp.iq import Iq
  20. from pyxmpp.presence import Presence
  21. from pyxmpp.message import Message
  22. from pyxmpp.jid import JID
  23. from pyxmpp import resolver
  24. from pyxmpp.stanzaprocessor import StanzaProcessor
  25. from pyxmpp.exceptions import StreamError, StreamEncryptionRequired, HostMismatch, ProtocolError
  26. from pyxmpp.exceptions import FatalStreamError, StreamParseError, StreamAuthenticationError
  27. STREAM_NS = 'http://etherx.jabber.org/streams'
  28. BIND_NS = 'urn:ietf:params:xml:ns:xmpp-bind'
  29.  
  30. def stanza_factory(xmlnode, stream = None):
  31.     if xmlnode.name == 'iq':
  32.         return Iq(xmlnode, stream = stream)
  33.     if xmlnode.name == 'message':
  34.         return Message(xmlnode, stream = stream)
  35.     if xmlnode.name == 'presence':
  36.         return Presence(xmlnode, stream = stream)
  37.     return Stanza(xmlnode, stream = stream)
  38.  
  39.  
  40. class StreamBase(StanzaProcessor, xmlextra.StreamHandler):
  41.     
  42.     def __init__(self, default_ns, extra_ns = (), keepalive = 0, owner = None):
  43.         StanzaProcessor.__init__(self)
  44.         xmlextra.StreamHandler.__init__(self)
  45.         self.default_ns_uri = default_ns
  46.         if extra_ns:
  47.             self.extra_ns_uris = extra_ns
  48.         else:
  49.             self.extra_ns_uris = []
  50.         self.keepalive = keepalive
  51.         self._reader_lock = threading.Lock()
  52.         self.process_all_stanzas = False
  53.         self.port = None
  54.         self._reset()
  55.         self.owner = owner
  56.         self._StreamBase__logger = logging.getLogger('pyxmpp.Stream')
  57.  
  58.     
  59.     def _reset(self):
  60.         self.doc_in = None
  61.         self.doc_out = None
  62.         self.socket = None
  63.         self._reader = None
  64.         self.addr = None
  65.         self.default_ns = None
  66.         self.extra_ns = { }
  67.         self.stream_ns = None
  68.         self._reader = None
  69.         self.ioreader = None
  70.         self.me = None
  71.         self.peer = None
  72.         self.skip = False
  73.         self.stream_id = None
  74.         self._iq_response_handlers = ExpiringDictionary()
  75.         self._iq_get_handlers = { }
  76.         self._iq_set_handlers = { }
  77.         self._message_handlers = []
  78.         self._presence_handlers = []
  79.         self.eof = False
  80.         self.initiator = None
  81.         self.features = None
  82.         self.authenticated = False
  83.         self.peer_authenticated = False
  84.         self.auth_method_used = None
  85.         self.version = None
  86.         self.last_keepalive = False
  87.  
  88.     
  89.     def _connect_socket(self, sock, to = None):
  90.         self.eof = 0
  91.         self.socket = sock
  92.         if to:
  93.             self.peer = JID(to)
  94.         else:
  95.             self.peer = None
  96.         self.initiator = 1
  97.         self._send_stream_start()
  98.         self._make_reader()
  99.  
  100.     
  101.     def connect(self, addr, port, service = None, to = None):
  102.         self.lock.acquire()
  103.         
  104.         try:
  105.             return self._connect(addr, port, service, to)
  106.         finally:
  107.             self.lock.release()
  108.  
  109.  
  110.     
  111.     def _connect(self, addr, port, service = None, to = None):
  112.         if to is None:
  113.             to = str(addr)
  114.         
  115.         if service is not None:
  116.             self.state_change('resolving srv', (addr, service))
  117.             addrs = resolver.resolve_srv(addr, service)
  118.             if not addrs:
  119.                 addrs = [
  120.                     (addr, port)]
  121.             
  122.         else:
  123.             addrs = [
  124.                 (addr, port)]
  125.         msg = None
  126.         for addr, port in addrs:
  127.             if type(addr) in (str, unicode):
  128.                 self.state_change('resolving', addr)
  129.             
  130.             s = None
  131.             for res in resolver.getaddrinfo(addr, port, 0, socket.SOCK_STREAM):
  132.                 (family, socktype, proto, _unused, sockaddr) = res
  133.                 
  134.                 try:
  135.                     s = socket.socket(family, socktype, proto)
  136.                     self.state_change('connecting', sockaddr)
  137.                     s.connect(sockaddr)
  138.                     self.state_change('connected', sockaddr)
  139.                 except socket.error:
  140.                     msg = None
  141.                     self._StreamBase__logger.debug('Connect to %r failed' % (sockaddr,))
  142.                     if s:
  143.                         s.close()
  144.                         s = None
  145.                         continue
  146.                     continue
  147.  
  148.             
  149.             if s:
  150.                 break
  151.                 continue
  152.         
  153.         if not s:
  154.             if msg:
  155.                 raise socket.error, msg
  156.             msg
  157.             raise FatalStreamError, 'Cannot connect'
  158.         s
  159.         self.addr = addr
  160.         self.port = port
  161.         self._connect_socket(s, to)
  162.         self.last_keepalive = time.time()
  163.  
  164.     
  165.     def accept(self, sock, myname):
  166.         self.lock.acquire()
  167.         
  168.         try:
  169.             return self._accept(sock, myname)
  170.         finally:
  171.             self.lock.release()
  172.  
  173.  
  174.     
  175.     def _accept(self, sock, myname):
  176.         self.eof = 0
  177.         (self.socket, addr) = sock.accept()
  178.         self._StreamBase__logger.debug('Connection from: %r' % (addr,))
  179.         (self.addr, self.port) = addr
  180.         if myname:
  181.             self.me = JID(myname)
  182.         else:
  183.             self.me = None
  184.         self.initiator = 0
  185.         self._make_reader()
  186.         self.last_keepalive = time.time()
  187.  
  188.     
  189.     def disconnect(self):
  190.         self.lock.acquire()
  191.         
  192.         try:
  193.             return self._disconnect()
  194.         finally:
  195.             self.lock.release()
  196.  
  197.  
  198.     
  199.     def _disconnect(self):
  200.         if self.doc_out:
  201.             self._send_stream_end()
  202.         
  203.  
  204.     
  205.     def _post_connect(self):
  206.         pass
  207.  
  208.     
  209.     def _post_auth(self):
  210.         pass
  211.  
  212.     
  213.     def state_change(self, state, arg):
  214.         self._StreamBase__logger.debug('State: %s: %r' % (state, arg))
  215.  
  216.     
  217.     def close(self):
  218.         self.lock.acquire()
  219.         
  220.         try:
  221.             return self._close()
  222.         finally:
  223.             self.lock.release()
  224.  
  225.  
  226.     
  227.     def _close(self):
  228.         self._disconnect()
  229.         if self.doc_in:
  230.             self.doc_in = None
  231.         
  232.         if self.features:
  233.             self.features = None
  234.         
  235.         self._reader = None
  236.         self.stream_id = None
  237.         if self.socket:
  238.             self.socket.close()
  239.         
  240.         self._reset()
  241.  
  242.     
  243.     def _make_reader(self):
  244.         self._reader = xmlextra.StreamReader(self)
  245.  
  246.     
  247.     def stream_start(self, doc):
  248.         self.doc_in = doc
  249.         self._StreamBase__logger.debug('input document: %r' % (self.doc_in.serialize(),))
  250.         
  251.         try:
  252.             r = self.doc_in.getRootElement()
  253.             if r.ns().getContent() != STREAM_NS:
  254.                 self._send_stream_error('invalid-namespace')
  255.                 raise FatalStreamError, 'Invalid namespace.'
  256.             r.ns().getContent() != STREAM_NS
  257.         except libxml2.treeError:
  258.             self._send_stream_error('invalid-namespace')
  259.             raise FatalStreamError, "Couldn't get the namespace."
  260.  
  261.         self.version = r.prop('version')
  262.         if self.version and self.version != '1.0':
  263.             self._send_stream_error('unsupported-version')
  264.             raise FatalStreamError, 'Unsupported protocol version.'
  265.         self.version != '1.0'
  266.         to_from_mismatch = 0
  267.         if self.initiator:
  268.             self.stream_id = r.prop('id')
  269.             peer = r.prop('from')
  270.             if peer:
  271.                 peer = JID(peer)
  272.             
  273.             if self.peer:
  274.                 if peer and peer != self.peer:
  275.                     self._StreamBase__logger.debug('peer hostname mismatch: %r != %r' % (peer, self.peer))
  276.                     to_from_mismatch = 1
  277.                 
  278.             else:
  279.                 self.peer = peer
  280.         else:
  281.             to = r.prop('to')
  282.             if to:
  283.                 to = self.check_to(to)
  284.                 if not to:
  285.                     self._send_stream_error('host-unknown')
  286.                     raise FatalStreamError, 'Bad "to"'
  287.                 to
  288.                 self.me = JID(to)
  289.             
  290.             self._send_stream_start(self.generate_id())
  291.             self._send_stream_features()
  292.             self.state_change('fully connected', self.peer)
  293.             self._post_connect()
  294.         if not self.version:
  295.             self.state_change('fully connected', self.peer)
  296.             self._post_connect()
  297.         
  298.         if to_from_mismatch:
  299.             raise HostMismatch
  300.         to_from_mismatch
  301.  
  302.     
  303.     def stream_end(self, _unused):
  304.         self._StreamBase__logger.debug('Stream ended')
  305.         self.eof = 1
  306.         if self.doc_out:
  307.             self._send_stream_end()
  308.         
  309.         if self.doc_in:
  310.             self.doc_in = None
  311.             self._reader = None
  312.             if self.features:
  313.                 self.features = None
  314.             
  315.         
  316.         self.state_change('disconnected', self.peer)
  317.  
  318.     
  319.     def stanza_start(self, doc, node):
  320.         pass
  321.  
  322.     
  323.     def stanza(self, _unused, node):
  324.         self._process_node(node)
  325.  
  326.     
  327.     def error(self, descr):
  328.         raise StreamParseError, descr
  329.  
  330.     
  331.     def _send_stream_end(self):
  332.         self.doc_out.getRootElement().addContent(' ')
  333.         s = self.doc_out.getRootElement().serialize(encoding = 'UTF-8')
  334.         end = s.rindex('<')
  335.         
  336.         try:
  337.             self._write_raw(s[end:])
  338.         except (IOError, SystemError, socket.error):
  339.             e = None
  340.             self._StreamBase__logger.debug('Sending stream closing tag failed:' + str(e))
  341.  
  342.         self.doc_out.freeDoc()
  343.         self.doc_out = None
  344.         if self.features:
  345.             self.features = None
  346.         
  347.  
  348.     
  349.     def _send_stream_start(self, sid = None):
  350.         if self.doc_out:
  351.             raise StreamError, 'Stream start already sent'
  352.         self.doc_out
  353.         self.doc_out = libxml2.newDoc('1.0')
  354.         root = self.doc_out.newChild(None, 'stream', None)
  355.         self.stream_ns = root.newNs(STREAM_NS, 'stream')
  356.         root.setNs(self.stream_ns)
  357.         self.default_ns = root.newNs(self.default_ns_uri, None)
  358.         for prefix, uri in self.extra_ns:
  359.             self.extra_ns[uri] = root.newNs(uri, prefix)
  360.         
  361.         if self.peer and self.initiator:
  362.             root.setProp('to', self.peer.as_utf8())
  363.         
  364.         if self.me and not (self.initiator):
  365.             root.setProp('from', self.me.as_utf8())
  366.         
  367.         root.setProp('version', '1.0')
  368.         if sid:
  369.             root.setProp('id', sid)
  370.             self.stream_id = sid
  371.         
  372.         sr = self.doc_out.serialize(encoding = 'UTF-8')
  373.         self._write_raw(sr[:sr.find('/>')] + '>')
  374.  
  375.     
  376.     def _send_stream_error(self, condition):
  377.         if not self.doc_out:
  378.             self._send_stream_start()
  379.         
  380.         e = StreamErrorNode(condition)
  381.         e.xmlnode.setNs(self.stream_ns)
  382.         self._write_raw(e.serialize())
  383.         e.free()
  384.         self._send_stream_end()
  385.  
  386.     
  387.     def _restart_stream(self):
  388.         self._reader = None
  389.         self.doc_out = None
  390.         self.doc_in = None
  391.         self.features = None
  392.         if self.initiator:
  393.             self._send_stream_start(self.stream_id)
  394.         
  395.         self._make_reader()
  396.  
  397.     
  398.     def _make_stream_features(self):
  399.         root = self.doc_out.getRootElement()
  400.         features = root.newChild(root.ns(), 'features', None)
  401.         return features
  402.  
  403.     
  404.     def _send_stream_features(self):
  405.         self.features = self._make_stream_features()
  406.         self._write_raw(self.features.serialize(encoding = 'UTF-8'))
  407.  
  408.     
  409.     def write_raw(self, data):
  410.         self.lock.acquire()
  411.         
  412.         try:
  413.             return self._write_raw(data)
  414.         finally:
  415.             self.lock.release()
  416.  
  417.  
  418.     
  419.     def _write_raw(self, data):
  420.         logging.getLogger('pyxmpp.Stream.out').debug('OUT: %r', data)
  421.         
  422.         try:
  423.             self.socket.send(data)
  424.         except (IOError, OSError, socket.error):
  425.             e = None
  426.             raise FatalStreamError('IO Error: ' + str(e))
  427.  
  428.  
  429.     
  430.     def _write_node(self, xmlnode):
  431.         if self.eof and not (self.socket) or not (self.doc_out):
  432.             self._StreamBase__logger.debug('Dropping stanza: %r' % (xmlnode,))
  433.             return None
  434.         xmlnode = xmlnode.docCopyNode(self.doc_out, 1)
  435.         self.doc_out.addChild(xmlnode)
  436.         
  437.         try:
  438.             ns = xmlnode.ns()
  439.         except libxml2.treeError:
  440.             not (self.doc_out)
  441.             not (self.doc_out)
  442.             ns = None
  443.         except:
  444.             not (self.doc_out)
  445.  
  446.         if ns and ns.content == xmlextra.COMMON_NS:
  447.             xmlextra.replace_ns(xmlnode, ns, self.default_ns)
  448.         
  449.         s = xmlextra.safe_serialize(xmlnode)
  450.         self._write_raw(s)
  451.         xmlnode.unlinkNode()
  452.         xmlnode.freeNode()
  453.  
  454.     
  455.     def send(self, stanza):
  456.         self.lock.acquire()
  457.         
  458.         try:
  459.             return self._send(stanza)
  460.         finally:
  461.             self.lock.release()
  462.  
  463.  
  464.     
  465.     def _send(self, stanza):
  466.         if not self.version:
  467.             
  468.             try:
  469.                 err = stanza.get_error()
  470.             except ProtocolError:
  471.                 err = None
  472.  
  473.             if err:
  474.                 err.downgrade()
  475.             
  476.         
  477.         self.fix_out_stanza(stanza)
  478.         self._write_node(stanza.xmlnode)
  479.  
  480.     
  481.     def idle(self):
  482.         self.lock.acquire()
  483.         
  484.         try:
  485.             return self._idle()
  486.         finally:
  487.             self.lock.release()
  488.  
  489.  
  490.     
  491.     def _idle(self):
  492.         self._iq_response_handlers.expire()
  493.         if not (self.socket) or self.eof:
  494.             return None
  495.         now = time.time()
  496.         if self.keepalive and now - self.last_keepalive >= self.keepalive:
  497.             self._write_raw(' ')
  498.             self.last_keepalive = now
  499.         
  500.  
  501.     
  502.     def fileno(self):
  503.         self.lock.acquire()
  504.         
  505.         try:
  506.             return self.socket.fileno()
  507.         finally:
  508.             self.lock.release()
  509.  
  510.  
  511.     
  512.     def loop(self, timeout):
  513.         self.lock.acquire()
  514.         
  515.         try:
  516.             while not (self.eof) and self.socket is not None:
  517.                 act = self._loop_iter(timeout)
  518.                 if not act:
  519.                     self._idle()
  520.                     continue
  521.         finally:
  522.             self.lock.release()
  523.  
  524.  
  525.     
  526.     def loop_iter(self, timeout):
  527.         self.lock.acquire()
  528.         
  529.         try:
  530.             return self._loop_iter(timeout)
  531.         finally:
  532.             self.lock.release()
  533.  
  534.  
  535.     
  536.     def _loop_iter(self, timeout):
  537.         import select
  538.         self.lock.release()
  539.         
  540.         try:
  541.             if not self.socket:
  542.                 time.sleep(timeout)
  543.                 return False
  544.             
  545.             try:
  546.                 (ifd, _unused, efd) = select.select([
  547.                     self.socket], [], [
  548.                     self.socket], timeout)
  549.             except select.error:
  550.                 self.socket
  551.                 e = self.socket
  552.                 if e.args[0] != errno.EINTR:
  553.                     raise 
  554.                 e.args[0] != errno.EINTR
  555.                 ifd = []
  556.                 _unused = []
  557.                 efd = []
  558.             except:
  559.                 self.socket
  560.  
  561.         finally:
  562.             self.lock.acquire()
  563.  
  564.         if self.socket in ifd or self.socket in efd:
  565.             self._process()
  566.             return True
  567.         return False
  568.  
  569.     
  570.     def process(self):
  571.         self.lock.acquire()
  572.         
  573.         try:
  574.             self._process()
  575.         finally:
  576.             self.lock.release()
  577.  
  578.  
  579.     
  580.     def _process(self):
  581.         
  582.         try:
  583.             
  584.             try:
  585.                 self._read()
  586.             except (xmlextra.error,):
  587.                 e = None
  588.                 self._StreamBase__logger.exception('Exception during read()')
  589.                 raise StreamParseError(unicode(e))
  590.             except:
  591.                 raise 
  592.  
  593.         except (IOError, OSError, socket.error):
  594.             e = None
  595.             self.close()
  596.             raise FatalStreamError('IO Error: ' + str(e))
  597.         except (FatalStreamError, KeyboardInterrupt, SystemExit):
  598.             e = None
  599.             self.close()
  600.             raise 
  601.  
  602.  
  603.     
  604.     def _read(self):
  605.         self._StreamBase__logger.debug('StreamBase._read(), socket: %r', self.socket)
  606.         if self.eof:
  607.             return None
  608.         
  609.         try:
  610.             r = self.socket.recv(1024)
  611.         except socket.error:
  612.             self.eof
  613.             e = self.eof
  614.             if e.args[0] != errno.EINTR:
  615.                 raise 
  616.             e.args[0] != errno.EINTR
  617.             return None
  618.  
  619.         self._feed_reader(r)
  620.  
  621.     
  622.     def _feed_reader(self, data):
  623.         logging.getLogger('pyxmpp.Stream.in').debug('IN: %r', data)
  624.         if data:
  625.             
  626.             try:
  627.                 r = self._reader.feed(data)
  628.                 while r:
  629.                     r = self._reader.feed('')
  630.                 if r is None:
  631.                     self.eof = 1
  632.                     self.disconnect()
  633.             except StreamParseError:
  634.                 self._send_stream_error('xml-not-well-formed')
  635.                 raise 
  636.             except:
  637.                 None<EXCEPTION MATCH>StreamParseError
  638.             
  639.  
  640.         None<EXCEPTION MATCH>StreamParseError
  641.         self.eof = 1
  642.         self.disconnect()
  643.         if self.eof:
  644.             self.stream_end(None)
  645.         
  646.  
  647.     
  648.     def _process_node(self, xmlnode):
  649.         ns_uri = xmlnode.ns().getContent()
  650.         if ns_uri == 'http://etherx.jabber.org/streams':
  651.             self._process_stream_node(xmlnode)
  652.             return None
  653.         if ns_uri == self.default_ns_uri:
  654.             stanza = stanza_factory(xmlnode, self)
  655.             self.lock.release()
  656.             
  657.             try:
  658.                 self.process_stanza(stanza)
  659.             finally:
  660.                 self.lock.acquire()
  661.                 stanza.free()
  662.  
  663.         else:
  664.             self._StreamBase__logger.debug('Unhandled node: %r' % (xmlnode.serialize(),))
  665.  
  666.     
  667.     def _process_stream_node(self, xmlnode):
  668.         if xmlnode.name == 'error':
  669.             e = StreamErrorNode(xmlnode)
  670.             self.lock.release()
  671.             
  672.             try:
  673.                 self.process_stream_error(e)
  674.             finally:
  675.                 self.lock.acquire()
  676.                 e.free()
  677.  
  678.             return None
  679.         if xmlnode.name == 'features':
  680.             self._StreamBase__logger.debug('Got stream features')
  681.             self._StreamBase__logger.debug('Node: %r' % (xmlnode,))
  682.             self.features = xmlnode.copyNode(1)
  683.             self.doc_in.addChild(self.features)
  684.             self._got_features()
  685.             return None
  686.         self._StreamBase__logger.debug('Unhandled stream node: %r' % (xmlnode.serialize(),))
  687.  
  688.     
  689.     def process_stream_error(self, err):
  690.         self._StreamBase__logger.debug('Unhandled stream error: condition: %s %r' % (err.get_condition().name, err.serialize()))
  691.  
  692.     
  693.     def check_to(self, to):
  694.         if to != self.me:
  695.             return None
  696.         return to
  697.  
  698.     
  699.     def generate_id(self):
  700.         return '%i-%i-%s' % (os.getpid(), time.time(), str(random.random())[2:])
  701.  
  702.     
  703.     def _got_features(self):
  704.         ctxt = self.doc_in.xpathNewContext()
  705.         ctxt.setContextNode(self.features)
  706.         ctxt.xpathRegisterNs('stream', STREAM_NS)
  707.         ctxt.xpathRegisterNs('bind', BIND_NS)
  708.         bind_n = None
  709.         
  710.         try:
  711.             bind_n = ctxt.xpathEval('bind:bind')
  712.         finally:
  713.             ctxt.xpathFreeContext()
  714.  
  715.         if self.authenticated:
  716.             if bind_n:
  717.                 self.bind(self.me.resource)
  718.             else:
  719.                 self.state_change('authorized', self.me)
  720.         
  721.  
  722.     
  723.     def bind(self, resource):
  724.         iq = Iq(stanza_type = 'set')
  725.         q = iq.new_query(BIND_NS, u'bind')
  726.         if resource:
  727.             q.newTextChild(None, 'resource', to_utf8(resource))
  728.         
  729.         self.state_change('binding', resource)
  730.         self.set_response_handlers(iq, self._bind_success, self._bind_error)
  731.         self.send(iq)
  732.         iq.free()
  733.  
  734.     
  735.     def _bind_success(self, stanza):
  736.         jid_n = stanza.xpath_eval('bind:bind/bind:jid', {
  737.             'bind': BIND_NS })
  738.         if jid_n:
  739.             self.me = JID(jid_n[0].getContent().decode('utf-8'))
  740.         
  741.         self.state_change('authorized', self.me)
  742.  
  743.     
  744.     def _bind_error(self, stanza):
  745.         raise FatalStreamError, 'Resource binding failed'
  746.  
  747.     
  748.     def connected(self):
  749.         if self.doc_in and self.doc_out and not (self.eof):
  750.             return True
  751.         return False
  752.  
  753.  
  754.