mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
[3.14] gh-133889: Improve tests for SimpleHTTPRequestHandler (GH-134102) (GH-134121)
(cherry picked from commit fcaf009907
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
f89323236f
commit
5cdad8c90c
1 changed files with 98 additions and 42 deletions
|
@ -522,34 +522,111 @@ class SimpleHTTPServerTestCase(BaseTestCase):
|
||||||
reader.close()
|
reader.close()
|
||||||
return body
|
return body
|
||||||
|
|
||||||
|
def check_list_dir_dirname(self, dirname, quotedname=None):
|
||||||
|
fullpath = os.path.join(self.tempdir, dirname)
|
||||||
|
try:
|
||||||
|
os.mkdir(os.path.join(self.tempdir, dirname))
|
||||||
|
except (OSError, UnicodeEncodeError):
|
||||||
|
self.skipTest(f'Can not create directory {dirname!a} '
|
||||||
|
f'on current file system')
|
||||||
|
|
||||||
|
if quotedname is None:
|
||||||
|
quotedname = urllib.parse.quote(dirname, errors='surrogatepass')
|
||||||
|
response = self.request(self.base_url + '/' + quotedname + '/')
|
||||||
|
body = self.check_status_and_reason(response, HTTPStatus.OK)
|
||||||
|
displaypath = html.escape(f'{self.base_url}/{dirname}/', quote=False)
|
||||||
|
enc = sys.getfilesystemencoding()
|
||||||
|
prefix = f'listing for {displaypath}</'.encode(enc, 'surrogateescape')
|
||||||
|
self.assertIn(prefix + b'title>', body)
|
||||||
|
self.assertIn(prefix + b'h1>', body)
|
||||||
|
|
||||||
|
def check_list_dir_filename(self, filename):
|
||||||
|
fullpath = os.path.join(self.tempdir, filename)
|
||||||
|
content = ascii(fullpath).encode() + (os_helper.TESTFN_UNDECODABLE or b'\xff')
|
||||||
|
try:
|
||||||
|
with open(fullpath, 'wb') as f:
|
||||||
|
f.write(content)
|
||||||
|
except OSError:
|
||||||
|
self.skipTest(f'Can not create file {filename!a} '
|
||||||
|
f'on current file system')
|
||||||
|
|
||||||
|
response = self.request(self.base_url + '/')
|
||||||
|
body = self.check_status_and_reason(response, HTTPStatus.OK)
|
||||||
|
quotedname = urllib.parse.quote(filename, errors='surrogatepass')
|
||||||
|
enc = response.headers.get_content_charset()
|
||||||
|
self.assertIsNotNone(enc)
|
||||||
|
self.assertIn((f'href="{quotedname}"').encode('ascii'), body)
|
||||||
|
displayname = html.escape(filename, quote=False)
|
||||||
|
self.assertIn(f'>{displayname}<'.encode(enc, 'surrogateescape'), body)
|
||||||
|
|
||||||
|
response = self.request(self.base_url + '/' + quotedname)
|
||||||
|
self.check_status_and_reason(response, HTTPStatus.OK, data=content)
|
||||||
|
|
||||||
|
@unittest.skipUnless(os_helper.TESTFN_NONASCII,
|
||||||
|
'need os_helper.TESTFN_NONASCII')
|
||||||
|
def test_list_dir_nonascii_dirname(self):
|
||||||
|
dirname = os_helper.TESTFN_NONASCII + '.dir'
|
||||||
|
self.check_list_dir_dirname(dirname)
|
||||||
|
|
||||||
|
@unittest.skipUnless(os_helper.TESTFN_NONASCII,
|
||||||
|
'need os_helper.TESTFN_NONASCII')
|
||||||
|
def test_list_dir_nonascii_filename(self):
|
||||||
|
filename = os_helper.TESTFN_NONASCII + '.txt'
|
||||||
|
self.check_list_dir_filename(filename)
|
||||||
|
|
||||||
@unittest.skipIf(is_apple,
|
@unittest.skipIf(is_apple,
|
||||||
'undecodable name cannot always be decoded on Apple platforms')
|
'undecodable name cannot always be decoded on Apple platforms')
|
||||||
@unittest.skipIf(sys.platform == 'win32',
|
@unittest.skipIf(sys.platform == 'win32',
|
||||||
'undecodable name cannot be decoded on win32')
|
'undecodable name cannot be decoded on win32')
|
||||||
@unittest.skipUnless(os_helper.TESTFN_UNDECODABLE,
|
@unittest.skipUnless(os_helper.TESTFN_UNDECODABLE,
|
||||||
'need os_helper.TESTFN_UNDECODABLE')
|
'need os_helper.TESTFN_UNDECODABLE')
|
||||||
def test_undecodable_filename(self):
|
def test_list_dir_undecodable_dirname(self):
|
||||||
enc = sys.getfilesystemencoding()
|
dirname = os.fsdecode(os_helper.TESTFN_UNDECODABLE) + '.dir'
|
||||||
|
self.check_list_dir_dirname(dirname)
|
||||||
|
|
||||||
|
@unittest.skipIf(is_apple,
|
||||||
|
'undecodable name cannot always be decoded on Apple platforms')
|
||||||
|
@unittest.skipIf(sys.platform == 'win32',
|
||||||
|
'undecodable name cannot be decoded on win32')
|
||||||
|
@unittest.skipUnless(os_helper.TESTFN_UNDECODABLE,
|
||||||
|
'need os_helper.TESTFN_UNDECODABLE')
|
||||||
|
def test_list_dir_undecodable_filename(self):
|
||||||
filename = os.fsdecode(os_helper.TESTFN_UNDECODABLE) + '.txt'
|
filename = os.fsdecode(os_helper.TESTFN_UNDECODABLE) + '.txt'
|
||||||
with open(os.path.join(self.tempdir, filename), 'wb') as f:
|
self.check_list_dir_filename(filename)
|
||||||
f.write(os_helper.TESTFN_UNDECODABLE)
|
|
||||||
response = self.request(self.base_url + '/')
|
def test_list_dir_undecodable_dirname2(self):
|
||||||
if is_apple:
|
dirname = '\ufffd.dir'
|
||||||
# On Apple platforms the HFS+ filesystem replaces bytes that
|
self.check_list_dir_dirname(dirname, quotedname='%ff.dir')
|
||||||
# aren't valid UTF-8 into a percent-encoded value.
|
|
||||||
for name in os.listdir(self.tempdir):
|
@unittest.skipUnless(os_helper.TESTFN_UNENCODABLE,
|
||||||
if name != 'test': # Ignore a filename created in setUp().
|
'need os_helper.TESTFN_UNENCODABLE')
|
||||||
filename = name
|
def test_list_dir_unencodable_dirname(self):
|
||||||
break
|
dirname = os_helper.TESTFN_UNENCODABLE + '.dir'
|
||||||
body = self.check_status_and_reason(response, HTTPStatus.OK)
|
self.check_list_dir_dirname(dirname)
|
||||||
quotedname = urllib.parse.quote(filename, errors='surrogatepass')
|
|
||||||
self.assertIn(('href="%s"' % quotedname)
|
@unittest.skipUnless(os_helper.TESTFN_UNENCODABLE,
|
||||||
.encode(enc, 'surrogateescape'), body)
|
'need os_helper.TESTFN_UNENCODABLE')
|
||||||
self.assertIn(('>%s<' % html.escape(filename, quote=False))
|
def test_list_dir_unencodable_filename(self):
|
||||||
.encode(enc, 'surrogateescape'), body)
|
filename = os_helper.TESTFN_UNENCODABLE + '.txt'
|
||||||
response = self.request(self.base_url + '/' + quotedname)
|
self.check_list_dir_filename(filename)
|
||||||
self.check_status_and_reason(response, HTTPStatus.OK,
|
|
||||||
data=os_helper.TESTFN_UNDECODABLE)
|
def test_list_dir_escape_dirname(self):
|
||||||
|
# Characters that need special treating in URL or HTML.
|
||||||
|
for name in ('q?', 'f#', '&', '&', '<i>', '"dq"', "'sq'",
|
||||||
|
'%A4', '%E2%82%AC'):
|
||||||
|
with self.subTest(name=name):
|
||||||
|
dirname = name + '.dir'
|
||||||
|
self.check_list_dir_dirname(dirname,
|
||||||
|
quotedname=urllib.parse.quote(dirname, safe='&<>\'"'))
|
||||||
|
|
||||||
|
def test_list_dir_escape_filename(self):
|
||||||
|
# Characters that need special treating in URL or HTML.
|
||||||
|
for name in ('q?', 'f#', '&', '&', '<i>', '"dq"', "'sq'",
|
||||||
|
'%A4', '%E2%82%AC'):
|
||||||
|
with self.subTest(name=name):
|
||||||
|
filename = name + '.txt'
|
||||||
|
self.check_list_dir_filename(filename)
|
||||||
|
os_helper.unlink(os.path.join(self.tempdir, filename))
|
||||||
|
|
||||||
def test_undecodable_parameter(self):
|
def test_undecodable_parameter(self):
|
||||||
# sanity check using a valid parameter
|
# sanity check using a valid parameter
|
||||||
|
@ -731,27 +808,6 @@ class SimpleHTTPServerTestCase(BaseTestCase):
|
||||||
self.assertEqual(response.getheader("Location"),
|
self.assertEqual(response.getheader("Location"),
|
||||||
self.tempdir_name + "/?hi=1")
|
self.tempdir_name + "/?hi=1")
|
||||||
|
|
||||||
def test_html_escape_filename(self):
|
|
||||||
filename = '<test&>.txt'
|
|
||||||
fullpath = os.path.join(self.tempdir, filename)
|
|
||||||
|
|
||||||
try:
|
|
||||||
open(fullpath, 'wb').close()
|
|
||||||
except OSError:
|
|
||||||
raise unittest.SkipTest('Can not create file %s on current file '
|
|
||||||
'system' % filename)
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = self.request(self.base_url + '/')
|
|
||||||
body = self.check_status_and_reason(response, HTTPStatus.OK)
|
|
||||||
enc = response.headers.get_content_charset()
|
|
||||||
finally:
|
|
||||||
os.unlink(fullpath) # avoid affecting test_undecodable_filename
|
|
||||||
|
|
||||||
self.assertIsNotNone(enc)
|
|
||||||
html_text = '>%s<' % html.escape(filename, quote=False)
|
|
||||||
self.assertIn(html_text.encode(enc), body)
|
|
||||||
|
|
||||||
|
|
||||||
cgi_file1 = """\
|
cgi_file1 = """\
|
||||||
#!%s
|
#!%s
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue