ipv6 support in gunicorn. fix ticket #107.

This commit is contained in:
benoitc 2010-11-20 21:04:03 +01:00
parent 108ccb7690
commit 09e243d6f6
2 changed files with 44 additions and 14 deletions

View File

@ -61,6 +61,14 @@ class TCPSocket(BaseSocket):
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
return super(TCPSocket, self).set_options(sock, bound=bound)
class TCP6Socket(TCPSocket):
FAMILY = socket.AF_INET6
def __str__(self):
(host, port, fl, sc) = self.sock.getsockname()
return "http://[%s]:%d" % (host, port)
class UnixSocket(BaseSocket):
FAMILY = socket.AF_UNIX
@ -97,7 +105,10 @@ def create_socket(conf):
addr = conf.address
if isinstance(addr, tuple):
sock_type = TCPSocket
if util.is_ipv6(addr[0]):
sock_type = TCP6Socket
else:
sock_type = TCPSocket
elif isinstance(addr, basestring):
sock_type = UnixSocket
else:

View File

@ -99,20 +99,39 @@ def chown(path, uid, gid):
os.chown(path, uid, gid)
except OverflowError:
os.chown(path, uid, -ctypes.c_int(-gid).value)
def is_ipv6(addr):
try:
socket.inet_pton(socket.AF_INET6, addr)
except socket.error: # not a valid address
return False
return True
def parse_address(host, port=None, default_port=8000):
if host.startswith("unix:"):
return host.split("unix:")[1]
if not port:
if ':' in host:
host, port = host.split(':', 1)
if not port.isdigit():
raise RuntimeError("%r is not a valid port number." % port)
port = int(port)
else:
port = default_port
return (host, int(port))
def parse_address(netloc, default_port=8000):
if netloc.startswith("unix:"):
return netloc.split("unix:")[1]
# get host
if '[' in netloc and ']' in netloc:
host = netloc.split(']')[0][1:].lower()
elif ':' in netloc:
host = netloc.split(':')[0].lower()
elif netloc == "":
host = "0.0.0.0"
else:
host = netloc.lower()
#get port
netloc = netloc.split(']')[-1]
if ":" in netloc:
port = netloc.rsplit(':', 1)[1]
if not port.isdigit():
raise RuntimeError("%r is not a valid port number." % port)
port = int(port)
else:
port = default_port
return (host, port)
def get_maxfd():
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]