mirror of
https://github.com/python/cpython.git
synced 2025-11-26 21:33:10 +00:00
bpo-35640: Allow passing PathLike arguments to SimpleHTTPRequestHandler (GH-11398)
This commit is contained in:
parent
e1d455f3a3
commit
781266ebb6
4 changed files with 80 additions and 24 deletions
|
|
@ -344,6 +344,9 @@ provides three different variants:
|
||||||
|
|
||||||
If not specified, the directory to serve is the current working directory.
|
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:
|
The :class:`SimpleHTTPRequestHandler` class defines the following methods:
|
||||||
|
|
||||||
.. method:: do_HEAD()
|
.. method:: do_HEAD()
|
||||||
|
|
|
||||||
|
|
@ -642,7 +642,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
|
||||||
def __init__(self, *args, directory=None, **kwargs):
|
def __init__(self, *args, directory=None, **kwargs):
|
||||||
if directory is None:
|
if directory is None:
|
||||||
directory = os.getcwd()
|
directory = os.getcwd()
|
||||||
self.directory = directory
|
self.directory = os.fspath(directory)
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import sys
|
||||||
import re
|
import re
|
||||||
import base64
|
import base64
|
||||||
import ntpath
|
import ntpath
|
||||||
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
import email.message
|
import email.message
|
||||||
import email.utils
|
import email.utils
|
||||||
|
|
@ -790,10 +791,10 @@ class CGIHTTPServerTestCase(BaseTestCase):
|
||||||
|
|
||||||
|
|
||||||
class SocketlessRequestHandler(SimpleHTTPRequestHandler):
|
class SocketlessRequestHandler(SimpleHTTPRequestHandler):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, directory=None):
|
||||||
request = mock.Mock()
|
request = mock.Mock()
|
||||||
request.makefile.return_value = BytesIO()
|
request.makefile.return_value = BytesIO()
|
||||||
super().__init__(request, None, None)
|
super().__init__(request, None, None, directory=directory)
|
||||||
|
|
||||||
self.get_called = False
|
self.get_called = False
|
||||||
self.protocol_version = "HTTP/1.1"
|
self.protocol_version = "HTTP/1.1"
|
||||||
|
|
@ -1068,41 +1069,91 @@ class BaseHTTPRequestHandlerTestCase(unittest.TestCase):
|
||||||
class SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
|
class SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
|
||||||
""" Test url parsing """
|
""" Test url parsing """
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.translated = os.getcwd()
|
self.translated_1 = os.path.join(os.getcwd(), 'filename')
|
||||||
self.translated = os.path.join(self.translated, 'filename')
|
self.translated_2 = os.path.join('foo', 'filename')
|
||||||
self.handler = SocketlessRequestHandler()
|
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):
|
def test_query_arguments(self):
|
||||||
path = self.handler.translate_path('/filename')
|
path = self.handler_1.translate_path('/filename')
|
||||||
self.assertEqual(path, self.translated)
|
self.assertEqual(path, self.translated_1)
|
||||||
path = self.handler.translate_path('/filename?foo=bar')
|
path = self.handler_2.translate_path('/filename')
|
||||||
self.assertEqual(path, self.translated)
|
self.assertEqual(path, self.translated_2)
|
||||||
path = self.handler.translate_path('/filename?a=b&spam=eggs#zot')
|
path = self.handler_3.translate_path('/filename')
|
||||||
self.assertEqual(path, self.translated)
|
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):
|
def test_start_with_double_slash(self):
|
||||||
path = self.handler.translate_path('//filename')
|
path = self.handler_1.translate_path('//filename')
|
||||||
self.assertEqual(path, self.translated)
|
self.assertEqual(path, self.translated_1)
|
||||||
path = self.handler.translate_path('//filename?foo=bar')
|
path = self.handler_2.translate_path('//filename')
|
||||||
self.assertEqual(path, self.translated)
|
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):
|
def test_windows_colon(self):
|
||||||
with support.swap_attr(server.os, 'path', ntpath):
|
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)
|
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: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_3)
|
||||||
|
|
||||||
path = self.handler.translate_path('\\c:../filename')
|
path = self.handler_1.translate_path('\\c:../filename')
|
||||||
path = path.replace(ntpath.sep, os.sep)
|
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:../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_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)
|
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)
|
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\\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_3)
|
||||||
|
|
||||||
|
|
||||||
class MiscTestCase(unittest.TestCase):
|
class MiscTestCase(unittest.TestCase):
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue