Add support for URLs and absolute paths in staticweb CSS listings.

Fixes bug 939267. Return the quoted web-listings-css value
if it starts with '/', 'http://', or 'https://.' All other values
are treated as relative paths.

Change-Id: I55ee4ec77cf8db99aa48c9a398e29767b200e1eb
This commit is contained in:
Doug Weimer 2012-02-23 05:50:36 +00:00
parent 48f7af6195
commit f73cf2b3eb
2 changed files with 70 additions and 6 deletions

View File

@ -307,8 +307,7 @@ class StaticWeb(object):
cgi.escape(env['PATH_INFO']) cgi.escape(env['PATH_INFO'])
if self._listings_css: if self._listings_css:
body += ' <link rel="stylesheet" type="text/css" ' \ body += ' <link rel="stylesheet" type="text/css" ' \
'href="%s%s" />\n' % \ 'href="%s" />\n' % (self._build_css_path(prefix))
('../' * prefix.count('/'), quote(self._listings_css))
else: else:
body += ' <style type="text/css">\n' \ body += ' <style type="text/css">\n' \
' h1 {font-size: 1em; font-weight: bold;}\n' \ ' h1 {font-size: 1em; font-weight: bold;}\n' \
@ -366,6 +365,19 @@ class StaticWeb(object):
self._log_response(env, resp.status_int) self._log_response(env, resp.status_int)
return resp(env, start_response) return resp(env, start_response)
def _build_css_path(self, prefix=''):
"""
Constructs a relative path from a given prefix within the container.
URLs and paths starting with '/' are not modified.
:param prefix: The prefix for the container listing.
"""
if self._listings_css.startswith(('/', 'http://', 'https://')):
css_path = quote(self._listings_css, ':/')
else:
css_path = '../' * prefix.count('/') + quote(self._listings_css)
return css_path
def _handle_container(self, env, start_response): def _handle_container(self, env, start_response):
""" """
Handles a possible static web request for a container. Handles a possible static web request for a container.

View File

@ -182,11 +182,30 @@ class FakeApp(object):
return self.listing(env, start_response, return self.listing(env, start_response,
{'x-container-read': '.r:*', {'x-container-read': '.r:*',
'x-container-meta-web-listings': 'f'}) 'x-container-meta-web-listings': 'f'})
elif env['PATH_INFO'] in ('/v1/a/c8', '/v1/a/c8/'):
return self.listing(env, start_response,
{'x-container-read': '.r:*',
'x-container-meta-web-error': 'error.html',
'x-container-meta-web-listings': 't',
'x-container-meta-web-listings-css': \
'http://localhost/stylesheets/listing.css'})
elif env['PATH_INFO'] == '/v1/a/c8/subdir/':
return Response(status='404 Not Found')(env, start_response)
elif env['PATH_INFO'] in ('/v1/a/c9', '/v1/a/c9/'):
return self.listing(env, start_response,
{'x-container-read': '.r:*',
'x-container-meta-web-error': 'error.html',
'x-container-meta-web-listings': 't',
'x-container-meta-web-listings-css': \
'/absolute/listing.css'})
elif env['PATH_INFO'] == '/v1/a/c9/subdir/':
return Response(status='404 Not Found')(env, start_response)
else: else:
raise Exception('Unknown path %r' % env['PATH_INFO']) raise Exception('Unknown path %r' % env['PATH_INFO'])
def listing(self, env, start_response, headers): def listing(self, env, start_response, headers):
if env['PATH_INFO'] in ('/v1/a/c3', '/v1/a/c4') and \ if env['PATH_INFO'] in ('/v1/a/c3', '/v1/a/c4', '/v1/a/c8', \
'/v1/a/c9') and \
env['QUERY_STRING'] == 'delimiter=/&format=json&prefix=subdir/': env['QUERY_STRING'] == 'delimiter=/&format=json&prefix=subdir/':
headers.update({'X-Container-Object-Count': '11', headers.update({'X-Container-Object-Count': '11',
'X-Container-Bytes-Used': '73741', 'X-Container-Bytes-Used': '73741',
@ -417,6 +436,7 @@ class TestStaticWeb(unittest.TestCase):
resp = Request.blank('/v1/a/c4/').get_response(self.test_staticweb) resp = Request.blank('/v1/a/c4/').get_response(self.test_staticweb)
self.assertEquals(resp.status_int, 200) self.assertEquals(resp.status_int, 200)
self.assert_('Listing of /v1/a/c4/' in resp.body) self.assert_('Listing of /v1/a/c4/' in resp.body)
self.assert_('href="listing.css"' in resp.body)
def test_container4indexhtmlauthed(self): def test_container4indexhtmlauthed(self):
resp = Request.blank('/v1/a/c4').get_response(self.test_staticweb) resp = Request.blank('/v1/a/c4').get_response(self.test_staticweb)
@ -479,7 +499,7 @@ class TestStaticWeb(unittest.TestCase):
self.assert_('Listing of /v1/a/c4/subdir/' in resp.body) self.assert_('Listing of /v1/a/c4/subdir/' in resp.body)
self.assert_('</style>' not in resp.body) self.assert_('</style>' not in resp.body)
self.assert_('<link' in resp.body) self.assert_('<link' in resp.body)
self.assert_('listing.css' in resp.body) self.assert_('href="../listing.css"' in resp.body)
self.assertEquals(resp.headers['content-type'], self.assertEquals(resp.headers['content-type'],
'text/html; charset=UTF-8') 'text/html; charset=UTF-8')
@ -512,6 +532,40 @@ class TestStaticWeb(unittest.TestCase):
resp = Request.blank('/v1/a/c7/').get_response(self.test_staticweb) resp = Request.blank('/v1/a/c7/').get_response(self.test_staticweb)
self.assertEquals(resp.status_int, 404) self.assertEquals(resp.status_int, 404)
def test_container8listingcss(self):
resp = Request.blank(
'/v1/a/c8/').get_response(self.test_staticweb)
self.assertEquals(resp.status_int, 200)
self.assert_('Listing of /v1/a/c8/' in resp.body)
self.assert_('<link' in resp.body)
self.assert_(
'href="http://localhost/stylesheets/listing.css"' in resp.body)
def test_container8subdirlistingcss(self):
resp = Request.blank(
'/v1/a/c8/subdir/').get_response(self.test_staticweb)
self.assertEquals(resp.status_int, 200)
self.assert_('Listing of /v1/a/c8/subdir/' in resp.body)
self.assert_('<link' in resp.body)
self.assert_(
'href="http://localhost/stylesheets/listing.css"' in resp.body)
def test_container9listingcss(self):
resp = Request.blank(
'/v1/a/c9/').get_response(self.test_staticweb)
self.assertEquals(resp.status_int, 200)
self.assert_('Listing of /v1/a/c9/' in resp.body)
self.assert_('<link' in resp.body)
self.assert_('href="/absolute/listing.css"' in resp.body)
def test_container9subdirlistingcss(self):
resp = Request.blank(
'/v1/a/c9/subdir/').get_response(self.test_staticweb)
self.assertEquals(resp.status_int, 200)
self.assert_('Listing of /v1/a/c9/subdir/' in resp.body)
self.assert_('<link' in resp.body)
self.assert_('href="/absolute/listing.css"' 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)
@ -520,7 +574,5 @@ class TestStaticWeb(unittest.TestCase):
self.assertEquals(resp.body, '1') self.assertEquals(resp.body, '1')
self.assertEquals(self.app.calls, 1) self.assertEquals(self.app.calls, 1)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()