def _lookup_port(self, port, socktype): if isinstance(port, string_types): try: port = int(port) except ValueError: try: if socktype == 0: try: port = getservbyname(port, 'tcp') socktype = SOCK_STREAM except error: port = getservbyname(port, 'udp') socktype = SOCK_DGRAM elif socktype == SOCK_STREAM: port = getservbyname(port, 'tcp') elif socktype == SOCK_DGRAM: port = getservbyname(port, 'udp') else: raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype') except error: ex = sys.exc_info()[1] if 'not found' in str(ex): raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype') else: raise gaierror(str(ex)) except UnicodeEncodeError: raise error('Int or String expected') elif port is None: port = 0 elif isinstance(port, int): pass else: raise error('Int or String expected') port = int(port % 65536) return port, socktype
def _lookup_port(self, port, socktype): socktypes = [] if isinstance(port, string_types): try: port = int(port) except ValueError: try: if socktype == 0: origport = port try: port = getservbyname(port, 'tcp') socktypes.append(SOCK_STREAM) except error: port = getservbyname(port, 'udp') socktypes.append(SOCK_DGRAM) else: try: if port == getservbyname(origport, 'udp'): socktypes.append(SOCK_DGRAM) except error: pass elif socktype == SOCK_STREAM: port = getservbyname(port, 'tcp') elif socktype == SOCK_DGRAM: port = getservbyname(port, 'udp') else: raise gaierror( EAI_SERVICE, 'Servname not supported for ai_socktype') except error: ex = sys.exc_info()[1] if 'not found' in str(ex): raise gaierror( EAI_SERVICE, 'Servname not supported for ai_socktype') else: raise gaierror(str(ex)) except UnicodeEncodeError: raise error('Int or String expected') elif port is None: port = 0 elif isinstance(port, int): pass else: raise error('Int or String expected') port = int(port % 65536) if not socktypes and socktype: socktypes.append(socktype) return port, socktypes
def gethostbyname_ex(self, hostname, family=AF_INET): if PY3: if isinstance(hostname, str): hostname = hostname.encode("idna") elif not isinstance(hostname, (bytes, bytearray)): raise TypeError("Expected es(idna), not %s" % type(hostname).__name__) else: if isinstance(hostname, text_type): hostname = hostname.encode("ascii") elif not isinstance(hostname, str): raise TypeError("Expected string, not %s" % type(hostname).__name__) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, "No address associated with hostname") return result except gaierror: if ares is self.ares: if hostname == b"255.255.255.255": # The stdlib handles this case in 2.7 and 3.x, but ares does not. # It is tested by test_socket.py in 3.4. # HACK: So hardcode the expected return. return ("255.255.255.255", [], ["255.255.255.255"]) raise
def __getnameinfo(self, hostname, port, sockaddr, flags): result = self.__getaddrinfo(hostname, port, family=AF_UNSPEC, socktype=SOCK_DGRAM, proto=0, flags=0, fill_in_type_proto=False) if len(result) != 1: raise error('sockaddr resolved to multiple addresses') family, _socktype, _proto, _name, address = result[0] if family == AF_INET: if len(sockaddr) != 2: raise error("IPv4 sockaddr must be 2 tuple") elif family == AF_INET6: address = address[:2] + sockaddr[2:] waiter = Waiter(self.hub) self.cares.getnameinfo(waiter, address, flags) node, service = waiter.get() if service is None and PY3: # ares docs: "If the query did not complete # successfully, or one of the values was not # requested, node or service will be NULL ". Python 2 # allows that for the service, but Python 3 raises # an error. This is tested by test_socket in py 3.4 err = gaierror(EAI_NONAME, self.EAI_NONAME_MSG) err.errno = EAI_NONAME raise err return node, service or '0'
def gethostbyname_ex(self, hostname, family=AF_INET): if PY3: if isinstance(hostname, str): hostname = hostname.encode('idna') elif not isinstance(hostname, (bytes, bytearray)): raise TypeError('Expected es(idna), not %s' % type(hostname).__name__) else: if isinstance(hostname, text_type): hostname = hostname.encode('ascii') elif not isinstance(hostname, str): raise TypeError('Expected string, not %s' % type(hostname).__name__) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, 'No address associated with hostname') return result except gaierror: if ares is self.ares: if hostname == b'255.255.255.255': # The stdlib handles this case in 2.7 and 3.x, but ares does not. # It is tested by test_socket.py in 3.4. # HACK: So hardcode the expected return. return ('255.255.255.255', [], ['255.255.255.255']) raise
def gethostbyname_ex(self, hostname, family=AF_INET): if PY3: if isinstance(hostname, str): hostname = hostname.encode('idna') elif not isinstance(hostname, (bytes, bytearray)): raise TypeError('Expected es(idna), not %s' % type(hostname).__name__) else: if isinstance(hostname, text_type): hostname = hostname.encode('ascii') elif not isinstance(hostname, str): raise TypeError('Expected string, not %s' % type(hostname).__name__) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, 'No address associated with hostname') return result except gaierror: if ares is self.ares: raise
def _lookup_port(port, socktype): # pylint:disable=too-many-branches socktypes = [] if isinstance(port, string_types): try: port = int(port) except ValueError: try: if socktype == 0: origport = port try: port = native_getservbyname(port, 'tcp') socktypes.append(SOCK_STREAM) except error: port = native_getservbyname(port, 'udp') socktypes.append(SOCK_DGRAM) else: try: if port == native_getservbyname(origport, 'udp'): socktypes.append(SOCK_DGRAM) except error: pass elif socktype == SOCK_STREAM: port = native_getservbyname(port, 'tcp') elif socktype == SOCK_DGRAM: port = native_getservbyname(port, 'udp') else: raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype') except error as ex: if 'not found' in str(ex): raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype') raise gaierror(str(ex)) except UnicodeEncodeError: raise error('Int or String expected', port) elif port is None: port = 0 elif isinstance(port, integer_types): pass else: raise error('Int or String expected', port, type(port)) port = int(port % 65536) if not socktypes and socktype: socktypes.append(socktype) return port, socktypes
def _lookup_port(self, port, socktype): # pylint:disable=too-many-branches socktypes = [] if isinstance(port, string_types): try: port = int(port) except ValueError: try: if socktype == 0: origport = port try: port = getservbyname(port, "tcp") socktypes.append(SOCK_STREAM) except error: port = getservbyname(port, "udp") socktypes.append(SOCK_DGRAM) else: try: if port == getservbyname(origport, "udp"): socktypes.append(SOCK_DGRAM) except error: pass elif socktype == SOCK_STREAM: port = getservbyname(port, "tcp") elif socktype == SOCK_DGRAM: port = getservbyname(port, "udp") else: raise gaierror(EAI_SERVICE, "Servname not supported for ai_socktype") except error as ex: if "not found" in str(ex): raise gaierror(EAI_SERVICE, "Servname not supported for ai_socktype") else: raise gaierror(str(ex)) except UnicodeEncodeError: raise error("Int or String expected") elif port is None: port = 0 elif isinstance(port, integer_types): pass else: raise error("Int or String expected", port, type(port)) port = int(port % 65536) if not socktypes and socktype: socktypes.append(socktype) return port, socktypes
def _lookup_port(self, port, socktype): socktypes = [] if isinstance(port, string_types): try: port = int(port) except ValueError: try: if socktype == 0: origport = port try: port = getservbyname(port, 'tcp') socktypes.append(SOCK_STREAM) except error: port = getservbyname(port, 'udp') socktypes.append(SOCK_DGRAM) else: try: if port == getservbyname(origport, 'udp'): socktypes.append(SOCK_DGRAM) except error: pass elif socktype == SOCK_STREAM: port = getservbyname(port, 'tcp') elif socktype == SOCK_DGRAM: port = getservbyname(port, 'udp') else: raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype') except error as ex: if 'not found' in str(ex): raise gaierror(EAI_SERVICE, 'Servname not supported for ai_socktype') else: raise gaierror(str(ex)) except UnicodeEncodeError: raise error('Int or String expected') elif port is None: port = 0 elif isinstance(port, int): pass else: raise error('Int or String expected') port = int(port % 65536) if not socktypes and socktype: socktypes.append(socktype) return port, socktypes
def gethostbyname_ex(self, hostname, family=AF_INET): while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, 'No address associated with hostname') return result except gaierror: if ares is self.ares: raise
def _getnameinfo(self, sockaddr, flags): if not isinstance(flags, int): raise TypeError('an integer is required') if not isinstance(sockaddr, tuple): raise TypeError('getnameinfo() argument 1 must be a tuple') address = sockaddr[0] if not PY3 and isinstance(address, text_type): address = address.encode('ascii') if not isinstance(address, string_types): raise TypeError('sockaddr[0] must be a string, not %s' % type(address).__name__) port = sockaddr[1] if not isinstance(port, int): raise TypeError('port must be an integer, not %s' % type(port)) waiter = Waiter(self.hub) result = self._getaddrinfo(address, str(sockaddr[1]), family=AF_UNSPEC, socktype=SOCK_DGRAM) if not result: reraise(*sys.exc_info()) elif len(result) != 1: raise error('sockaddr resolved to multiple addresses') family, _socktype, _proto, _name, address = result[0] if family == AF_INET: if len(sockaddr) != 2: raise error("IPv4 sockaddr must be 2 tuple") elif family == AF_INET6: address = address[:2] + sockaddr[2:] self.ares.getnameinfo(waiter, address, flags) node, service = waiter.get() if service is None: if PY3: # ares docs: "If the query did not complete # successfully, or one of the values was not # requested, node or service will be NULL ". Python 2 # allows that for the service, but Python 3 raises # an error. This is tested by test_socket in py 3.4 err = gaierror('nodename nor servname provided, or not known') err.errno = 8 raise err service = '0' return node, service
def test_unknown_host(self): """ Tests the case where the client is configured with a host that cannot be resolved. """ # Test e = gaierror() code = self.exception_handler.handle_unknown_host(e) # Verify self.assertEqual(code, handler.CODE_UNKNOWN_HOST) self.assertTrue(self.config['server']['host'] in self.recorder.lines[0]) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0])
def _getnameinfo(self, sockaddr, flags): if not isinstance(flags, int): raise TypeError("an integer is required") if not isinstance(sockaddr, tuple): raise TypeError("getnameinfo() argument 1 must be a tuple") address = sockaddr[0] if not PY3 and isinstance(address, text_type): address = address.encode("ascii") if not isinstance(address, string_types): raise TypeError("sockaddr[0] must be a string, not %s" % type(address).__name__) port = sockaddr[1] if not isinstance(port, int): raise TypeError("port must be an integer, not %s" % type(port)) waiter = Waiter(self.hub) result = self._getaddrinfo(address, str(sockaddr[1]), family=AF_UNSPEC, socktype=SOCK_DGRAM) if not result: reraise(*sys.exc_info()) elif len(result) != 1: raise error("sockaddr resolved to multiple addresses") family, _socktype, _proto, _name, address = result[0] if family == AF_INET: if len(sockaddr) != 2: raise error("IPv4 sockaddr must be 2 tuple") elif family == AF_INET6: address = address[:2] + sockaddr[2:] self.ares.getnameinfo(waiter, address, flags) node, service = waiter.get() if service is None: if PY3: # ares docs: "If the query did not complete # successfully, or one of the values was not # requested, node or service will be NULL ". Python 2 # allows that for the service, but Python 3 raises # an error. This is tested by test_socket in py 3.4 err = gaierror("nodename nor servname provided, or not known") err.errno = 8 raise err service = "0" return node, service
def gethostbyname_ex(self, hostname, family=AF_INET): if isinstance(hostname, text_type): hostname = hostname.encode('ascii') elif not isinstance(hostname, str): raise TypeError('Expected string, not %s' % type(hostname).__name__) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, 'No address associated with hostname') return result except gaierror: if ares is self.ares: raise
def _gethostbyname_ex(self, hostname_bytes, family): while True: ares = self.cares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname_bytes, family) result = waiter.get() if not result[-1]: raise herror(EAI_NONAME, self.EAI_NONAME_MSG) return result except herror as ex: if ares is self.cares: if ex.args[0] == 1: # Somewhere along the line, the internal # implementation of gethostbyname_ex changed to invoke # getaddrinfo() as a first pass, much like we do for ``getnameinfo()``; # this means it raises a different error for not-found hosts. raise gaierror(EAI_NONAME, self.EAI_NONAME_MSG) raise
def gethostbyname_ex(self, hostname, family=AF_INET): if isinstance(hostname, unicode): hostname = hostname.encode('ascii') elif not isinstance(hostname, str): raise TypeError('Expected string, not %s' % type(hostname).__name__) if family==AF_INET and self.pool is not None and '.' not in hostname: return self.pool.apply_e(BaseException, gethostbyname_ex, (hostname, )) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, 'No address associated with hostname') return result except gaierror: if ares is self.ares: raise
def gethostbyname_ex(self, hostname, family=AF_INET): if isinstance(hostname, unicode): hostname = hostname.encode('ascii') elif not isinstance(hostname, str): raise TypeError('Expected string, not %s' % type(hostname).__name__) if family == AF_INET and self.pool is not None and '.' not in hostname: return self.pool.apply_e(BaseException, gethostbyname_ex, (hostname, )) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, 'No address associated with hostname') return result except gaierror: if ares is self.ares: raise
def gethostbyname_ex(self, hostname, family=AF_INET): if PY3: if isinstance(hostname, str): hostname = hostname.encode("idna") elif not isinstance(hostname, (bytes, bytearray)): raise TypeError("Expected es(idna), not %s" % type(hostname).__name__) else: if isinstance(hostname, text_type): hostname = hostname.encode("ascii") elif not isinstance(hostname, str): raise TypeError("Expected string, not %s" % type(hostname).__name__) while True: ares = self.ares try: waiter = Waiter(self.hub) ares.gethostbyname(waiter, hostname, family) result = waiter.get() if not result[-1]: raise gaierror(-5, "No address associated with hostname") return result except gaierror: if ares is self.ares: raise
def test_handle_exception(self): """ Tests the high level call that branches based on exception type for all types. """ # For each exception type, check that the proper code is returned and # that a failure message has been output. For simplicity in those tests, # reset the tags after each run. code = self.exception_handler.handle_exception( exceptions.BadRequestException({})) self.assertEqual(code, handler.CODE_BAD_REQUEST) self.assertEqual(3, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ConflictException({})) self.assertEqual(code, handler.CODE_CONFLICT) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ConnectionException({})) self.assertEqual(code, handler.CODE_CONNECTION_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.NotFoundException({'resources': { 'repo_id': 'foo' }})) self.assertEqual(code, handler.CODE_NOT_FOUND) self.assertEqual(2, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.PermissionsException({})) self.assertEqual(code, handler.CODE_PERMISSIONS_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.PulpServerException({})) self.assertEqual(code, handler.CODE_PULP_SERVER_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( InvalidConfig('Test Message')) self.assertEqual(code, handler.CODE_INVALID_CONFIG) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( WrongHost('expected', 'actual')) self.assertEqual(code, handler.CODE_WRONG_HOST) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ApacheServerException('Test Message')) self.assertEqual(code, handler.CODE_APACHE_SERVER_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(gaierror()) self.assertEqual(code, handler.CODE_UNKNOWN_HOST) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(socket_error()) self.assertEqual(code, handler.CODE_SOCKET_ERROR) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception( exceptions.ClientCertificateExpiredException(CERT_FILENAME)) self.assertEqual(code, handler.CODE_PERMISSIONS_EXCEPTION) self.assertEqual([TAG_FAILURE, TAG_PARAGRAPH], self.prompt.get_write_tags()) self.prompt.tags = [] code = self.exception_handler.handle_exception(Exception({})) self.assertEqual(code, handler.CODE_UNEXPECTED) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = []
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): if isinstance(host, unicode): host = host.encode('idna') elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set if self.pool is not None: return self.pool.apply_e(BaseException, getaddrinfo, (host, port, family, socktype, proto, flags)) else: return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* if self.pool is not None and '.' not in host: # localhost, <broadcast> return self.pool.apply_e(BaseException, getaddrinfo, (host, port, family, socktype, proto, flags)) origport = port port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: values = Values(self.hub, 2) ares.gethostbyname(values, host, AF_INET) ares.gethostbyname(values, host, AF_INET6) elif family == AF_INET: values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET) elif family == AF_INET6: values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET6) else: if self.pool is not None: return self.pool.apply_e(BaseException, getaddrinfo, (host, origport, family, socktype, proto, flags)) else: return getaddrinfo(host, origport, family, socktype, proto, flags) values = values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype, proto in socktype_proto: result4.append((AF_INET, socktype, proto, '', sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == '::1': dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype, proto in socktype_proto: dest.append((AF_INET6, socktype, proto, '', sockaddr)) result += result4 + result6 if not result: raise gaierror(-5, 'No address associated with hostname') return result
def __getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0, fill_in_type_proto=True): """ Returns a list ``(family, socktype, proto, canonname, sockaddr)`` :raises gaierror: If no results are found. """ # pylint:disable=too-many-locals,too-many-branches if isinstance(host, text_type): host = host.encode('idna') if isinstance(port, text_type): port = port.encode('ascii') elif isinstance(port, integer_types): if port == 0: port = None else: port = str(port).encode('ascii') waiter = Waiter(self.hub) self.cares.getaddrinfo( waiter, host, port, family, socktype, proto, flags, ) # Result is a list of: # (family, socktype, proto, canonname, sockaddr) # Where sockaddr depends on family; for INET it is # (address, port) # and INET6 is # (address, port, flow info, scope id) result = waiter.get() if not result: raise gaierror(EAI_NONAME, self.EAI_NONAME_MSG) if fill_in_type_proto: # c-ares 1.16 DOES NOT fill in socktype or proto in the results, # ever. It's at least supposed to do that if they were given as # hints, but it doesn't (https://github.com/c-ares/c-ares/issues/317) # Sigh. # The SOL_* constants are another (older?) name for IPPROTO_* if socktype: hard_type_proto = [ (socktype, SOL_TCP if socktype == SOCK_STREAM else SOL_UDP), ] elif proto: hard_type_proto = [ (SOCK_STREAM if proto == SOL_TCP else SOCK_DGRAM, proto), ] else: hard_type_proto = [ (SOCK_STREAM, SOL_TCP), (SOCK_DGRAM, SOL_UDP), ] # pylint:disable=not-an-iterable,unsubscriptable-object result = [(rfamily, hard_type if not rtype else rtype, hard_proto if not rproto else rproto, rcanon, raddr) for rfamily, rtype, rproto, rcanon, raddr in result for hard_type, hard_proto in hard_type_proto] return result
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): # pylint:disable=too-many-locals,too-many-branches if isinstance(host, text_type): host = host.encode("idna") elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: ares_values = Values(self.hub, 2) ares.gethostbyname(ares_values, host, AF_INET) ares.gethostbyname(ares_values, host, AF_INET6) elif family == AF_INET: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET) elif family == AF_INET6: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET6) else: raise gaierror(5, "ai_family not supported: %r" % (family,)) values = ares_values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype, proto in socktype_proto: result4.append((AF_INET, socktype, proto, "", sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == "::1": dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype, proto in socktype_proto: dest.append((AF_INET6, socktype, proto, "", sockaddr)) # As of 2016, some platforms return IPV6 first and some do IPV4 first, # and some might even allow configuration of which is which. For backwards # compatibility with earlier releases (but not necessarily resolver_thread!) # we return 4 first. See https://github.com/gevent/gevent/issues/815 for more. result += result4 + result6 if not result: raise gaierror(-5, "No address associated with hostname") return result
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): # pylint:disable=too-many-locals,too-many-branches if isinstance(host, text_type): host = host.encode('idna') elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: # Because there is no plug into ares.gethostbyname_file ares lib function, # we must call gethostbyname with IPv4 first and then IPv6. If the # two are called simultaneously as before, and if a DNS server is down, and # even if the IPv4 address is in hosts file, it will wait for IPv6 to hit # missing/invalid DNS server which will cause a huge wait. # This change has the benefit of returning immediately if IPv4 address is in # hosts file but drawback of waiting for IPv4 to miss hosts file lookup AND # missing DNS hit before looking at IPv6 if IPv4 address is not defined in hosts # file. This all can be better solved by looking in the hosts file for IPv4 and # and v6 first before attempting to look into DNS servers. values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET) if not len(values.get(throw_on_error=False)): values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET6) elif family == AF_INET: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET) elif family == AF_INET6: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET6) else: raise gaierror(5, 'ai_family not supported: %r' % (family, )) values = ares_values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype, proto in socktype_proto: result4.append((AF_INET, socktype, proto, '', sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == '::1': dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype, proto in socktype_proto: dest.append((AF_INET6, socktype, proto, '', sockaddr)) # As of 2016, some platforms return IPV6 first and some do IPV4 first, # and some might even allow configuration of which is which. For backwards # compatibility with earlier releases (but not necessarily resolver_thread!) # we return 4 first. See https://github.com/gevent/gevent/issues/815 for more. result += result4 + result6 if not result: raise gaierror(-5, 'No address associated with hostname') return result
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): # pylint:disable=too-many-locals,too-many-branches if isinstance(host, text_type): host = host.encode('idna') elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: ares_values = Values(self.hub, 2) ares.gethostbyname(ares_values, host, AF_INET) ares.gethostbyname(ares_values, host, AF_INET6) elif family == AF_INET: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET) elif family == AF_INET6: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET6) else: raise gaierror(5, 'ai_family not supported: %r' % (family, )) values = ares_values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype4, proto4 in socktype_proto: result4.append( (AF_INET, socktype4, proto4, '', sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == '::1': dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype6, proto6 in socktype_proto: dest.append( (AF_INET6, socktype6, proto6, '', sockaddr)) # As of 2016, some platforms return IPV6 first and some do IPV4 first, # and some might even allow configuration of which is which. For backwards # compatibility with earlier releases (but not necessarily resolver_thread!) # we return 4 first. See https://github.com/gevent/gevent/issues/815 for more. result += result4 + result6 if not result: raise gaierror(-5, 'No address associated with hostname') return result
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): # pylint:disable=too-many-locals,too-many-branches if isinstance(host, text_type): host = host.encode('idna') elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: ares_values = Values(self.hub, 2) ares.gethostbyname(ares_values, host, AF_INET) ares.gethostbyname(ares_values, host, AF_INET6) elif family == AF_INET: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET) elif family == AF_INET6: ares_values = Values(self.hub, 1) ares.gethostbyname(ares_values, host, AF_INET6) else: raise gaierror(5, 'ai_family not supported: %r' % (family, )) values = ares_values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype, proto in socktype_proto: result4.append( (AF_INET, socktype, proto, '', sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == '::1': dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype, proto in socktype_proto: dest.append((AF_INET6, socktype, proto, '', sockaddr)) result += result4 + result6 if not result: raise gaierror(-5, 'No address associated with hostname') return result
def test_handle_exception(self): """ Tests the high level call that branches based on exception type for all types. """ # For each exception type, check that the proper code is returned and # that a failure message has been output. For simplicity in those tests, # reset the tags after each run. code = self.exception_handler.handle_exception(exceptions.BadRequestException({})) self.assertEqual(code, handler.CODE_BAD_REQUEST) self.assertEqual(3, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.ConflictException({})) self.assertEqual(code, handler.CODE_CONFLICT) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.ConnectionException({})) self.assertEqual(code, handler.CODE_CONNECTION_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.NotFoundException({'resources' : {'repo_id' : 'foo'}})) self.assertEqual(code, handler.CODE_NOT_FOUND) self.assertEqual(2, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.PermissionsException({})) self.assertEqual(code, handler.CODE_PERMISSIONS_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.PulpServerException({})) self.assertEqual(code, handler.CODE_PULP_SERVER_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(InvalidConfig('Test Message')) self.assertEqual(code, handler.CODE_INVALID_CONFIG) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(WrongHost('expected', 'actual')) self.assertEqual(code, handler.CODE_WRONG_HOST) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.ApacheServerException('Test Message')) self.assertEqual(code, handler.CODE_APACHE_SERVER_EXCEPTION) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(gaierror()) self.assertEqual(code, handler.CODE_UNKNOWN_HOST) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(socket_error()) self.assertEqual(code, handler.CODE_SOCKET_ERROR) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = [] code = self.exception_handler.handle_exception(exceptions.ClientCertificateExpiredException( CERT_FILENAME)) self.assertEqual(code, handler.CODE_PERMISSIONS_EXCEPTION) self.assertEqual([TAG_FAILURE, TAG_PARAGRAPH], self.prompt.get_write_tags()) self.prompt.tags = [] code = self.exception_handler.handle_exception(Exception({})) self.assertEqual(code, handler.CODE_UNEXPECTED) self.assertEqual(1, len(self.prompt.tags)) self.assertEqual(TAG_FAILURE, self.prompt.get_write_tags()[0]) self.prompt.tags = []
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): if isinstance(host, text_type): host = host.encode("idna") elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: values = Values(self.hub, 2) ares.gethostbyname(values, host, AF_INET) ares.gethostbyname(values, host, AF_INET6) elif family == AF_INET: values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET) elif family == AF_INET6: values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET6) else: raise gaierror(5, "ai_family not supported: %r" % (family,)) values = values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype, proto in socktype_proto: result4.append((AF_INET, socktype, proto, "", sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == "::1": dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype, proto in socktype_proto: dest.append((AF_INET6, socktype, proto, "", sockaddr)) result += result4 + result6 if not result: raise gaierror(-5, "No address associated with hostname") return result
def _getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0): if isinstance(host, unicode): host = host.encode('idna') elif not isinstance(host, str) or (flags & AI_NUMERICHOST): # this handles cases which do not require network access # 1) host is None # 2) host is of an invalid type # 3) AI_NUMERICHOST flag is set if self.pool is not None: return self.pool.apply_e( BaseException, getaddrinfo, (host, port, family, socktype, proto, flags)) else: return getaddrinfo(host, port, family, socktype, proto, flags) # we also call _socket.getaddrinfo below if family is not one of AF_* if self.pool is not None and '.' not in host: # localhost, <broadcast> return self.pool.apply_e( BaseException, getaddrinfo, (host, port, family, socktype, proto, flags)) origport = port port, socktypes = self._lookup_port(port, socktype) socktype_proto = [(SOCK_STREAM, 6), (SOCK_DGRAM, 17), (SOCK_RAW, 0)] if socktypes: socktype_proto = [(x, y) for (x, y) in socktype_proto if x in socktypes] if proto: socktype_proto = [(x, y) for (x, y) in socktype_proto if proto == y] ares = self.ares if family == AF_UNSPEC: values = Values(self.hub, 2) ares.gethostbyname(values, host, AF_INET) ares.gethostbyname(values, host, AF_INET6) elif family == AF_INET: values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET) elif family == AF_INET6: values = Values(self.hub, 1) ares.gethostbyname(values, host, AF_INET6) else: if self.pool is not None: return self.pool.apply_e( BaseException, getaddrinfo, (host, origport, family, socktype, proto, flags)) else: return getaddrinfo(host, origport, family, socktype, proto, flags) values = values.get() if len(values) == 2 and values[0] == values[1]: values.pop() result = [] result4 = [] result6 = [] for addrs in values: if addrs.family == AF_INET: for addr in addrs[-1]: sockaddr = (addr, port) for socktype, proto in socktype_proto: result4.append( (AF_INET, socktype, proto, '', sockaddr)) elif addrs.family == AF_INET6: for addr in addrs[-1]: if addr == '::1': dest = result else: dest = result6 sockaddr = (addr, port, 0, 0) for socktype, proto in socktype_proto: dest.append((AF_INET6, socktype, proto, '', sockaddr)) result += result4 + result6 if not result: raise gaierror(-5, 'No address associated with hostname') return result