diff --git a/openstack_dashboard/dashboards/project/containers/tests.py b/openstack_dashboard/dashboards/project/containers/tests.py index 7daa1134fc..a368477e30 100644 --- a/openstack_dashboard/dashboards/project/containers/tests.py +++ b/openstack_dashboard/dashboards/project/containers/tests.py @@ -34,7 +34,7 @@ from openstack_dashboard.dashboards.project.containers import views from openstack_dashboard.test import helpers as test -CONTAINER_NAME_1 = u"container_one%\u6346" +CONTAINER_NAME_1 = u"container one%\u6346" CONTAINER_NAME_2 = u"container_two\u6346" CONTAINER_NAME_1_QUOTED = utils_http.urlquote(CONTAINER_NAME_1) CONTAINER_NAME_2_QUOTED = utils_http.urlquote(CONTAINER_NAME_2) @@ -114,7 +114,7 @@ class SwiftTests(test.TestCase): @test.create_stubs({api.swift: ('swift_update_container', )}) def test_update_container_to_public(self): - container = self.containers.get(name=u"container_one%\u6346") + container = self.containers.get(name=u"container one%\u6346") api.swift.swift_update_container(IsA(http.HttpRequest), container.name, metadata=({'is_public': True})) @@ -267,6 +267,14 @@ class SwiftTests(test.TestCase): res = self.client.get(download_url) self.assertEqual(res.content, obj.data) self.assertTrue(res.has_header('Content-Disposition')) + # Check that the returned Content-Disposition filename is well + # surrounded by double quotes and with commas removed + expected_name = '"%s"' % obj.name.replace( + ',', '').encode('utf-8') + self.assertEqual( + res.get('Content-Disposition'), + 'attachment; filename=%s' % expected_name + ) @test.create_stubs({api.swift: ('swift_get_containers',)}) def test_copy_index(self): diff --git a/openstack_dashboard/dashboards/project/containers/views.py b/openstack_dashboard/dashboards/project/containers/views.py index 97e7a136c5..06af0acb1e 100644 --- a/openstack_dashboard/dashboards/project/containers/views.py +++ b/openstack_dashboard/dashboards/project/containers/views.py @@ -216,7 +216,7 @@ def object_download(request, container_name, object_path): filename = "%s%s" % (filename, ext) response = http.HttpResponse() safe_name = filename.replace(",", "").encode('utf-8') - response['Content-Disposition'] = 'attachment; filename=%s' % safe_name + response['Content-Disposition'] = 'attachment; filename="%s"' % safe_name response['Content-Type'] = 'application/octet-stream' response.write(obj.data) return response diff --git a/openstack_dashboard/test/test_data/swift_data.py b/openstack_dashboard/test/test_data/swift_data.py index 9a651648a1..48d4a80ee1 100644 --- a/openstack_dashboard/test/test_data/swift_data.py +++ b/openstack_dashboard/test/test_data/swift_data.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +from django.utils import http as utils_http + from openstack_dashboard.api import swift from openstack_dashboard.openstack.common import timeutils @@ -22,26 +24,38 @@ def data(TEST): TEST.containers = utils.TestDataContainer() TEST.objects = utils.TestDataContainer() - # '%' can break URL if not properly quoted (bug 1231904) - container_dict_1 = {"name": u"container_one%\u6346", + # '%' can break URL if not properly url-quoted + # ' ' (space) can break 'Content-Disposition' if not properly + # double-quoted + + container_dict_1 = {"name": u"container one%\u6346", "container_object_count": 2, "container_bytes_used": 256, "timestamp": timeutils.isotime(), "is_public": False, "public_url": ""} container_1 = swift.Container(container_dict_1) - container_dict_2 = {"name": u"container_two\u6346", + container_2_name = u"container_two\u6346" + container_dict_2 = {"name": container_2_name, "container_object_count": 4, "container_bytes_used": 1024, "timestamp": timeutils.isotime(), "is_public": True, "public_url": "http://public.swift.example.com:8080/" + - "v1/project_id/container_two\u6346"} + "v1/project_id/%s" % utils_http.urlquote( + container_2_name)} container_2 = swift.Container(container_dict_2) - TEST.containers.add(container_1, container_2) + container_dict_3 = {"name": u"container,three%\u6346", + "container_object_count": 2, + "container_bytes_used": 256, + "timestamp": timeutils.isotime(), + "is_public": False, + "public_url": ""} + container_3 = swift.Container(container_dict_3) + TEST.containers.add(container_1, container_2, container_3) - object_dict = {"name": u"test_object%\u6346", + object_dict = {"name": u"test object%\u6346", "content_type": u"text/plain", "bytes": 128, "timestamp": timeutils.isotime(), @@ -53,7 +67,13 @@ def data(TEST): "timestamp": timeutils.isotime(), "last_modified": None, "hash": u"object_hash_2"} - obj_dicts = [object_dict, object_dict_2] + object_dict_3 = {"name": u"test,object_three%\u6346", + "content_type": u"text/plain", + "bytes": 128, + "timestamp": timeutils.isotime(), + "last_modified": None, + "hash": u"object_hash"} + obj_dicts = [object_dict, object_dict_2, object_dict_3] obj_data = "Fake Data" for obj_dict in obj_dicts: