Make staticweb return URL-encoded Location headers

Also, enhance tests to verify proper encoding in generated responses.

Change-Id: Ib696b1c3a34722f3a6de010973b90ef8b1917012
Partial-Bug: 1774238
This commit is contained in:
Tim Burke 2018-06-01 15:59:25 -07:00
parent b27026f6c7
commit e5ff405ec9
2 changed files with 39 additions and 37 deletions

View File

@ -376,7 +376,8 @@ class _StaticWebContext(WSGIContext):
env['wsgi.url_scheme'] = self.url_scheme env['wsgi.url_scheme'] = self.url_scheme
if self.url_host: if self.url_host:
env['HTTP_HOST'] = self.url_host env['HTTP_HOST'] = self.url_host
resp = HTTPMovedPermanently(location=(env['PATH_INFO'] + '/')) resp = HTTPMovedPermanently(
location=wsgi_quote(env['PATH_INFO'] + '/'))
return resp(env, start_response) return resp(env, start_response)
def handle_container(self, env, start_response): def handle_container(self, env, start_response):

View File

@ -16,6 +16,8 @@
import functools import functools
from unittest2 import SkipTest from unittest2 import SkipTest
from six.moves.urllib.parse import unquote
from swift.common.utils import quote
import test.functional as tf import test.functional as tf
from test.functional import cluster_info from test.functional import cluster_info
from test.functional.tests import Utils, Base, BaseEnv from test.functional.tests import Utils, Base, BaseEnv
@ -74,8 +76,8 @@ class TestStaticWebEnv(BaseEnv):
'listings_css', 'listings_css',
'dir/', 'dir/',
'dir/obj', 'dir/obj',
'dir/subdir/', 'dir/some sub%dir/',
'dir/subdir/obj'] 'dir/some sub%dir/obj']
cls.objects = {} cls.objects = {}
for item in sorted(objects): for item in sorted(objects):
@ -168,12 +170,12 @@ class TestStaticWeb(Base):
def _test_redirect_slash_direct(self, anonymous): def _test_redirect_slash_direct(self, anonymous):
host = self.env.account.conn.storage_netloc host = self.env.account.conn.storage_netloc
path = '%s/%s' % (self.env.account.conn.storage_path, path = '%s/%s' % (self.env.account.conn.storage_path,
self.env.container.name) quote(self.env.container.name))
self._test_redirect_with_slash(host, path, anonymous=anonymous) self._test_redirect_with_slash(host, path, anonymous=anonymous)
path = '%s/%s/%s' % (self.env.account.conn.storage_path, path = '%s/%s/%s' % (self.env.account.conn.storage_path,
self.env.container.name, quote(self.env.container.name),
self.env.objects['dir/'].name) quote(self.env.objects['dir/'].name))
self._test_redirect_with_slash(host, path, anonymous=anonymous) self._test_redirect_with_slash(host, path, anonymous=anonymous)
def test_redirect_slash_auth_direct(self): def test_redirect_slash_auth_direct(self):
@ -185,10 +187,10 @@ class TestStaticWeb(Base):
@requires_domain_remap @requires_domain_remap
def _test_redirect_slash_remap_acct(self, anonymous): def _test_redirect_slash_remap_acct(self, anonymous):
host = self.domain_remap_acct host = self.domain_remap_acct
path = '/%s' % self.env.container.name path = '/%s' % quote(self.env.container.name)
self._test_redirect_with_slash(host, path, anonymous=anonymous) self._test_redirect_with_slash(host, path, anonymous=anonymous)
path = '/%s/%s' % (self.env.container.name, path = '/%s/%s' % (quote(self.env.container.name),
self.env.objects['dir/'].name) self.env.objects['dir/'].name)
self._test_redirect_with_slash(host, path, anonymous=anonymous) self._test_redirect_with_slash(host, path, anonymous=anonymous)
@ -229,13 +231,14 @@ class TestStaticWeb(Base):
self._set_staticweb_headers(listings=True, self._set_staticweb_headers(listings=True,
listings_css=(css is not None)) listings_css=(css is not None))
if title is None: if title is None:
title = path title = unquote(path)
expected_in = ['Listing of %s' % title] + [ expected_in = ['Listing of %s' % title] + [
'<a href="{0}">{0}</a>'.format(link) for link in links] '<a href="{0}">{1}</a>'.format(quote(link), link)
for link in links]
expected_not_in = notins expected_not_in = notins
if css: if css:
expected_in.append('<link rel="stylesheet" type="text/css" ' expected_in.append('<link rel="stylesheet" type="text/css" '
'href="%s" />' % css) 'href="%s" />' % quote(css))
self._test_get_path(host, path, anonymous=anonymous, self._test_get_path(host, path, anonymous=anonymous,
expected_in=expected_in, expected_in=expected_in,
expected_not_in=expected_not_in) expected_not_in=expected_not_in)
@ -244,7 +247,7 @@ class TestStaticWeb(Base):
objects = self.env.objects objects = self.env.objects
host = self.env.account.conn.storage_netloc host = self.env.account.conn.storage_netloc
path = '%s/%s/' % (self.env.account.conn.storage_path, path = '%s/%s/' % (self.env.account.conn.storage_path,
self.env.container.name) quote(self.env.container.name))
css = objects['listings_css'].name if listings_css else None css = objects['listings_css'].name if listings_css else None
self._test_listing(host, path, anonymous=True, css=css, self._test_listing(host, path, anonymous=True, css=css,
links=[objects['index'].name, links=[objects['index'].name,
@ -252,15 +255,15 @@ class TestStaticWeb(Base):
notins=[objects['dir/obj'].name]) notins=[objects['dir/obj'].name])
path = '%s/%s/%s/' % (self.env.account.conn.storage_path, path = '%s/%s/%s/' % (self.env.account.conn.storage_path,
self.env.container.name, quote(self.env.container.name),
objects['dir/'].name) quote(objects['dir/'].name))
css = '../%s' % objects['listings_css'].name if listings_css else None css = '../%s' % objects['listings_css'].name if listings_css else None
self._test_listing(host, path, anonymous=anonymous, css=css, self._test_listing(
host, path, anonymous=anonymous, css=css,
links=[objects['dir/obj'].name.split('/')[-1], links=[objects['dir/obj'].name.split('/')[-1],
objects['dir/subdir/'].name.split('/')[-1] objects['dir/some sub%dir/'].name.split('/')[-1] + '/'],
+ '/'],
notins=[objects['index'].name, notins=[objects['index'].name,
objects['dir/subdir/obj'].name]) objects['dir/some sub%dir/obj'].name])
def test_listing_auth_direct_without_css(self): def test_listing_auth_direct_without_css(self):
self._test_listing_direct(False, False) self._test_listing_direct(False, False)
@ -293,13 +296,12 @@ class TestStaticWeb(Base):
title = '%s/%s/%s/' % (self.env.account.conn.storage_path, title = '%s/%s/%s/' % (self.env.account.conn.storage_path,
self.env.container.name, self.env.container.name,
objects['dir/']) objects['dir/'])
self._test_listing(host, path, title=title, anonymous=anonymous, self._test_listing(
css=css, host, path, title=title, anonymous=anonymous, css=css,
links=[objects['dir/obj'].name.split('/')[-1], links=[objects['dir/obj'].name.split('/')[-1],
objects['dir/subdir/'].name.split('/')[-1] objects['dir/some sub%dir/'].name.split('/')[-1] + '/'],
+ '/'],
notins=[objects['index'].name, notins=[objects['index'].name,
objects['dir/subdir/obj'].name]) objects['dir/some sub%dir/obj'].name])
def test_listing_auth_remap_acct_without_css(self): def test_listing_auth_remap_acct_without_css(self):
self._test_listing_remap_acct(False, False) self._test_listing_remap_acct(False, False)
@ -332,13 +334,12 @@ class TestStaticWeb(Base):
title = '%s/%s/%s/' % (self.env.account.conn.storage_path, title = '%s/%s/%s/' % (self.env.account.conn.storage_path,
self.env.container.name, self.env.container.name,
objects['dir/']) objects['dir/'])
self._test_listing(host, path, title=title, anonymous=anonymous, self._test_listing(
css=css, host, path, title=title, anonymous=anonymous, css=css,
links=[objects['dir/obj'].name.split('/')[-1], links=[objects['dir/obj'].name.split('/')[-1],
objects['dir/subdir/'].name.split('/')[-1] objects['dir/some sub%dir/'].name.split('/')[-1] + '/'],
+ '/'],
notins=[objects['index'].name, notins=[objects['index'].name,
objects['dir/subdir/obj'].name]) objects['dir/some sub%dir/obj'].name])
def test_listing_auth_remap_cont_without_css(self): def test_listing_auth_remap_cont_without_css(self):
self._test_listing_remap_cont(False, False) self._test_listing_remap_cont(False, False)
@ -369,12 +370,12 @@ class TestStaticWeb(Base):
objects = self.env.objects objects = self.env.objects
host = self.env.account.conn.storage_netloc host = self.env.account.conn.storage_netloc
path = '%s/%s/' % (self.env.account.conn.storage_path, path = '%s/%s/' % (self.env.account.conn.storage_path,
self.env.container.name) quote(self.env.container.name))
self._test_index(host, path, anonymous=anonymous) self._test_index(host, path, anonymous=anonymous)
path = '%s/%s/%s/' % (self.env.account.conn.storage_path, path = '%s/%s/%s/' % (self.env.account.conn.storage_path,
self.env.container.name, quote(self.env.container.name),
objects['dir/'].name) quote(objects['dir/'].name))
self._test_index(host, path, anonymous=anonymous, expected_status=404) self._test_index(host, path, anonymous=anonymous, expected_status=404)
def test_index_auth_direct(self): def test_index_auth_direct(self):