From 2e220ca9121e3f1b7359de0259a324e0533fa55e Mon Sep 17 00:00:00 2001 From: Donagh McCabe Date: Tue, 18 Feb 2014 09:41:25 +0000 Subject: [PATCH] Improve StaticWeb 404 on web-listings/index A common scenario is for users to make a container public via an ACL. They can then use a browser to display the objects in the container. Next, they enable StaticWeb with something such as "X-Container-Meta-Web-Index:index.html" -- but then get confused because they get 404 Not Found (when index.html does not exist). For someone who understands what they are doing, this makes sense. However, we've had several customer escalations because of this. Usually, they are just playing with our GUI and have no intention of using StaticWeb for real -- the 404 looks like something is broken; not the correct response. The solution is to provide a better error message. This message is only shown when StaticWeb is refusing to give a listing -- other 404 situations are not affected. Also, a custom 404 error page is not affected. Change-Id: I3ba8c48e0ce148d8e91a1e0dc16a0d37a692a24e --- swift/common/middleware/staticweb.py | 26 ++++++++++++++++++- test/unit/common/middleware/test_staticweb.py | 17 ++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/swift/common/middleware/staticweb.py b/swift/common/middleware/staticweb.py index 6caca0159c..34b102ea53 100644 --- a/swift/common/middleware/staticweb.py +++ b/swift/common/middleware/staticweb.py @@ -209,7 +209,31 @@ class _StaticWebContext(WSGIContext): :param prefix: Any prefix desired for the container listing. """ if not config_true_value(self._listings): - resp = HTTPNotFound()(env, self._start_response) + body = '\n' \ + '\n' \ + '\n' \ + 'Listing of %s\n' % cgi.escape(env['PATH_INFO']) + if self._listings_css: + body += ' \n' % self._build_css_path(prefix or '') + else: + body += ' \n' + body += '\n' \ + '

Web Listing Disabled

' \ + '

The owner of this web site has disabled web listing.' \ + '

If you are the owner of this web site, you can enable' \ + ' web listing by setting X-Container-Meta-Web-Listings.

' + if self._index: + body += '

Index File Not Found

' \ + '

The owner of this web site has set ' \ + ' X-Container-Meta-Web-Index: %s. ' \ + ' However, this file is not found.

' % self._index + body += ' \n\n' + resp = HTTPNotFound(body=body)(env, self._start_response) return self._error_response(resp, env, start_response) tmp_env = make_pre_authed_env( env, 'GET', '/%s/%s/%s' % ( diff --git a/test/unit/common/middleware/test_staticweb.py b/test/unit/common/middleware/test_staticweb.py index 712dee38c8..a5c61b1c31 100644 --- a/test/unit/common/middleware/test_staticweb.py +++ b/test/unit/common/middleware/test_staticweb.py @@ -58,6 +58,8 @@ meta_map = { 'web-directory-type': 'text/directory'}}, 'c12': {'meta': {'web-index': 'index.html', 'web-error': 'error.html'}}, + 'c13': {'meta': {'web-listings': 'f', + 'web-listings-css': 'listing.css'}}, } @@ -604,6 +606,7 @@ class TestStaticWeb(unittest.TestCase): def test_container7listing(self): resp = Request.blank('/v1/a/c7/').get_response(self.test_staticweb) self.assertEquals(resp.status_int, 404) + self.assert_('Web Listing Disabled' in resp.body) def test_container8listingcss(self): resp = Request.blank( @@ -665,6 +668,7 @@ class TestStaticWeb(unittest.TestCase): resp = Request.blank('/v1/a/c11a/subdir/').get_response( self.test_staticweb) self.assertEquals(resp.status_int, 404) + self.assert_('Index File Not Found' in resp.body) def test_container11subdirmarkeraltdirtype(self): resp = Request.blank('/v1/a/c11a/subdir2/').get_response( @@ -682,6 +686,19 @@ class TestStaticWeb(unittest.TestCase): self.assertEquals(resp.status_int, 200) self.assert_('index file' in resp.body) + def test_container_404_has_css(self): + resp = Request.blank('/v1/a/c13/').get_response( + self.test_staticweb) + self.assertEquals(resp.status_int, 404) + self.assert_('listing.css' in resp.body) + + def test_container_404_has_no_css(self): + resp = Request.blank('/v1/a/c7/').get_response( + self.test_staticweb) + self.assertEquals(resp.status_int, 404) + self.assert_('listing.css' not in resp.body) + self.assert_('