[Python-checkins] cpython (merge 3.4 -> default): Issue #22165: SimpleHTTPRequestHandler now supports undecodable file names.
serhiy.storchaka
python-checkins at python.org
Sun Aug 17 07:25:54 CEST 2014
http://hg.python.org/cpython/rev/3153a400b739
changeset: 92126:3153a400b739
parent: 92124:6219aa966a5f
parent: 92125:f180a9156cc8
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sun Aug 17 08:24:49 2014 +0300
summary:
Issue #22165: SimpleHTTPRequestHandler now supports undecodable file names.
files:
Lib/http/server.py | 19 +++++++++++++++----
Lib/test/test_httpservers.py | 19 +++++++++++++++++++
Misc/NEWS | 2 ++
3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/Lib/http/server.py b/Lib/http/server.py
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -747,7 +747,12 @@
return None
list.sort(key=lambda a: a.lower())
r = []
- displaypath = html.escape(urllib.parse.unquote(self.path))
+ try:
+ displaypath = urllib.parse.unquote(self.path,
+ errors='surrogatepass')
+ except UnicodeDecodeError:
+ displaypath = urllib.parse.unquote(path)
+ displaypath = html.escape(displaypath)
enc = sys.getfilesystemencoding()
title = 'Directory listing for %s' % displaypath
r.append('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
@@ -769,9 +774,11 @@
displayname = name + "@"
# Note: a link to a directory displays with @ and links with /
r.append('<li><a href="%s">%s</a></li>'
- % (urllib.parse.quote(linkname), html.escape(displayname)))
+ % (urllib.parse.quote(linkname,
+ errors='surrogatepass'),
+ html.escape(displayname)))
r.append('</ul>\n<hr>\n</body>\n</html>\n')
- encoded = '\n'.join(r).encode(enc)
+ encoded = '\n'.join(r).encode(enc, 'surrogateescape')
f = io.BytesIO()
f.write(encoded)
f.seek(0)
@@ -794,7 +801,11 @@
path = path.split('#',1)[0]
# Don't forget explicit trailing slash when normalizing. Issue17324
trailing_slash = path.rstrip().endswith('/')
- path = posixpath.normpath(urllib.parse.unquote(path))
+ try:
+ path = urllib.parse.unquote(path, errors='surrogatepass')
+ except UnicodeDecodeError:
+ path = urllib.parse.unquote(path)
+ path = posixpath.normpath(path)
words = path.split('/')
words = filter(None, words)
path = os.getcwd()
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -14,6 +14,7 @@
import base64
import shutil
import urllib.parse
+import html
import http.client
import tempfile
from io import BytesIO
@@ -266,6 +267,24 @@
self.assertIsNotNone(response.reason)
if data:
self.assertEqual(data, body)
+ return body
+
+ @unittest.skipUnless(support.TESTFN_UNDECODABLE,
+ 'need support.TESTFN_UNDECODABLE')
+ def test_undecodable_filename(self):
+ filename = os.fsdecode(support.TESTFN_UNDECODABLE) + '.txt'
+ with open(os.path.join(self.tempdir, filename), 'wb') as f:
+ f.write(support.TESTFN_UNDECODABLE)
+ response = self.request(self.tempdir_name + '/')
+ body = self.check_status_and_reason(response, 200)
+ quotedname = urllib.parse.quote(filename, errors='surrogatepass')
+ self.assertIn(('href="%s"' % quotedname)
+ .encode('utf-8', 'surrogateescape'), body)
+ self.assertIn(('>%s<' % html.escape(filename))
+ .encode('utf-8', 'surrogateescape'), body)
+ response = self.request(self.tempdir_name + '/' + quotedname)
+ self.check_status_and_reason(response, 200,
+ data=support.TESTFN_UNDECODABLE)
def test_get(self):
#constructs the path relative to the root directory of the HTTPServer
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -118,6 +118,8 @@
Library
-------
+- Issue #22165: SimpleHTTPRequestHandler now supports undecodable file names.
+
- Issue #15381: Optimized line reading in io.BytesIO.
- Issue #20729: Restored the use of lazy iterkeys()/itervalues()/iteritems()
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list