Commit 9edbba34 authored by Jason Madden's avatar Jason Madden

Merge #495.

- Additional testing on a mix of ip4 and ip6 connections.
- Simplify address parsing.
- changelog.

Fixes #495.
parent b808d892
......@@ -50,6 +50,9 @@
installation time. Previously, if it wasn't available, a build was
attempted at every import. This could lead to scattered "gevent"
directories and undependable results.
- Servers: Default to AF_INET6 when binding to all addresses. This
supports both IPv4 and IPv6 connections. Original change in
:pr:`495` by Felix Kaiser.
1.1.0 (Mar 5, 2016)
......
......@@ -378,19 +378,20 @@ def _parse_address(address):
if not address[0] or ':' in address[0]:
return _socket.AF_INET6, address
return _socket.AF_INET, address
elif isinstance(address, string_types):
if ':' in address:
if ((isinstance(address, string_types) and ':' not in address)
or isinstance(address, integer_types)): # noqa (pep8 E129)
# Just a port
return _socket.AF_INET6, ('', int(address))
if not isinstance(address, string_types):
raise TypeError('Expected tuple or string, got %s' % type(address))
host, port = address.rsplit(':', 1)
family, host = _extract_family(host)
if host == '*':
host = ''
return family, (host, int(port))
else:
return _socket.AF_INET6, ('', int(address))
elif isinstance(address, integer_types):
return _socket.AF_INET6, ('', int(address))
else:
raise TypeError('Expected tuple or string, got %s' % type(address))
def parse_address(address):
......
......@@ -251,7 +251,9 @@ class TestCase(greentest.TestCase):
def init_server(self, application):
logger = self.logger = self.init_logger()
self.server = pywsgi.WSGIServer(('127.0.0.1', 0), application,
# Bind to default address, which should give us ipv6 (when available)
# and ipv4. (see self.connect())
self.server = pywsgi.WSGIServer(('', 0), application,
log=logger, error_log=logger)
def setUp(self):
......@@ -284,6 +286,8 @@ class TestCase(greentest.TestCase):
# XXX currently listening socket is kept open in gevent.wsgi
def connect(self):
# connect on ipv4, even though we bound to ipv6 too
# to prove ipv4 works
conn = socket.create_connection(('127.0.0.1', self.port))
self.connected.append(weakref.ref(conn))
result = conn
......
......@@ -85,10 +85,19 @@ class TestCase(greentest.TestCase):
return sock
def makefile(self, timeout=_DEFAULT_SOCKET_TIMEOUT, bufsize=1):
sock = socket.socket()
server_host = self.server.server_host
if not server_host or server_host == '::':
server_host = 'localhost'
try:
family = self.server.socket.family
except AttributeError:
# server deletes socket when closed
family = socket.AF_INET
sock = socket.socket(family=family)
try:
sock.connect((self.server.server_host, self.server.server_port))
except:
sock.connect((server_host, self.server.server_port))
except Exception as e:
# avoid ResourceWarning under Py3
sock.close()
raise
......@@ -176,7 +185,7 @@ class TestCase(greentest.TestCase):
print('^^^^^')
def init_server(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server = self.ServerSubClass(('', 0))
self.server.start()
gevent.sleep(0.01)
......@@ -186,9 +195,11 @@ class TestCase(greentest.TestCase):
def _test_invalid_callback(self):
try:
self.expect_one_error()
self.server = self.ServerClass(('127.0.0.1', 0), lambda: None)
self.server = self.ServerClass(('', 0), lambda: None)
self.server.start()
self.expect_one_error()
self.assert500()
self.assert_error(TypeError)
finally:
......@@ -231,7 +242,7 @@ class TestDefaultSpawn(TestCase):
self.assertRaises(TypeError, self.ServerClass, self.get_listener(), backlog=25, handle=False)
def test_backlog_is_accepted_for_address(self):
self.server = self.ServerSubClass(('127.0.0.1', 0), backlog=25)
self.server = self.ServerSubClass(('', 0), backlog=25)
self.assertConnectionRefused()
self._test_server_start_stop(restartable=False)
......@@ -246,7 +257,7 @@ class TestDefaultSpawn(TestCase):
self._test_server_start_stop(restartable=True)
def test_subclass_with_address(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server = self.ServerSubClass(('', 0))
self.assertConnectionRefused()
self._test_server_start_stop(restartable=True)
......@@ -272,7 +283,7 @@ class TestDefaultSpawn(TestCase):
self._test_serve_forever()
def test_serve_forever_after_start(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server = self.ServerSubClass(('', 0))
self.assertConnectionRefused()
assert not self.server.started
self.server.start()
......@@ -280,7 +291,7 @@ class TestDefaultSpawn(TestCase):
self._test_serve_forever()
def test_server_closes_client_sockets(self):
self.server = self.ServerClass(('127.0.0.1', 0), lambda *args: [])
self.server = self.ServerClass(('', 0), lambda *args: [])
self.server.start()
conn = self.send_request()
timeout = gevent.Timeout.start_new(1)
......@@ -303,7 +314,7 @@ class TestDefaultSpawn(TestCase):
self.stop_server()
def init_server(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server = self.ServerSubClass(('', 0))
self.server.start()
gevent.sleep(0.01)
......@@ -399,7 +410,7 @@ class TestNoneSpawn(TestCase):
def test_assertion_in_blocking_func(self):
def sleep(*args):
gevent.sleep(0)
self.server = Settings.ServerClass(('127.0.0.1', 0), sleep, spawn=None)
self.server = Settings.ServerClass(('', 0), sleep, spawn=None)
self.server.start()
self.expect_one_error()
self.assert500()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment