Remove simplejson from staticweb
Since we're dropping Python 2.6 support, we can rely on stdlib's json and get rid of our dependency on simplejson. This lets us get rid of some redundant Unicode encoding. Before, we would take the container-listing response off the wire, JSON-deserialize it (str -> unicode), then pass each of several fields from each entry to get_valid_utf8_str(), which would encode it, (unicode -> str), decode it (str -> unicode), and then encode it again (unicode -> str) for good measure. The net effect was that each object's name would, in the proxy server, go str -> unicode -> str -> unicode -> str. By replacing simplejson with stdlib json, we get a guarantee that each container-listing entry's name, hash, content_type, and last_modified are unicodes, so we can stop worrying about them being valid UTF-8 or not. This takes an encode and decode out of the path, so we just have str -> unicode -> str. While it'd be ideal to avoid this, the first transform (str -> unicode) happens when we decode the container-listing response body (json.loads()), so there's no way out. Change-Id: I00aedf952d691a809c23025b89131ea0f02b6431
This commit is contained in:
parent
15fd063ac3
commit
38787d0fb5
@ -117,10 +117,11 @@ Example usage of this middleware via ``swift``:
|
|||||||
|
|
||||||
|
|
||||||
import cgi
|
import cgi
|
||||||
|
import json
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from swift.common.utils import human_readable, split_path, config_true_value, \
|
from swift.common.utils import human_readable, split_path, config_true_value, \
|
||||||
json, quote, get_valid_utf8_str, register_swift_info
|
quote, register_swift_info
|
||||||
from swift.common.wsgi import make_pre_authed_env, WSGIContext
|
from swift.common.wsgi import make_pre_authed_env, WSGIContext
|
||||||
from swift.common.http import is_success, is_redirection, HTTP_NOT_FOUND
|
from swift.common.http import is_success, is_redirection, HTTP_NOT_FOUND
|
||||||
from swift.common.swob import Response, HTTPMovedPermanently, HTTPNotFound
|
from swift.common.swob import Response, HTTPMovedPermanently, HTTPNotFound
|
||||||
@ -289,7 +290,7 @@ class _StaticWebContext(WSGIContext):
|
|||||||
' </tr>\n'
|
' </tr>\n'
|
||||||
for item in listing:
|
for item in listing:
|
||||||
if 'subdir' in item:
|
if 'subdir' in item:
|
||||||
subdir = get_valid_utf8_str(item['subdir'])
|
subdir = item['subdir'].encode("utf-8")
|
||||||
if prefix:
|
if prefix:
|
||||||
subdir = subdir[len(prefix):]
|
subdir = subdir[len(prefix):]
|
||||||
body += ' <tr class="item subdir">\n' \
|
body += ' <tr class="item subdir">\n' \
|
||||||
@ -300,13 +301,14 @@ class _StaticWebContext(WSGIContext):
|
|||||||
(quote(subdir), cgi.escape(subdir))
|
(quote(subdir), cgi.escape(subdir))
|
||||||
for item in listing:
|
for item in listing:
|
||||||
if 'name' in item:
|
if 'name' in item:
|
||||||
name = get_valid_utf8_str(item['name'])
|
name = item['name'].encode("utf-8")
|
||||||
if prefix:
|
if prefix:
|
||||||
name = name[len(prefix):]
|
name = name[len(prefix):]
|
||||||
content_type = get_valid_utf8_str(item['content_type'])
|
content_type = item['content_type'].encode("utf-8")
|
||||||
bytes = get_valid_utf8_str(human_readable(item['bytes']))
|
bytes = human_readable(item['bytes'])
|
||||||
last_modified = (cgi.escape(item['last_modified']).
|
last_modified = (
|
||||||
split('.')[0].replace('T', ' '))
|
cgi.escape(item['last_modified'].encode("utf-8")).
|
||||||
|
split('.')[0].replace('T', ' '))
|
||||||
body += ' <tr class="item %s">\n' \
|
body += ' <tr class="item %s">\n' \
|
||||||
' <td class="colname"><a href="%s">%s</a></td>\n' \
|
' <td class="colname"><a href="%s">%s</a></td>\n' \
|
||||||
' <td class="colsize">%s</td>\n' \
|
' <td class="colsize">%s</td>\n' \
|
||||||
@ -315,7 +317,7 @@ class _StaticWebContext(WSGIContext):
|
|||||||
(' '.join('type-' + cgi.escape(t.lower(), quote=True)
|
(' '.join('type-' + cgi.escape(t.lower(), quote=True)
|
||||||
for t in content_type.split('/')),
|
for t in content_type.split('/')),
|
||||||
quote(name), cgi.escape(name),
|
quote(name), cgi.escape(name),
|
||||||
bytes, get_valid_utf8_str(last_modified))
|
bytes, last_modified)
|
||||||
body += ' </table>\n' \
|
body += ' </table>\n' \
|
||||||
' </body>\n' \
|
' </body>\n' \
|
||||||
'</html>\n'
|
'</html>\n'
|
||||||
|
@ -13,15 +13,9 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
try:
|
import json
|
||||||
import simplejson as json
|
|
||||||
except ImportError:
|
|
||||||
import json
|
|
||||||
import json as stdlib_json
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import mock
|
|
||||||
|
|
||||||
from swift.common.swob import Request, Response
|
from swift.common.swob import Request, Response
|
||||||
from swift.common.middleware import staticweb
|
from swift.common.middleware import staticweb
|
||||||
|
|
||||||
@ -699,24 +693,6 @@ class TestStaticWeb(unittest.TestCase):
|
|||||||
self.assert_('listing.css' not in resp.body)
|
self.assert_('listing.css' not in resp.body)
|
||||||
self.assert_('<style' in resp.body)
|
self.assert_('<style' 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):
|
def test_subrequest_once_if_possible(self):
|
||||||
resp = Request.blank(
|
resp = Request.blank(
|
||||||
'/v1/a/c4/one.txt').get_response(self.test_staticweb)
|
'/v1/a/c4/one.txt').get_response(self.test_staticweb)
|
||||||
|
Loading…
Reference in New Issue
Block a user