Author: asterix
Date: 2007-02-07 23:05:52 +0100 (Wed, 07 Feb 2007)
New Revision: 7954
Modified:
trunk/src/common/connection.py
trunk/src/common/xmpp/client_nb.py
trunk/src/common/xmpp/transports_nb.py
Log:
handle proxy errors. fixes #799 (socks5 proxies should now be supported. tests needed)
Modified: trunk/src/common/connection.py
===================================================================
--- trunk/src/common/connection.py 2007-02-07 21:16:27 UTC (rev 7953)
+++ trunk/src/common/connection.py 2007-02-07 22:05:52 UTC (rev 7954)
@@ -368,6 +368,15 @@
self._hosts = [i for i in result_array]
self.connect_to_next_host()
+ def on_proxy_failure(self, reason):
+ log.debug('Connection to proxy failed')
+ self.time_to_reconnect = None
+ self.on_connect_failure = None
+ self.disconnect(on_purpose = True)
+ self.dispatch('STATUS', 'offline')
+ self.dispatch('CONNECTION_LOST',
+ (_('Connection to proxy failed'), reason))
+
def connect_to_next_host(self, retry = False):
if len(self._hosts):
if self.last_connection:
@@ -377,10 +386,12 @@
if gajim.verbose:
con = common.xmpp.NonBlockingClient(self._hostname, caller = self,
on_connect = self.on_connect_success,
+ on_proxy_failure = self.on_proxy_failure,
on_connect_failure = self.connect_to_next_host)
else:
con = common.xmpp.NonBlockingClient(self._hostname, debug = [], caller = self,
on_connect = self.on_connect_success,
+ on_proxy_failure = self.on_proxy_failure,
on_connect_failure = self.connect_to_next_host)
self.last_connection = con
# increase default timeout for server responses
@@ -397,7 +408,6 @@
log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port'])
con.connect((host['host'], host['port']), proxy = self._proxy,
secure = self._secure)
- return
else:
if not retry and self.retrycount == 0:
log.debug("Out of hosts, giving up connecting to %s", self.name)
Modified: trunk/src/common/xmpp/client_nb.py
===================================================================
--- trunk/src/common/xmpp/client_nb.py 2007-02-07 21:16:27 UTC (rev 7953)
+++ trunk/src/common/xmpp/client_nb.py 2007-02-07 22:05:52 UTC (rev 7954)
@@ -32,7 +32,7 @@
class NBCommonClient(CommonClient):
''' Base for Client and Component classes.'''
def __init__(self, server, port=5222, debug=['always', 'nodebuilder'], caller=None,
- on_connect=None, on_connect_failure=None):
+ on_connect=None, on_proxy_failure=None, on_connect_failure=None):
''' Caches server name and (optionally) port to connect to. "debug" parameter specifies
the debug IDs that will go into debug output. You can either specifiy an "include"
or "exclude" list. The latter is done via adding "always" pseudo-ID to the list.
@@ -65,6 +65,7 @@
self.idlequeue = None
self.socket = None
self.on_connect = on_connect
+ self.on_proxy_failure = on_proxy_failure
self.on_connect_failure = on_connect_failure
def set_idlequeue(self, idlequeue):
@@ -108,14 +109,17 @@
if proxy.has_key('type'):
type_ = proxy['type']
if type_ == 'socks5':
- self.socket = transports_nb.NBSOCKS5PROXYsocket(self._on_connected,
+ self.socket = transports_nb.NBSOCKS5PROXYsocket(
+ self._on_connected, self._on_proxy_failure,
self._on_connected_failure, proxy, server)
elif type_ == 'http':
self.socket = transports_nb.NBHTTPPROXYsocket(self._on_connected,
- self._on_connected_failure, proxy, server)
+ self._on_proxy_failure, self._on_connected_failure, proxy,
+ server)
else:
self.socket = transports_nb.NBHTTPPROXYsocket(self._on_connected,
- self._on_connected_failure, proxy, server)
+ self._on_proxy_failure, self._on_connected_failure, proxy,
+ server)
else:
self.connected = 'tcp'
self.socket = transports_nb.NonBlockingTcp(self._on_connected,
@@ -127,6 +131,10 @@
self.on_stream_start = on_stream_start
self.onreceive(self._on_receive_document_attrs)
+ def _on_proxy_failure(self, reason):
+ if self.on_proxy_failure:
+ self.on_proxy_failure(reason)
+
def _on_connected_failure(self, retry = None):
if self.socket:
self.socket.disconnect()
Modified: trunk/src/common/xmpp/transports_nb.py
===================================================================
--- trunk/src/common/xmpp/transports_nb.py 2007-02-07 21:16:27 UTC (rev 7953)
+++ trunk/src/common/xmpp/transports_nb.py 2007-02-07 22:05:52 UTC (rev 7954)
@@ -374,7 +374,10 @@
self.state = -2
self.sendqueue = None
self.remove_timeout()
- self._owner.disconnected()
+ try:
+ self._owner.disconnected()
+ except:
+ pass
self.idlequeue.unplug_idle(self.fd)
sock = getattr(self, '_sock', None)
if sock:
@@ -609,7 +612,10 @@
def getName(self):
''' Return the server's name, or 'getHost()' if not available.'''
retval = None
- retval = gattr(self._owner, 'name')
+ try:
+ retval = gattr(self._owner, 'name')
+ except:
+ pass
if retval: return retval
return self.getHost()
@@ -834,12 +840,13 @@
(optionally) simple authentication (using login and password).
'''
- def __init__(self, on_connect =None, on_connect_failure = None,proxy = None,server = None,use_srv=True):
+ def __init__(self, on_connect =None, on_proxy_failure=None, on_connect_failure = None,proxy = None,server = None,use_srv=True):
''' Caches proxy and target addresses.
'proxy' argument is a dictionary with mandatory keys 'host' and 'port' (proxy address)
and optional keys 'user' and 'password' to use for authentication.
'server' argument is a tuple of host and port - just like TCPsocket uses. '''
self.on_connect_proxy = on_connect
+ self.on_proxy_failure = on_proxy_failure
self.on_connect_failure = on_connect_failure
NonBlockingTcp.__init__(self, self._on_tcp_connect, on_connect_failure, server, use_srv)
self.DBG_LINE=DBG_CONNECT_PROXY
@@ -881,10 +888,12 @@
except:
log.error("_on_headers_sent:", exc_info=True)
#traceback.print_exc()
- raise error('Invalid proxy reply')
+ self.on_proxy_failure('Invalid proxy reply')
+ return
if code <> '200':
self.DEBUG('Invalid proxy reply: %s %s %s' % (proto, code, desc),'error')
self._owner.disconnected()
+ self.on_proxy_failure('Invalid proxy reply')
return
if len(reply) != 2:
pass
@@ -893,9 +902,11 @@
def _on_proxy_auth(self, reply):
if self.reply.find('\n\n') == -1:
if reply is None:
- return
+ self.on_proxy_failure('Proxy authentification failed')
+ return
if reply.find('\n\n') == -1:
self.reply += reply.replace('\r', '')
+ self.on_proxy_failure('Proxy authentification failed')
return
self.DEBUG('Authentification successfull. Jabber server contacted.','ok')
if self.on_connect_proxy:
@@ -910,14 +921,15 @@
redefines only connect method. Allows to use SOCKS5 proxies with
(optionally) simple authentication (only USERNAME/PASSWORD auth).
'''
- def __init__(self, on_connect = None, on_connect_failure = None,
- proxy = None, server = None, use_srv = True):
+ def __init__(self, on_connect = None, on_proxy_failure = None,
+ on_connect_failure = None, proxy = None, server = None, use_srv = True):
''' Caches proxy and target addresses.
'proxy' argument is a dictionary with mandatory keys 'host' and 'port'
(proxy address) and optional keys 'user' and 'password' to use for
authentication. 'server' argument is a tuple of host and port -
just like TCPsocket uses. '''
self.on_connect_proxy = on_connect
+ self.on_proxy_failure = on_proxy_failure
self.on_connect_failure = on_connect_failure
NonBlockingTcp.__init__(self, self._on_tcp_connect, on_connect_failure,
server, use_srv)
@@ -952,23 +964,31 @@
if reply is None:
return
if len(reply) != 2:
- raise error('Invalid proxy reply')
+ self.on_proxy_failure('Invalid proxy reply')
+ return
if reply[0] != '\x05':
self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
+ self.on_proxy_failure('Invalid proxy reply')
return
if reply[1] == '\x00':
return self._on_proxy_auth('\x01\x00')
elif reply[1] == '\x02':
- # TODO: Do authentification
+ to_send = '\x01' + chr(len(self.proxy['user'])) + self.proxy['user'] +\
+ chr(len(self.proxy['password'])) + self.proxy['password']
self.onreceive(self._on_proxy_auth)
+ self.send(to_send)
else:
if reply[1] == '\xff':
self.DEBUG('Authentification to proxy impossible: no acceptable '
'auth method', 'error')
- else:
- self.DEBUG('Invalid proxy reply', 'error')
+ self._owner.disconnected()
+ self.on_proxy_failure('Authentification to proxy impossible: no '
+ 'acceptable authentification method')
+ return
+ self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
+ self.on_proxy_failure('Invalid proxy reply')
return
def _on_proxy_auth(self, reply):
@@ -977,14 +997,17 @@
if len(reply) != 2:
self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
- raise error('Invalid proxy reply')
+ self.on_proxy_failure('Invalid proxy reply')
+ return
if reply[0] != '\x01':
self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
- raise error('Invalid proxy reply')
+ self.on_proxy_failure('Invalid proxy reply')
+ return
if reply[1] != '\x00':
self.DEBUG('Authentification to proxy failed', 'error')
self._owner.disconnected()
+ self.on_proxy_failure('Authentification to proxy failed')
return
self.DEBUG('Authentification successfull. Jabber server contacted.','ok')
# Request connection
@@ -1014,11 +1037,13 @@
if len(reply) < 10:
self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
- raise error('Invalid proxy reply')
+ self.on_proxy_failure('Invalid proxy reply')
+ return
if reply[0] != '\x05':
self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
- raise error('Invalid proxy reply')
+ self.on_proxy_failure('Invalid proxy reply')
+ return
if reply[1] != "\x00":
# Connection failed
self._owner.disconnected()
@@ -1036,6 +1061,7 @@
else:
txt = 'Invalid proxy reply'
self.DEBUG(txt, 'error')
+ self.on_proxy_failure(txt)
return
# Get the bound address/port
elif reply[3] == "\x01":
@@ -1045,6 +1071,7 @@
else:
self.DEBUG('Invalid proxy reply', 'error')
self._owner.disconnected()
+ self.on_proxy_failure('Invalid proxy reply')
return
if self.on_connect_proxy: