Show
Ignore:
Timestamp:
07/03/08 01:29:10 (5 months ago)
Author:
tomk
Message:

moved bosh code from client_nb.py to bosh.py, replaced debug logging with debug.py by logging in whole xmpppy (debug.py is now unused)

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/bosh_support/src/common/xmpp/client_nb.py

    r9870 r9877  
    2323 
    2424import socket 
    25 import debug 
    26 import random 
    2725 
    2826import transports_nb, tls_nb, dispatcher_nb, auth_nb, roster_nb, protocol 
     
    3230log = logging.getLogger('gajim.c.x.client_nb') 
    3331 
    34 consoleloghandler = logging.StreamHandler() 
    35 consoleloghandler.setLevel(logging.DEBUG) 
    36 consoleloghandler.setFormatter( 
    37         logging.Formatter('%(levelname)s: %(message)s') 
    38 ) 
    39 log.setLevel(logging.DEBUG) 
    40 log.addHandler(consoleloghandler) 
    41 log.propagate = False 
    42  
    4332 
    4433class NBCommonClient: 
    4534        ''' Base for Client and Component classes.''' 
    46         def __init__(self, hostname, idlequeue, port=5222, debug=['always', 'nodebuilder'], caller=None): 
     35        def __init__(self, domain, idlequeue, caller=None): 
    4736                 
    4837                ''' Caches connection data: 
    49                 :param hostname: hostname of machine where the XMPP server is running (from Account 
    50                         of from SRV request) and port to connect to. 
     38                :param domain: domain - for to: attribute (from account info) 
    5139                :param idlequeue: processing idlequeue 
    5240                :param port: port of listening XMPP server 
    53                 :param debug: specifies the debug IDs that will go into debug output. You can either 
    54                         specifiy an "include" or "exclude" list. The latter is done via adding "always"  
    55                         pseudo-ID to the list. Full list: ['nodebuilder', 'dispatcher', 'gen_auth',  
    56                         'SASL_auth', 'bind', 'socket', 'CONNECTproxy', 'TLS', 'roster', 'browser', 'ibb']. 
    57                         TODO: get rid of debug.py using 
    5841                :param caller: calling object - it has to implement certain methods (necessary?) 
    5942                         
    6043                ''' 
    6144                 
    62                 self.DBG = DBG_CLIENT 
    63  
    6445                self.Namespace = protocol.NS_CLIENT 
    6546 
     
    6849                self.disconnect_handlers = [] 
    6950 
    70                 # XMPP server and port from account or SRV 
    71                 self.Server = hostname 
    72                 self.Port = port 
     51                self.Server = domain 
    7352                 
    7453                # caller is who initiated this client, it is sed to register the EventDispatcher 
    7554                self._caller = caller 
    76                 if debug and type(debug) != list:  
    77                         debug = ['always', 'nodebuilder'] 
    78                 self._DEBUG = Debug.Debug(debug) 
    79                 self.DEBUG = self._DEBUG.Show 
    80                 self.debug_flags = self._DEBUG.debug_flags 
    81                 self.debug_flags.append(self.DBG) 
    8255                self._owner = self 
    8356                self._registered_name = None 
     
    9972                 
    10073                self.connected='' 
    101                 self.DEBUG(self.DBG,'Disconnect detected','stop') 
     74                log.debug('Client disconnected..') 
    10275                for i in reversed(self.disconnect_handlers): 
    103                         self.DEBUG(self.DBG, 'Calling disc handler %s' % i, 'stop') 
     76                        log.debug('Calling disconnect handler %s' % i) 
    10477                        i() 
    10578                if self.__dict__.has_key('NonBlockingRoster'): 
     
    12194                 
    12295 
    123         def send(self, stanza, is_message = False, now = False): 
     96        def send(self, stanza, now = False): 
    12497                ''' interface for putting stanzas on wire. Puts ID to stanza if needed and 
    12598                sends it via socket wrapper''' 
    12699                (id, stanza_to_send) = self.Dispatcher.assign_id(stanza) 
    127100 
    128                 if is_message: 
    129                         # somehow zeroconf-specific 
    130                         self.Connection.send(stanza_to_send, True, now = now) 
    131                 else: 
    132                         self.Connection.send(stanza_to_send, now = now) 
     101                self.Connection.send(stanza_to_send, now = now) 
    133102                return id 
    134103 
    135104 
    136105 
    137         def connect(self, on_connect, on_connect_failure, on_proxy_failure=None, proxy=None, secure=None): 
     106        def connect(self, on_connect, on_connect_failure, hostname=None, port=5222,  
     107                on_proxy_failure=None, proxy=None, secure=None): 
    138108                '''  
    139109                Open XMPP connection (open streams in both directions). 
     110                :param hostname: hostname of XMPP server from SRV request  
     111                :param port: port number of XMPP server 
    140112                :param on_connect: called after stream is successfully opened 
    141113                :param on_connect_failure: called when error occures during connection 
     
    147119                :param secure: 
    148120                ''' 
    149                  
     121                self.Port = port 
     122                if hostname: 
     123                        xmpp_hostname = hostname 
     124                else: 
     125                        xmpp_hostname = self.Server 
     126 
    150127                self.on_connect = on_connect 
    151128                self.on_connect_failure=on_connect_failure 
     
    156133                if proxy: 
    157134                        # with proxies, client connects to proxy instead of directly to 
    158                         # XMPP server from __init__.  
    159                         # tcp_server is hostname used for socket connecting 
     135                        # XMPP server ((hostname, port)) 
     136                        # tcp_server is machine used for socket connection 
    160137                        tcp_server=proxy['host']                         
    161138                        tcp_port=proxy['port'] 
     
    169146                                type_ = proxy['type'] 
    170147                                if type_ == 'socks5': 
     148                                        # SOCKS5 proxy 
    171149                                        self.socket = transports_nb.NBSOCKS5ProxySocket( 
    172150                                                on_disconnect=self.on_disconnect, 
    173151                                                proxy_creds=proxy_creds, 
    174                                                 xmpp_server=(self.Server, self.Port)) 
     152                                                xmpp_server=(xmpp_hostname, self.Port)) 
    175153                                elif type_ == 'http': 
     154                                        # HTTP CONNECT to proxy 
    176155                                        self.socket = transports_nb.NBHTTPProxySocket( 
    177156                                                on_disconnect=self.on_disconnect, 
    178157                                                proxy_creds=proxy_creds, 
    179                                                 xmpp_server=(self.Server, self.Port)) 
     158                                                xmpp_server=(xmpp_hostname, self.Port)) 
    180159                                elif type_ == 'bosh': 
     160                                        # BOSH - XMPP over HTTP 
    181161                                        tcp_server = transports_nb.urisplit(tcp_server)[1] 
    182                                         self.socket = transports_nb.NonBlockingHttpBOSH( 
     162                                        self.socket = transports_nb.NonBlockingHTTP( 
    183163                                                on_disconnect=self.on_disconnect, 
    184                                                 bosh_uri = proxy['host'], 
    185                                                 bosh_port = tcp_port) 
     164                                                http_uri = proxy['host'], 
     165                                                http_port = tcp_port) 
    186166                        else: 
    187167                                # HTTP CONNECT to proxy from environment variables 
     
    189169                                        on_disconnect=self.on_disconnect, 
    190170                                        proxy_creds=(None, None), 
    191                                         xmpp_server=(self.Server, self.Port)) 
     171                                        xmpp_server=(xmpp_hostname, self.Port)) 
    192172                else:  
    193173                        self._on_tcp_failure = self._on_connect_failure 
    194                         tcp_server=self.Server 
     174                        tcp_server=xmpp_hostname 
    195175                        tcp_port=self.Port 
    196176                        self.socket = transports_nb.NonBlockingTcp(on_disconnect = self.on_disconnect) 
     
    222202                '''iterates over IP addresses from getaddinfo''' 
    223203                if err_message: 
    224                         self.DEBUG(self.DBG,err_message,'connect') 
     204                        log.debug('While looping over DNS A records: %s' % connect) 
    225205                if self.ip_addresses == []: 
    226206                        self._on_tcp_failure(err_message='Run out of hosts for name %s:%s' %  
     
    306286                self.connected = None 
    307287                if err_message: 
    308                         self.DEBUG(self.DBG, err_message, 'connecting') 
     288                        log.debug('While connecting: %s' % err_message) 
    309289                if self.socket: 
    310290                        self.socket.disconnect() 
     
    461441 
    462442 
    463 class BOSHClient(NBCommonClient): 
    464         ''' 
    465         Client class implementing BOSH.  
    466         ''' 
    467         def __init__(self, *args, **kw): 
    468                 '''Preceeds constructor of NBCommonClient and sets some of values that will 
    469                 be used as attributes in <body> tag''' 
    470                 self.Namespace = NS_HTTP_BIND 
    471                 # BOSH parameters should be given via Advanced Configuration Editor 
    472                 self.bosh_hold = 1 
    473                 self.bosh_wait=60 
    474                 self.bosh_rid=-1 
    475                 self.bosh_httpversion = 'HTTP/1.1' 
    476                 NBCommonClient.__init__(self, *args, **kw) 
    477  
    478  
    479         def connect(self, *args, **kw): 
    480                 proxy = kw['proxy'] 
    481                 self.bosh_protocol, self.bosh_host, self.bosh_uri = self.urisplit(proxy['host']) 
    482                 self.bosh_port = proxy['port'] 
    483                 NBCommonClient.connect(*args, **kw) 
    484                  
    485  
    486         def _on_stream_start(self): 
    487                 ''' 
    488                 Called after XMPP stream is opened. In BOSH TLS is negotiated on tranport layer 
    489                 so success callback can be invoked. 
    490                 (authentication is started from auth() method) 
    491                 ''' 
    492                 self.onreceive(None) 
    493                 if self.connected == 'tcp': 
    494                         self._on_connect() 
    495  
    496  
    497  
    498  
    499  
    500         def bosh_raise_event(self, realm, event, data): 
    501                 # should to extract stanza from body 
    502                 self.DEBUG(self.DBG,'realm: %s, event: %s, data: %s' % (realm, event, data), 
    503                         'BOSH EventHandler') 
    504                 self._caller._event_dispatcher(realm, event, data) 
    505  
    506  
    507         def StreamInit(self): 
    508                 ''' 
    509                 Init of BOSH session. Called instead of Dispatcher.StreamInit() 
    510                 Initial body tag is created and sent. 
    511                 ''' 
    512                 #self.Dispatcher.RegisterEventHandler(self.bosh_event_handler) 
    513                 self.Dispatcher.Stream = simplexml.NodeBuilder() 
    514                 self.Dispatcher.Stream._dispatch_depth = 2 
    515                 self.Dispatcher.Stream.dispatch = self.Dispatcher.dispatch 
    516                 self.Dispatcher.Stream.stream_header_received = self._check_stream_start 
    517                 self.Dispatcher.Stream.features = None 
    518  
    519                 r = random.Random() 
    520                 r.seed() 
    521                 # with 50-bit random initial rid, session would have to go up 
    522                 # to 7881299347898368 messages to raise rid over 2**53  
    523                 # (see http://www.xmpp.org/extensions/xep-0124.html#rids) 
    524                 self.bosh_rid = r.getrandbits(50) 
    525  
    526                 initial_body_tag = BOSHBody( 
    527                         attrs={'content': 'text/xml; charset=utf-8', 
    528                                 'hold': str(self.bosh_hold), 
    529                                 # "to" should be domain, not hostname of machine 
    530                                 'to': self.Server, 
    531                                 'wait': str(self.bosh_wait), 
    532                                 'rid': str(self.bosh_rid), 
    533                                 'xmpp:version': '1.0', 
    534                                 'xmlns:xmpp': 'urn:xmpp:xbosh'} 
    535                         ) 
    536  
    537                 if locale.getdefaultlocale()[0]: 
    538                         initial_body_tag.setAttr('xml:lang', 
    539                                 locale.getdefaultlocale()[0].split('_')[0]) 
    540                 initial_body_tag.setAttr('xmpp:version', '1.0') 
    541                 initial_body_tag.setAttr('xmlns:xmpp', 'urn:xmpp:xbosh') 
    542                 self.send(initial_body_tag)