Quoting attachment filename
Attachment file name was not surrounded by quotes. If an attachment was "picture of me.png", the browser was proposing to download a file named "picture". Change-Id: I17a1f8ca3b7ef44171c4977bacc9045e4695e18c Closes-bug: #1245927
This commit is contained in:
@@ -34,7 +34,7 @@ from openstack_dashboard.dashboards.project.containers import views
|
|||||||
from openstack_dashboard.test import helpers as test
|
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_2 = u"container_two\u6346"
|
||||||
CONTAINER_NAME_1_QUOTED = utils_http.urlquote(CONTAINER_NAME_1)
|
CONTAINER_NAME_1_QUOTED = utils_http.urlquote(CONTAINER_NAME_1)
|
||||||
CONTAINER_NAME_2_QUOTED = utils_http.urlquote(CONTAINER_NAME_2)
|
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', )})
|
@test.create_stubs({api.swift: ('swift_update_container', )})
|
||||||
def test_update_container_to_public(self):
|
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),
|
api.swift.swift_update_container(IsA(http.HttpRequest),
|
||||||
container.name,
|
container.name,
|
||||||
metadata=({'is_public': True}))
|
metadata=({'is_public': True}))
|
||||||
@@ -267,6 +267,14 @@ class SwiftTests(test.TestCase):
|
|||||||
res = self.client.get(download_url)
|
res = self.client.get(download_url)
|
||||||
self.assertEqual(res.content, obj.data)
|
self.assertEqual(res.content, obj.data)
|
||||||
self.assertTrue(res.has_header('Content-Disposition'))
|
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',)})
|
@test.create_stubs({api.swift: ('swift_get_containers',)})
|
||||||
def test_copy_index(self):
|
def test_copy_index(self):
|
||||||
|
@@ -216,7 +216,7 @@ def object_download(request, container_name, object_path):
|
|||||||
filename = "%s%s" % (filename, ext)
|
filename = "%s%s" % (filename, ext)
|
||||||
response = http.HttpResponse()
|
response = http.HttpResponse()
|
||||||
safe_name = filename.replace(",", "").encode('utf-8')
|
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['Content-Type'] = 'application/octet-stream'
|
||||||
response.write(obj.data)
|
response.write(obj.data)
|
||||||
return response
|
return response
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from django.utils import http as utils_http
|
||||||
|
|
||||||
from openstack_dashboard.api import swift
|
from openstack_dashboard.api import swift
|
||||||
from openstack_dashboard.openstack.common import timeutils
|
from openstack_dashboard.openstack.common import timeutils
|
||||||
|
|
||||||
@@ -22,26 +24,38 @@ def data(TEST):
|
|||||||
TEST.containers = utils.TestDataContainer()
|
TEST.containers = utils.TestDataContainer()
|
||||||
TEST.objects = utils.TestDataContainer()
|
TEST.objects = utils.TestDataContainer()
|
||||||
|
|
||||||
# '%' can break URL if not properly quoted (bug 1231904)
|
# '%' can break URL if not properly url-quoted
|
||||||
container_dict_1 = {"name": u"container_one%\u6346",
|
# ' ' (space) can break 'Content-Disposition' if not properly
|
||||||
|
# double-quoted
|
||||||
|
|
||||||
|
container_dict_1 = {"name": u"container one%\u6346",
|
||||||
"container_object_count": 2,
|
"container_object_count": 2,
|
||||||
"container_bytes_used": 256,
|
"container_bytes_used": 256,
|
||||||
"timestamp": timeutils.isotime(),
|
"timestamp": timeutils.isotime(),
|
||||||
"is_public": False,
|
"is_public": False,
|
||||||
"public_url": ""}
|
"public_url": ""}
|
||||||
container_1 = swift.Container(container_dict_1)
|
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_object_count": 4,
|
||||||
"container_bytes_used": 1024,
|
"container_bytes_used": 1024,
|
||||||
"timestamp": timeutils.isotime(),
|
"timestamp": timeutils.isotime(),
|
||||||
"is_public": True,
|
"is_public": True,
|
||||||
"public_url":
|
"public_url":
|
||||||
"http://public.swift.example.com:8080/" +
|
"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)
|
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",
|
"content_type": u"text/plain",
|
||||||
"bytes": 128,
|
"bytes": 128,
|
||||||
"timestamp": timeutils.isotime(),
|
"timestamp": timeutils.isotime(),
|
||||||
@@ -53,7 +67,13 @@ def data(TEST):
|
|||||||
"timestamp": timeutils.isotime(),
|
"timestamp": timeutils.isotime(),
|
||||||
"last_modified": None,
|
"last_modified": None,
|
||||||
"hash": u"object_hash_2"}
|
"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"
|
obj_data = "Fake Data"
|
||||||
|
|
||||||
for obj_dict in obj_dicts:
|
for obj_dict in obj_dicts:
|
||||||
|
Reference in New Issue
Block a user