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) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
return super(TCPSocket, self).set_options(sock, bound=bound) 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): class UnixSocket(BaseSocket):
FAMILY = socket.AF_UNIX FAMILY = socket.AF_UNIX
@ -97,6 +105,9 @@ def create_socket(conf):
addr = conf.address addr = conf.address
if isinstance(addr, tuple): if isinstance(addr, tuple):
if util.is_ipv6(addr[0]):
sock_type = TCP6Socket
else:
sock_type = TCPSocket sock_type = TCPSocket
elif isinstance(addr, basestring): elif isinstance(addr, basestring):
sock_type = UnixSocket sock_type = UnixSocket

View File

@ -100,19 +100,38 @@ def chown(path, uid, gid):
except OverflowError: except OverflowError:
os.chown(path, uid, -ctypes.c_int(-gid).value) os.chown(path, uid, -ctypes.c_int(-gid).value)
def parse_address(host, port=None, default_port=8000):
if host.startswith("unix:"):
return host.split("unix:")[1]
if not port: def is_ipv6(addr):
if ':' in host: try:
host, port = host.split(':', 1) socket.inet_pton(socket.AF_INET6, addr)
except socket.error: # not a valid address
return False
return True
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(): if not port.isdigit():
raise RuntimeError("%r is not a valid port number." % port) raise RuntimeError("%r is not a valid port number." % port)
port = int(port) port = int(port)
else: else:
port = default_port port = default_port
return (host, int(port)) return (host, port)
def get_maxfd(): def get_maxfd():
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]