From b86bc51607a6855deaa5a365d705174836151e8b Mon Sep 17 00:00:00 2001 From: Matthew Oliver Date: Mon, 18 Mar 2019 16:43:29 +1100 Subject: [PATCH] py3: port staticweb middleware This patch is porting the staticweb middleware to py3. Change-Id: I5d9a13baecedd13d2b7a8ae3dd639eaff0894441 --- swift/common/middleware/staticweb.py | 36 ++++--- test/unit/common/middleware/test_staticweb.py | 96 +++++++++---------- tox.ini | 1 + 3 files changed, 73 insertions(+), 60 deletions(-) diff --git a/swift/common/middleware/staticweb.py b/swift/common/middleware/staticweb.py index d01c753b34..60514c59a6 100644 --- a/swift/common/middleware/staticweb.py +++ b/swift/common/middleware/staticweb.py @@ -125,6 +125,7 @@ Example usage of this middleware via ``swift``: import cgi import json +import six import time from swift.common.utils import human_readable, split_path, config_true_value, \ @@ -132,7 +133,7 @@ from swift.common.utils import human_readable, split_path, config_true_value, \ from swift.common.wsgi import make_env, WSGIContext from swift.common.http import is_success, is_redirection, HTTP_NOT_FOUND from swift.common.swob import Response, HTTPMovedPermanently, HTTPNotFound, \ - Request + Request, wsgi_quote, wsgi_to_str from swift.proxy.controllers.base import get_container_info @@ -145,6 +146,12 @@ class _StaticWebContext(WSGIContext): that might need to be handled to make keeping contextual information about the request a bit simpler than storing it in the WSGI env. + + :param staticweb: The staticweb middleware object in use. + :param version: A WSGI string representation of the swift api version. + :param account: A WSGI string representation of the account name. + :param container: A WSGI string representation of the container name. + :param obj: A WSGI string representation of the object name. """ def __init__(self, staticweb, version, account, container, obj): @@ -223,9 +230,9 @@ class _StaticWebContext(WSGIContext): :param start_response: The original WSGI start_response hook. :param prefix: Any prefix desired for the container listing. """ - label = env['PATH_INFO'] + label = wsgi_to_str(env['PATH_INFO']) if self._listings_label: - groups = env['PATH_INFO'].split('/') + groups = wsgi_to_str(env['PATH_INFO']).split('/') label = '{0}/{1}'.format(self._listings_label, '/'.join(groups[4:])) @@ -262,14 +269,14 @@ class _StaticWebContext(WSGIContext): self.agent, swift_source='SW') tmp_env['QUERY_STRING'] = 'delimiter=/' if prefix: - tmp_env['QUERY_STRING'] += '&prefix=%s' % quote(prefix) + tmp_env['QUERY_STRING'] += '&prefix=%s' % wsgi_quote(prefix) else: prefix = '' resp = self._app_call(tmp_env) if not is_success(self._get_status_int()): return self._error_response(resp, env, start_response) listing = None - body = ''.join(resp) + body = b''.join(resp) if body: listing = json.loads(body) if not listing: @@ -280,7 +287,8 @@ class _StaticWebContext(WSGIContext): 'Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n' \ '\n' \ ' \n' \ - ' Listing of %s\n' % cgi.escape(label) + ' Listing of %s\n' % \ + cgi.escape(label) if self._listings_css: body += ' \n' % (self._build_css_path(prefix)) @@ -308,7 +316,8 @@ class _StaticWebContext(WSGIContext): ' \n' for item in listing: if 'subdir' in item: - subdir = item['subdir'].encode("utf-8") + subdir = item['subdir'] if six.PY3 else \ + item['subdir'].encode('utf-8') if prefix: subdir = subdir[len(prefix):] body += ' \n' \ @@ -319,13 +328,16 @@ class _StaticWebContext(WSGIContext): (quote(subdir), cgi.escape(subdir)) for item in listing: if 'name' in item: - name = item['name'].encode("utf-8") + name = item['name'] if six.PY3 else \ + item['name'].encode('utf-8') if prefix: name = name[len(prefix):] - content_type = item['content_type'].encode("utf-8") + content_type = item['content_type'] if six.PY3 else \ + item['content_type'].encode('utf-8') bytes = human_readable(item['bytes']) last_modified = ( - cgi.escape(item['last_modified'].encode("utf-8")). + cgi.escape(item['last_modified'] if six.PY3 else + item['last_modified'].encode('utf-8')). split('.')[0].replace('T', ' ')) body += ' \n' \ ' %s\n' \ @@ -466,9 +478,9 @@ class _StaticWebContext(WSGIContext): self.version, self.account, self.container), self.agent, swift_source='SW') tmp_env['QUERY_STRING'] = 'limit=1&delimiter=/&prefix=%s' % ( - quote(self.obj + '/'), ) + quote(wsgi_to_str(self.obj) + '/'), ) resp = self._app_call(tmp_env) - body = ''.join(resp) + body = b''.join(resp) if not is_success(self._get_status_int()) or not body or \ not json.loads(body): resp = HTTPNotFound()(env, self._start_response) diff --git a/test/unit/common/middleware/test_staticweb.py b/test/unit/common/middleware/test_staticweb.py index ba6d1a705d..b72b34bf29 100644 --- a/test/unit/common/middleware/test_staticweb.py +++ b/test/unit/common/middleware/test_staticweb.py @@ -528,7 +528,7 @@ class TestStaticWeb(unittest.TestCase): def test_container3indexhtml(self): resp = Request.blank('/v1/a/c3/').get_response(self.test_staticweb) self.assertEqual(resp.status_int, 200) - self.assertTrue('Test main index.html file.' in resp.body) + self.assertIn(b'Test main index.html file.', resp.body) def test_container3subsubdir(self): resp = Request.blank( @@ -539,16 +539,16 @@ class TestStaticWeb(unittest.TestCase): resp = Request.blank( '/v1/a/c3/subdir3/subsubdir/').get_response(self.test_staticweb) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.body, 'index file') + self.assertEqual(resp.body, b'index file') def test_container3subdir(self): resp = Request.blank( '/v1/a/c3/subdir/').get_response(self.test_staticweb) self.assertEqual(resp.status_int, 200) - self.assertIn('Listing of /v1/a/c3/subdir/', resp.body) - self.assertIn('', resp.body) - self.assertNotIn('', resp.body) + self.assertNotIn(b'', resp.body) - self.assertIn('', resp.body) + self.assertIn(b'c11 subdir index' in resp.body) + self.assertIn(b'

c11 subdir index

', resp.body) def test_container11subdirmarkermatchdirtype(self): resp = Request.blank('/v1/a/c11a/subdir/').get_response( self.test_staticweb) self.assertEqual(resp.status_int, 404) - self.assertIn('Index File Not Found', resp.body) + self.assertIn(b'Index File Not Found', resp.body) def test_container11subdirmarkeraltdirtype(self): resp = Request.blank('/v1/a/c11a/subdir2/').get_response( @@ -775,27 +775,27 @@ class TestStaticWeb(unittest.TestCase): resp = Request.blank('/v1/a/c12/').get_response( self.test_staticweb) self.assertEqual(resp.status_int, 200) - self.assertIn('index file', resp.body) + self.assertIn(b'index file', resp.body) def test_container_404_has_css(self): resp = Request.blank('/v1/a/c13/').get_response( self.test_staticweb) self.assertEqual(resp.status_int, 404) - self.assertIn('listing.css', resp.body) + self.assertIn(b'listing.css', resp.body) def test_container_404_has_no_css(self): resp = Request.blank('/v1/a/c7/').get_response( self.test_staticweb) self.assertEqual(resp.status_int, 404) - self.assertNotIn('listing.css', resp.body) - self.assertIn('