async def detect_proxy(self, host='www.google.com', port=80, log_failure=True): '''Attempt to detect a proxy by establishing a connection through it to the given target host / port pair. ''' if self.is_up(): return sock = None for proxy_port in self.try_ports: if proxy_port is None: continue paddress = (self.host, proxy_port) try: sock = await self.connect_via_proxy(host, port, paddress) break except Exception as e: if log_failure: self.logger.info('failed to detect proxy at {}: {}' .format(util.address_string(paddress), e)) self.tried_event.set() # Failed all ports? if sock is None: return peername = sock.getpeername() sock.close() self.ip_addr = peername[0] self.port = proxy_port self.errors = 0 self.logger.info('detected proxy at {} ({})' .format(util.address_string(paddress), self.ip_addr))
async def handshake(self): '''Write the proxy handshake sequence.''' if self.ip_address and self.ip_address.version == 6: await self._socks5_handshake() else: await self._socks4_handshake() if self.debug: address = (self.host, self.port) self.log_info('successful connection via proxy to {}' .format(util.address_string(address)))
async def create_connection(self, protocol_factory, host, port, ssl=None): '''All arguments are as to asyncio's create_connection method.''' if self.port is None: proxy_ports = [9050, 9150, 1080] else: proxy_ports = [self.port] for proxy_port in proxy_ports: address = (self.host, proxy_port) sock = socket.socket() sock.setblocking(False) try: await self.loop.sock_connect(sock, address) except OSError as e: if proxy_port == proxy_ports[-1]: raise continue socks = Socks(self.loop, sock, host, port) try: await socks.handshake() if self.port is None: self.ip_addr = sock.getpeername()[0] self.port = proxy_port self.logger.info('detected proxy at {} ({})'.format( util.address_string(address), self.ip_addr)) break except Exception as e: sock.close() raise hostname = host if ssl else None return await self.loop.create_connection(protocol_factory, ssl=ssl, sock=sock, server_hostname=hostname)
def test_address_string(): assert util.address_string(('foo.bar', 84)) == 'foo.bar:84' assert util.address_string(('1.2.3.4', 84)) == '1.2.3.4:84' assert util.address_string(('0a::23', 84)) == '[a::23]:84'