A few more coding standards and readability improvements in client_nb.py.

This commit is contained in:
Stephan Erb 2009-01-08 16:30:27 +00:00
parent 10449444dd
commit cca10e6d29
2 changed files with 64 additions and 52 deletions

View File

@ -120,7 +120,7 @@ class NonBlockingClient:
if not stream_started: if not stream_started:
# if error occur before XML stream was opened, e.g. no response on # if error occur before XML stream was opened, e.g. no response on
# init request, we call the on_connect_failure callback because # init request, we call the on_connect_failure callback because
# proper connection is not estabilished yet and it's not a proxy # proper connection is not established yet and it's not a proxy
# issue # issue
log.debug('calling on_connect_failure cb') log.debug('calling on_connect_failure cb')
self.on_connect_failure() self.on_connect_failure()
@ -146,15 +146,15 @@ class NonBlockingClient:
values for keys 'host' and 'port' - connection details for proxy serve values for keys 'host' and 'port' - connection details for proxy serve
and optionally keys 'user' and 'pass' as proxy credentials and optionally keys 'user' and 'pass' as proxy credentials
:param secure_tuple: tuple of (desired connection type, cacerts, mycerts) :param secure_tuple: tuple of (desired connection type, cacerts, mycerts)
connection type can be 'ssl' - TLS estabilished after TCP connection, connection type can be 'ssl' - TLS established after TCP connection,
'tls' - TLS estabilished after negotiation with starttls, or 'plain'. 'tls' - TLS established after negotiation with starttls, or 'plain'.
cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more
details details
''' '''
self.on_connect = on_connect self.on_connect = on_connect
self.on_connect_failure=on_connect_failure self.on_connect_failure=on_connect_failure
self.on_proxy_failure = on_proxy_failure self.on_proxy_failure = on_proxy_failure
self.secure, self.cacerts, self.mycerts = secure_tuple self.desired_security, self.cacerts, self.mycerts = secure_tuple
self.Connection = None self.Connection = None
self.Port = port self.Port = port
self.proxy = proxy self.proxy = proxy
@ -164,7 +164,11 @@ class NonBlockingClient:
else: else:
self.xmpp_hostname = self.Server self.xmpp_hostname = self.Server
estabilish_tls = self.secure == 'ssl' # We only check for SSL here as for TLS we will first have to start a
# PLAIN connection and negotiate TLS afterwards.
# establish_tls will instruct transport to start secure connection
# directly
establish_tls = self.desired_security == 'ssl'
certs = (self.cacerts, self.mycerts) certs = (self.cacerts, self.mycerts)
proxy_dict = {} proxy_dict = {}
@ -182,15 +186,15 @@ class NonBlockingClient:
if proxy['type'] == 'bosh': if proxy['type'] == 'bosh':
# Setup BOSH transport # Setup BOSH transport
self.socket = bosh.NonBlockingBOSH( self.socket = bosh.NonBlockingBOSH(
on_disconnect = self.disconnect, on_disconnect=self.disconnect,
raise_event = self.raise_event, raise_event=self.raise_event,
idlequeue = self.idlequeue, idlequeue=self.idlequeue,
estabilish_tls = estabilish_tls, estabilish_tls=establish_tls,
certs = certs, certs=certs,
proxy_creds = (proxy_user, proxy_pass), proxy_creds=(proxy_user, proxy_pass),
xmpp_server = (self.xmpp_hostname, self.Port), xmpp_server=(self.xmpp_hostname, self.Port),
domain = self.Server, domain=self.Server,
bosh_dict = proxy) bosh_dict=proxy)
self.protocol_type = 'BOSH' self.protocol_type = 'BOSH'
self.wait_for_restart_response = \ self.wait_for_restart_response = \
proxy['bosh_wait_for_restart_response'] proxy['bosh_wait_for_restart_response']
@ -203,12 +207,12 @@ class NonBlockingClient:
if not proxy or proxy['type'] != 'bosh': if not proxy or proxy['type'] != 'bosh':
# Setup ordinary TCP transport # Setup ordinary TCP transport
self.socket = transports_nb.NonBlockingTCP( self.socket = transports_nb.NonBlockingTCP(
on_disconnect = self.disconnect, on_disconnect=self.disconnect,
raise_event = self.raise_event, raise_event=self.raise_event,
idlequeue = self.idlequeue, idlequeue=self.idlequeue,
estabilish_tls = estabilish_tls, estabilish_tls=establish_tls,
certs = certs, certs=certs,
proxy_dict = proxy_dict) proxy_dict=proxy_dict)
# plug transport into client as self.Connection # plug transport into client as self.Connection
self.socket.PlugIn(self) self.socket.PlugIn(self)
@ -221,8 +225,8 @@ class NonBlockingClient:
def _resolve_hostname(self, hostname, port, on_success): def _resolve_hostname(self, hostname, port, on_success):
''' wrapper for getaddinfo call. FIXME: getaddinfo blocks''' ''' wrapper for getaddinfo call. FIXME: getaddinfo blocks'''
try: try:
self.ip_addresses = socket.getaddrinfo(hostname,port, self.ip_addresses = socket.getaddrinfo(hostname, port,
socket.AF_UNSPEC,socket.SOCK_STREAM) socket.AF_UNSPEC, socket.SOCK_STREAM)
except socket.gaierror, (errnum, errstr): except socket.gaierror, (errnum, errstr):
self.disconnect(message='Lookup failure for %s:%s, hostname: %s - %s' % self.disconnect(message='Lookup failure for %s:%s, hostname: %s - %s' %
(self.Server, self.Port, hostname, errstr)) (self.Server, self.Port, hostname, errstr))
@ -241,7 +245,7 @@ class NonBlockingClient:
self.current_ip = self.ip_addresses.pop(0) self.current_ip = self.ip_addresses.pop(0)
self.socket.connect( self.socket.connect(
conn_5tuple=self.current_ip, conn_5tuple=self.current_ip,
on_connect=lambda: self._xmpp_connect(socket_type='plain'), on_connect=lambda: self._xmpp_connect(),
on_connect_failure=self._try_next_ip) on_connect_failure=self._try_next_ip)
def incoming_stream_version(self): def incoming_stream_version(self):
@ -251,14 +255,20 @@ class NonBlockingClient:
else: else:
return None return None
def _xmpp_connect(self, socket_type): def _xmpp_connect(self, socket_type=None):
''' '''
Starts XMPP connecting process - opens the XML stream. Is called after TCP Starts XMPP connecting process - opens the XML stream. Is called after TCP
connection is estabilished or after switch to TLS when successfully connection is established or after switch to TLS when successfully
negotiated with <starttls>. negotiated with <starttls>.
''' '''
if socket_type == 'plain' and self.Connection.ssl_lib: # socket_type contains info which transport connection was established
socket_type = 'ssl' if not socket_type:
if self.Connection.ssl_lib:
# When ssl_lib is set we connected via SSL
socket_type = 'ssl'
else:
# PLAIN is default
socket_type = 'plain'
self.connected = socket_type self.connected = socket_type
self._xmpp_connect_machine() self._xmpp_connect_machine()
@ -287,7 +297,7 @@ class NonBlockingClient:
if self.__dict__.has_key('Dispatcher'): if self.__dict__.has_key('Dispatcher'):
self.Dispatcher.PlugOut() self.Dispatcher.PlugOut()
self.got_features = False self.got_features = False
d = dispatcher_nb.Dispatcher().PlugIn(self) dispatcher_nb.Dispatcher().PlugIn(self)
on_next_receive('RECEIVE_DOCUMENT_ATTRIBUTES') on_next_receive('RECEIVE_DOCUMENT_ATTRIBUTES')
elif mode == 'FAILURE': elif mode == 'FAILURE':
@ -307,7 +317,6 @@ class NonBlockingClient:
else: else:
log.info('got STREAM FEATURES in first recv') log.info('got STREAM FEATURES in first recv')
self._xmpp_connect_machine(mode='STREAM_STARTED') self._xmpp_connect_machine(mode='STREAM_STARTED')
else: else:
log.info('incoming stream version less than 1.0') log.info('incoming stream version less than 1.0')
self._xmpp_connect_machine(mode='STREAM_STARTED') self._xmpp_connect_machine(mode='STREAM_STARTED')
@ -330,32 +339,35 @@ class NonBlockingClient:
def _on_stream_start(self): def _on_stream_start(self):
''' '''
Called after XMPP stream is opened. Called after XMPP stream is opened. TLS negotiation may follow if
TLS negotiation may follow when stream is established. supported and desired.
''' '''
self.stream_started = True self.stream_started = True
self.onreceive(None) self.onreceive(None)
if self.connected == 'plain': if self.connected == 'plain':
if self.secure == 'plain': if self.desired_security == 'plain':
# if we want plain connection, we're done now # if we want and have plain connection, we're done now
self._on_connect() self._on_connect()
return else:
if self.incoming_stream_version() != '1.0': # try to negotiate TLS
# if stream version is less than 1.0, we can't do more if self.incoming_stream_version() != '1.0':
log.warn('While connecting with type = "tls": stream version is less than 1.0') # if stream version is less than 1.0, we can't do more
self._on_connect() log.warn('While connecting with type = "tls": stream version is less than 1.0')
return self._on_connect()
if not self.Dispatcher.Stream.features.getTag('starttls'): return
# if server doesn't advertise TLS in init response, we can't do more if self.Dispatcher.Stream.features.getTag('starttls'):
log.warn('While connecting with type = "tls": TLS unsupported by remote server') # Server advertises TLS support, start negotiation
self._on_connect() self.stream_started = False
return log.info('TLS supported by remote server. Requesting TLS start.')
# otherwise start TLS negotioation self._tls_negotiation_handler()
self.stream_started = False else:
log.info("TLS supported by remote server. Requesting TLS start.") log.warn('While connecting with type = "tls": TLS unsupported by remote server')
self._tls_negotiation_handler() self._on_connect()
elif self.connected in ['ssl', 'tls']: elif self.connected in ['ssl', 'tls']:
self._on_connect() self._on_connect()
assert False # should never be reached
def _tls_negotiation_handler(self, con=None, tag=None): def _tls_negotiation_handler(self, con=None, tag=None):
''' takes care of TLS negotioation with <starttls> ''' ''' takes care of TLS negotioation with <starttls> '''
@ -374,7 +386,7 @@ class NonBlockingClient:
return return
tagname = tag.getName() tagname = tag.getName()
if tagname == 'failure': if tagname == 'failure':
self.disconnect('TLS <failure> received: %s' % tag) self.disconnect('TLS <failure> received: %s' % tag)
return return
log.info('Got starttls proceed response. Switching to TLS/SSL...') log.info('Got starttls proceed response. Switching to TLS/SSL...')
# following call wouldn't work for BOSH transport but it doesn't matter # following call wouldn't work for BOSH transport but it doesn't matter
@ -464,7 +476,7 @@ class NonBlockingClient:
# wrong user/pass, stop auth # wrong user/pass, stop auth
if 'SASL' in self.__dict__: if 'SASL' in self.__dict__:
self.SASL.PlugOut() self.SASL.PlugOut()
self.connected = None self.connected = None # FIXME: is this intended?
self._on_sasl_auth(None) self._on_sasl_auth(None)
elif self.SASL.startsasl == 'success': elif self.SASL.startsasl == 'success':
auth_nb.NonBlockingBind().PlugIn(self) auth_nb.NonBlockingBind().PlugIn(self)

View File

@ -198,6 +198,7 @@ class NonBlockingTransport(PlugIn):
if hasattr(self._owner, 'Dispatcher'): if hasattr(self._owner, 'Dispatcher'):
self.on_receive = self._owner.Dispatcher.ProcessNonBlocking self.on_receive = self._owner.Dispatcher.ProcessNonBlocking
else: else:
log.warning('No Dispatcher plugged. Received data will not be processed')
self.on_receive = None self.on_receive = None
return return
self.on_receive = recv_handler self.on_receive = recv_handler
@ -344,7 +345,6 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
else: else:
NonBlockingTransport._on_connect(self) NonBlockingTransport._on_connect(self)
def tls_init(self, on_succ, on_fail): def tls_init(self, on_succ, on_fail):
''' '''
Estabilishes TLS/SSL using this TCP connection by plugging a Estabilishes TLS/SSL using this TCP connection by plugging a