diff --git a/swift/common/middleware/staticweb.py b/swift/common/middleware/staticweb.py index 8874096beb..8a2061cb17 100644 --- a/swift/common/middleware/staticweb.py +++ b/swift/common/middleware/staticweb.py @@ -125,13 +125,17 @@ from swift.common.swob import Response, HTTPMovedPermanently, HTTPNotFound from swift.proxy.controllers.base import get_container_info +def ensure_utf8_bytes(value): + if isinstance(value, unicode): + value = value.encode('utf-8') + return value + + def quote(value, safe='/'): """ Patched version of urllib.quote that encodes utf-8 strings before quoting """ - if isinstance(value, unicode): - value = value.encode('utf-8') - return urllib_quote(value, safe) + return urllib_quote(ensure_utf8_bytes(value), safe) class _StaticWebContext(WSGIContext): @@ -272,10 +276,7 @@ class _StaticWebContext(WSGIContext): ' \n' for item in listing: if 'subdir' in item: - if isinstance(item['subdir'], unicode): - subdir = item['subdir'].encode('utf-8') - else: - subdir = item['subdir'] + subdir = ensure_utf8_bytes(item['subdir']) if prefix: subdir = subdir[len(prefix):] body += ' \n' \ @@ -286,23 +287,22 @@ class _StaticWebContext(WSGIContext): (quote(subdir), cgi.escape(subdir)) for item in listing: if 'name' in item: - if isinstance(item['name'], unicode): - name = item['name'].encode('utf-8') - else: - name = item['name'] + name = ensure_utf8_bytes(item['name']) if prefix: name = name[len(prefix):] + content_type = ensure_utf8_bytes(item['content_type']) + bytes = ensure_utf8_bytes(human_readable(item['bytes'])) + last_modified = (cgi.escape(item['last_modified']). + split('.')[0].replace('T', ' ')) body += ' \n' \ ' %s\n' \ ' %s\n' \ ' %s\n' \ ' \n' % \ (' '.join('type-' + cgi.escape(t.lower(), quote=True) - for t in item['content_type'].split('/')), + for t in content_type.split('/')), quote(name), cgi.escape(name), - human_readable(item['bytes']), - cgi.escape(item['last_modified']).split('.')[0]. - replace('T', ' ')) + bytes, ensure_utf8_bytes(last_modified)) body += ' \n' \ ' \n' \ '\n' diff --git a/test/unit/common/middleware/test_staticweb.py b/test/unit/common/middleware/test_staticweb.py index 886e744c59..11c34fcb28 100644 --- a/test/unit/common/middleware/test_staticweb.py +++ b/test/unit/common/middleware/test_staticweb.py @@ -17,8 +17,11 @@ try: import simplejson as json except ImportError: import json +import json as stdlib_json import unittest +import mock + from swift.common.swob import Request, Response from swift.common.middleware import staticweb @@ -659,12 +662,30 @@ class TestStaticWeb(unittest.TestCase): self.test_staticweb) self.assertEquals(resp.status_int, 200) + def test_container12unredirectedrequest(self): resp = Request.blank('/v1/a/c12/').get_response( self.test_staticweb) self.assertEquals(resp.status_int, 200) self.assert_('index file' in resp.body) + def test_container_unicode_stdlib_json(self): + with mock.patch('swift.common.middleware.staticweb.json', new=stdlib_json): + resp = Request.blank( + '/v1/a/c10/').get_response(self.test_staticweb) + self.assertEquals(resp.status_int, 200) + self.assert_('Listing of /v1/a/c10/' in resp.body) + resp = Request.blank( + '/v1/a/c10/\xe2\x98\x83/').get_response(self.test_staticweb) + self.assertEquals(resp.status_int, 200) + self.assert_('Listing of /v1/a/c10/\xe2\x98\x83/' in resp.body) + resp = Request.blank( + '/v1/a/c10/\xe2\x98\x83/\xe2\x98\x83/' + ).get_response(self.test_staticweb) + self.assertEquals(resp.status_int, 200) + self.assert_( + 'Listing of /v1/a/c10/\xe2\x98\x83/\xe2\x98\x83/' in resp.body) + def test_subrequest_once_if_possible(self): resp = Request.blank( '/v1/a/c4/one.txt').get_response(self.test_staticweb)