diff options
-rw-r--r-- | Doc/library/http.server.rst | 3 | ||||
-rw-r--r-- | Lib/http/server.py | 2 | ||||
-rw-r--r-- | Lib/test/test_httpservers.py | 97 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst | 2 |
4 files changed, 80 insertions, 24 deletions
diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index a367e37..5173dec 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -344,6 +344,9 @@ provides three different variants: If not specified, the directory to serve is the current working directory. + .. versionchanged:: 3.9 + Accepts a :term:`path-like object`. + The :class:`SimpleHTTPRequestHandler` class defines the following methods: .. method:: do_HEAD() diff --git a/Lib/http/server.py b/Lib/http/server.py index b247675..005dd82 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -642,7 +642,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): def __init__(self, *args, directory=None, **kwargs): if directory is None: directory = os.getcwd() - self.directory = directory + self.directory = os.fspath(directory) super().__init__(*args, **kwargs) def do_GET(self): diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 87d4924..1c980a2 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -14,6 +14,7 @@ import sys import re import base64 import ntpath +import pathlib import shutil import email.message import email.utils @@ -790,10 +791,10 @@ class CGIHTTPServerTestCase(BaseTestCase): class SocketlessRequestHandler(SimpleHTTPRequestHandler): - def __init__(self, *args, **kwargs): + def __init__(self, directory=None): request = mock.Mock() request.makefile.return_value = BytesIO() - super().__init__(request, None, None) + super().__init__(request, None, None, directory=directory) self.get_called = False self.protocol_version = "HTTP/1.1" @@ -1068,41 +1069,91 @@ class BaseHTTPRequestHandlerTestCase(unittest.TestCase): class SimpleHTTPRequestHandlerTestCase(unittest.TestCase): """ Test url parsing """ def setUp(self): - self.translated = os.getcwd() - self.translated = os.path.join(self.translated, 'filename') - self.handler = SocketlessRequestHandler() + self.translated_1 = os.path.join(os.getcwd(), 'filename') + self.translated_2 = os.path.join('foo', 'filename') + self.translated_3 = os.path.join('bar', 'filename') + self.handler_1 = SocketlessRequestHandler() + self.handler_2 = SocketlessRequestHandler(directory='foo') + self.handler_3 = SocketlessRequestHandler(directory=pathlib.PurePath('bar')) def test_query_arguments(self): - path = self.handler.translate_path('/filename') - self.assertEqual(path, self.translated) - path = self.handler.translate_path('/filename?foo=bar') - self.assertEqual(path, self.translated) - path = self.handler.translate_path('/filename?a=b&spam=eggs#zot') - self.assertEqual(path, self.translated) + path = self.handler_1.translate_path('/filename') + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('/filename') + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('/filename') + self.assertEqual(path, self.translated_3) + + path = self.handler_1.translate_path('/filename?foo=bar') + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('/filename?foo=bar') + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('/filename?foo=bar') + self.assertEqual(path, self.translated_3) + + path = self.handler_1.translate_path('/filename?a=b&spam=eggs#zot') + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('/filename?a=b&spam=eggs#zot') + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('/filename?a=b&spam=eggs#zot') + self.assertEqual(path, self.translated_3) def test_start_with_double_slash(self): - path = self.handler.translate_path('//filename') - self.assertEqual(path, self.translated) - path = self.handler.translate_path('//filename?foo=bar') - self.assertEqual(path, self.translated) + path = self.handler_1.translate_path('//filename') + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('//filename') + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('//filename') + self.assertEqual(path, self.translated_3) + + path = self.handler_1.translate_path('//filename?foo=bar') + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('//filename?foo=bar') + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('//filename?foo=bar') + self.assertEqual(path, self.translated_3) def test_windows_colon(self): with support.swap_attr(server.os, 'path', ntpath): - path = self.handler.translate_path('c:c:c:foo/filename') + path = self.handler_1.translate_path('c:c:c:foo/filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('c:c:c:foo/filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('c:c:c:foo/filename') path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) + self.assertEqual(path, self.translated_3) - path = self.handler.translate_path('\\c:../filename') + path = self.handler_1.translate_path('\\c:../filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('\\c:../filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('\\c:../filename') path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) + self.assertEqual(path, self.translated_3) - path = self.handler.translate_path('c:\\c:..\\foo/filename') + path = self.handler_1.translate_path('c:\\c:..\\foo/filename') path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('c:\\c:..\\foo/filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('c:\\c:..\\foo/filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_3) - path = self.handler.translate_path('c:c:foo\\c:c:bar/filename') + path = self.handler_1.translate_path('c:c:foo\\c:c:bar/filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_1) + path = self.handler_2.translate_path('c:c:foo\\c:c:bar/filename') + path = path.replace(ntpath.sep, os.sep) + self.assertEqual(path, self.translated_2) + path = self.handler_3.translate_path('c:c:foo\\c:c:bar/filename') path = path.replace(ntpath.sep, os.sep) - self.assertEqual(path, self.translated) + self.assertEqual(path, self.translated_3) class MiscTestCase(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst b/Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst new file mode 100644 index 0000000..abdf87a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst @@ -0,0 +1,2 @@ +Allow passing a :term:`path-like object` as ``directory`` argument to the +:class:`http.server.SimpleHTTPRequestHandler` class. Patch by Géry Ogam. |