mirror of
https://github.com/python/cpython.git
synced 2025-07-16 07:45:20 +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()
|
||||
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,
|
||||
'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_undecodable_filename(self):
|
||||
enc = sys.getfilesystemencoding()
|
||||
def test_list_dir_undecodable_dirname(self):
|
||||
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'
|
||||
with open(os.path.join(self.tempdir, filename), 'wb') as f:
|
||||
f.write(os_helper.TESTFN_UNDECODABLE)
|
||||
response = self.request(self.base_url + '/')
|
||||
if is_apple:
|
||||
# On Apple platforms the HFS+ filesystem replaces bytes that
|
||||
# aren't valid UTF-8 into a percent-encoded value.
|
||||
for name in os.listdir(self.tempdir):
|
||||
if name != 'test': # Ignore a filename created in setUp().
|
||||
filename = name
|
||||
break
|
||||
body = self.check_status_and_reason(response, HTTPStatus.OK)
|
||||
quotedname = urllib.parse.quote(filename, errors='surrogatepass')
|
||||
self.assertIn(('href="%s"' % quotedname)
|
||||
.encode(enc, 'surrogateescape'), body)
|
||||
self.assertIn(('>%s<' % html.escape(filename, quote=False))
|
||||
.encode(enc, 'surrogateescape'), body)
|
||||
response = self.request(self.base_url + '/' + quotedname)
|
||||
self.check_status_and_reason(response, HTTPStatus.OK,
|
||||
data=os_helper.TESTFN_UNDECODABLE)
|
||||
self.check_list_dir_filename(filename)
|
||||
|
||||
def test_list_dir_undecodable_dirname2(self):
|
||||
dirname = '\ufffd.dir'
|
||||
self.check_list_dir_dirname(dirname, quotedname='%ff.dir')
|
||||
|
||||
@unittest.skipUnless(os_helper.TESTFN_UNENCODABLE,
|
||||
'need os_helper.TESTFN_UNENCODABLE')
|
||||
def test_list_dir_unencodable_dirname(self):
|
||||
dirname = os_helper.TESTFN_UNENCODABLE + '.dir'
|
||||
self.check_list_dir_dirname(dirname)
|
||||
|
||||
@unittest.skipUnless(os_helper.TESTFN_UNENCODABLE,
|
||||
'need os_helper.TESTFN_UNENCODABLE')
|
||||
def test_list_dir_unencodable_filename(self):
|
||||
filename = os_helper.TESTFN_UNENCODABLE + '.txt'
|
||||
self.check_list_dir_filename(filename)
|
||||
|
||||
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):
|
||||
# sanity check using a valid parameter
|
||||
|
@ -731,27 +808,6 @@ class SimpleHTTPServerTestCase(BaseTestCase):
|
|||
self.assertEqual(response.getheader("Location"),
|
||||
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 = """\
|
||||
#!%s
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue