From 433433fa6d55091600ce88dd19206b3902e0a87d Mon Sep 17 00:00:00 2001 From: Lisa Roach Date: Mon, 26 Nov 2018 10:43:38 -0800 Subject: [PATCH] Adds IPv6 support when invoking http.server directly. (GH-10595) --- Doc/library/http.server.rst | 8 ++++++-- Lib/http/server.py | 3 +++ Lib/test/test_httpservers.py | 20 +++++++++++++++++++ .../2018-11-18-18-44-40.bpo-24209.p3YWOf.rst | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-11-18-18-44-40.bpo-24209.p3YWOf.rst diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 29f6e7da3bd..a367e373dc3 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -410,14 +410,18 @@ the previous example, this serves files relative to the current directory:: python -m http.server 8000 By default, server binds itself to all interfaces. The option ``-b/--bind`` -specifies a specific address to which it should bind. For example, the -following command causes the server to bind to localhost only:: +specifies a specific address to which it should bind. Both IPv4 and IPv6 +addresses are supported. For example, the following command causes the server +to bind to localhost only:: python -m http.server 8000 --bind 127.0.0.1 .. versionadded:: 3.4 ``--bind`` argument was introduced. +.. versionadded:: 3.8 + ``--bind`` argument enhanced to support IPv6 + By default, server uses the current directory. The option ``-d/--directory`` specifies a directory to which it should serve the files. For example, the following command uses a specific directory:: diff --git a/Lib/http/server.py b/Lib/http/server.py index ca2dd507392..22d865f2fdf 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -1226,6 +1226,9 @@ def test(HandlerClass=BaseHTTPRequestHandler, """ server_address = (bind, port) + if ':' in bind: + ServerClass.address_family = socket.AF_INET6 + HandlerClass.protocol_version = protocol with ServerClass(server_address, HandlerClass) as httpd: sa = httpd.socket.getsockname() diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index cc829a522b8..3d8e0af8b45 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -9,6 +9,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer, \ from http import server, HTTPStatus import os +import socket import sys import re import base64 @@ -1116,6 +1117,24 @@ class MiscTestCase(unittest.TestCase): self.assertCountEqual(server.__all__, expected) +class ScriptTestCase(unittest.TestCase): + @mock.patch('builtins.print') + def test_server_test_ipv6(self, _): + mock_server = mock.MagicMock() + server.test(ServerClass=mock_server, bind="::") + self.assertEqual(mock_server.address_family, socket.AF_INET6) + + mock_server.reset_mock() + server.test(ServerClass=mock_server, + bind="2001:0db8:85a3:0000:0000:8a2e:0370:7334") + self.assertEqual(mock_server.address_family, socket.AF_INET6) + + mock_server.reset_mock() + server.test(ServerClass=mock_server, + bind="::1") + self.assertEqual(mock_server.address_family, socket.AF_INET6) + + def test_main(verbose=None): cwd = os.getcwd() try: @@ -1127,6 +1146,7 @@ def test_main(verbose=None): CGIHTTPServerTestCase, SimpleHTTPRequestHandlerTestCase, MiscTestCase, + ScriptTestCase ) finally: os.chdir(cwd) diff --git a/Misc/NEWS.d/next/Library/2018-11-18-18-44-40.bpo-24209.p3YWOf.rst b/Misc/NEWS.d/next/Library/2018-11-18-18-44-40.bpo-24209.p3YWOf.rst new file mode 100644 index 00000000000..88749e920c2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-11-18-18-44-40.bpo-24209.p3YWOf.rst @@ -0,0 +1 @@ +Adds IPv6 support when invoking http.server directly.