proxy.py.bak
1 """ 2 Set proxy if avaiable otherwise exception 3 """ 4 # pylint: disable=protected-access 5 import logging 6 import socket 7 import time 8 9 import asyncore_pollchoose as asyncore 10 from advanceddispatcher import AdvancedDispatcher 11 from bmconfigparser import config 12 from node import Peer 13 14 logger = logging.getLogger('default') 15 16 17 class ProxyError(Exception): 18 """Base proxy exception class""" 19 errorCodes = ("Unknown error",) 20 21 def __init__(self, code=-1): 22 self.code = code 23 try: 24 self.message = self.errorCodes[code] 25 except IndexError: 26 self.message = self.errorCodes[-1] 27 super(ProxyError, self).__init__(self.message) 28 29 30 class GeneralProxyError(ProxyError): 31 """General proxy error class (not specfic to an implementation)""" 32 errorCodes = ( 33 "Success", 34 "Invalid data", 35 "Not connected", 36 "Not available", 37 "Bad proxy type", 38 "Bad input", 39 "Timed out", 40 "Network unreachable", 41 "Connection refused", 42 "Host unreachable" 43 ) 44 45 46 class Proxy(AdvancedDispatcher): 47 """Base proxy class""" 48 # these are global, and if you change config during runtime, 49 # all active/new instances should change too 50 _proxy = ("127.0.0.1", 9050) 51 _auth = None 52 _onion_proxy = None 53 _onion_auth = None 54 _remote_dns = True 55 56 @property 57 def proxy(self): 58 """Return proxy IP and port""" 59 return self.__class__._proxy 60 61 @proxy.setter 62 def proxy(self, address): 63 """Set proxy IP and port""" 64 if (not isinstance(address, tuple) or len(address) < 2 65 or not isinstance(address[0], str) 66 or not isinstance(address[1], int)): 67 raise ValueError 68 self.__class__._proxy = address 69 70 @property 71 def auth(self): 72 """Return proxy authentication settings""" 73 return self.__class__._auth 74 75 @auth.setter 76 def auth(self, authTuple): 77 """Set proxy authentication (username and password)""" 78 self.__class__._auth = authTuple 79 80 @property 81 def onion_proxy(self): 82 """ 83 Return separate proxy IP and port for use only with onion 84 addresses. Untested. 85 """ 86 return self.__class__._onion_proxy 87 88 @onion_proxy.setter 89 def onion_proxy(self, address): 90 """Set onion proxy address""" 91 if address is not None and ( 92 not isinstance(address, tuple) or len(address) < 2 93 or not isinstance(address[0], str) 94 or not isinstance(address[1], int) 95 ): 96 raise ValueError 97 self.__class__._onion_proxy = address 98 99 @property 100 def onion_auth(self): 101 """Return proxy authentication settings for onion hosts only""" 102 return self.__class__._onion_auth 103 104 @onion_auth.setter 105 def onion_auth(self, authTuple): 106 """Set proxy authentication for onion hosts only. Untested.""" 107 self.__class__._onion_auth = authTuple 108 109 def __init__(self, address): 110 if not isinstance(address, Peer): 111 raise ValueError 112 AdvancedDispatcher.__init__(self) 113 self.destination = address 114 self.isOutbound = True 115 self.fullyEstablished = False 116 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 117 if config.safeGetBoolean( 118 "bitmessagesettings", "socksauthentication"): 119 self.auth = ( 120 config.safeGet( 121 "bitmessagesettings", "socksusername"), 122 config.safeGet( 123 "bitmessagesettings", "sockspassword")) 124 else: 125 self.auth = None 126 self.connect( 127 self.onion_proxy 128 if address.host.endswith(".onion") and self.onion_proxy else 129 self.proxy 130 ) 131 132 def handle_connect(self): 133 """Handle connection event (to the proxy)""" 134 self.set_state("init") 135 try: 136 AdvancedDispatcher.handle_connect(self) 137 except socket.error as e: 138 if e.errno in asyncore._DISCONNECTED: 139 logger.debug( 140 "%s:%i: Connection failed: %s", 141 self.destination.host, self.destination.port, e) 142 return 143 self.state_init() 144 145 def state_proxy_handshake_done(self): 146 """Handshake is complete at this point""" 147 self.connectedAt = time.time() 148 return False