From 4cc392fb2a873b77b85fb8790be64c50f5d8b223 Mon Sep 17 00:00:00 2001 From: Sergey Ninua <1624866+ffix@users.noreply.github.com> Date: Mon, 30 Oct 2017 09:22:33 +0300 Subject: [PATCH] fixed ValueError for AF_INET6 sockets (#2431) * fixed ValueError for AF_INET6 sockets * changelog entry added for #2431 * Update 2431.bugfix * rename has_ipv6 to HAS_IPV6: it's a contant --- CHANGES/2431.bugfix | 1 + aiohttp/web.py | 2 +- tests/test_run_app.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 CHANGES/2431.bugfix diff --git a/CHANGES/2431.bugfix b/CHANGES/2431.bugfix new file mode 100644 index 00000000000..99e5c17db92 --- /dev/null +++ b/CHANGES/2431.bugfix @@ -0,0 +1 @@ +fixed ValueError for AF_INET6 sockets if a preexisting INET6 socket to the `aiohttp.web.run_app` function. diff --git a/aiohttp/web.py b/aiohttp/web.py index cc89d9304a8..28c0cf82510 100644 --- a/aiohttp/web.py +++ b/aiohttp/web.py @@ -421,7 +421,7 @@ def _make_server_creators(handler, *, loop, ssl_context, if hasattr(socket, 'AF_UNIX') and sock.family == socket.AF_UNIX: uris.append('{}://unix:{}:'.format(scheme, sock.getsockname())) else: - host, port = sock.getsockname() + host, port = sock.getsockname()[:2] uris.append(str(base_url.with_host(host).with_port(port))) return server_creations, uris diff --git a/tests/test_run_app.py b/tests/test_run_app.py index 89629de36a1..44e90c63783 100644 --- a/tests/test_run_app.py +++ b/tests/test_run_app.py @@ -42,6 +42,16 @@ ) del _has_unix_domain_socks, _abstract_path_failed +HAS_IPV6 = socket.has_ipv6 +if HAS_IPV6: + # The socket.has_ipv6 flag may be True if Python was built with IPv6 + # support, but the target system still may not have it. + # So let's ensure that we really have IPv6 support. + try: + socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + except OSError: + HAS_IPV6 = False + # tokio event loop does not allow to override attributes def skip_if_no_dict(loop): @@ -451,6 +461,31 @@ def test_run_app_preexisting_inet_socket(loop, mocker): assert "http://0.0.0.0:{}".format(port) in printer.call_args[0][0] +@pytest.mark.skipif(not HAS_IPV6, reason="IPv6 is not available") +def test_run_app_preexisting_inet6_socket(loop, mocker): + skip_if_no_dict(loop) + + mocker.spy(loop, 'create_server') + + app = web.Application() + mocker.spy(app, 'startup') + + sock = socket.socket(socket.AF_INET6) + with contextlib.closing(sock): + sock.bind(('::', 0)) + port = sock.getsockname()[1] + + printer = mock.Mock(wraps=stopper(loop)) + web.run_app(app, loop=loop, sock=sock, print=printer) + + assert not loop.is_closed() + loop.create_server.assert_called_with( + mock.ANY, sock=sock, backlog=128, ssl=None + ) + app.startup.assert_called_once_with() + assert "http://:::{}".format(port) in printer.call_args[0][0] + + @skip_if_no_unix_socks def test_run_app_preexisting_unix_socket(loop, mocker): skip_if_no_dict(loop)