Skip to content

Instantly share code, notes, and snippets.

@pyrocat101
Created August 25, 2014 04:30
Show Gist options
  • Save pyrocat101/2f1bb9fd1a864feda0f4 to your computer and use it in GitHub Desktop.
Save pyrocat101/2f1bb9fd1a864feda0f4 to your computer and use it in GitHub Desktop.
import select
import socket
import pycares
class CAresError(socket.error):
def __init__(self, errno, strerror):
super(CAresError, self).__init__(errno, strerror)
def wait(channel):
while True:
read_fds, write_fds = channel.getsock()
if not read_fds and not write_fds:
break
timeout = channel.timeout()
if timeout == 0.0:
channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD)
continue
rlist, wlist, _ = select.select(read_fds, write_fds, [], timeout)
for fd in rlist:
channel.process_fd(fd, pycares.ARES_SOCKET_BAD)
for fd in wlist:
channel.process_fd(pycares.ARES_SOCKET_BAD, fd)
def getaddrinfo(host, port, channel=None, timeout=1.0):
timeout = float(timeout)
errors = []
def callback4(res, errno):
if errno:
errors.append(CAresError(errno, pycares.errno.strerror(errno)))
else:
callback4.res = [(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, '', (addr, port))
for addr in res.addresses]
callback4.res = None
def callback6(res, errno):
if errno:
errors.append(CAresError(errno, pycares.errno.strerror(errno)))
else:
callback6.res = [(socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP, '', (addr, port, 0, 0))
for addr in res.addresses]
callback6.res = None
if channel is None:
channel = pycares.Channel(timeout=timeout)
channel.gethostbyname(host, socket.AF_INET6, callback6)
channel.gethostbyname(host, socket.AF_INET, callback4)
wait(channel)
if len(errors) > 0:
raise errors[0]
return callback6.res + callback4.res
from pprint import pprint as pp
# This should work
pp(getaddrinfo('google.com', 80, timeout=1.00))
# This does not work
pp(getaddrinfo('google.com', 80, timeout=0.99))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment