##// END OF EJS Templates
downlaods: properly encode " in the filenames, and add RFC 5987 header for non-ascii files.
marcink -
r3343:15b9bc69 stable
parent child Browse files
Show More
@@ -428,7 +428,7 b' class TestRawFileHandling(object):'
428 repo_name=backend.repo_name,
428 repo_name=backend.repo_name,
429 commit_id=commit.raw_id, f_path='vcs/nodes.py'),)
429 commit_id=commit.raw_id, f_path='vcs/nodes.py'),)
430
430
431 assert response.content_disposition == "attachment; filename=nodes.py"
431 assert response.content_disposition == 'attachment; filename="nodes.py"; filename*=UTF-8\'\'nodes.py'
432 assert response.content_type == "text/x-python"
432 assert response.content_type == "text/x-python"
433
433
434 def test_download_file_wrong_cs(self, backend):
434 def test_download_file_wrong_cs(self, backend):
@@ -24,6 +24,7 b' import os'
24 import shutil
24 import shutil
25 import tempfile
25 import tempfile
26 import collections
26 import collections
27 import urllib
27
28
28 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound
29 from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound
29 from pyramid.view import view_config
30 from pyramid.view import view_config
@@ -708,9 +709,14 b' class RepoFilesView(RepoAppView):'
708
709
709 return Response(html)
710 return Response(html)
710
711
711 def _get_attachement_disposition(self, f_path):
712 def _get_attachement_headers(self, f_path):
712 return 'attachment; filename=%s' % \
713 f_name = safe_str(f_path.split(Repository.NAME_SEP)[-1])
713 safe_str(f_path.split(Repository.NAME_SEP)[-1])
714 safe_path = f_name.replace('"', '\\"')
715 encoded_path = urllib.quote(f_name)
716
717 return "attachment; " \
718 "filename=\"{}\"; " \
719 "filename*=UTF-8\'\'{}".format(safe_path, encoded_path)
714
720
715 @LoginRequired()
721 @LoginRequired()
716 @HasRepoPermissionAnyDecorator(
722 @HasRepoPermissionAnyDecorator(
@@ -765,7 +771,7 b' class RepoFilesView(RepoAppView):'
765 mimetype, disposition = 'text/plain', 'inline'
771 mimetype, disposition = 'text/plain', 'inline'
766
772
767 if disposition == 'attachment':
773 if disposition == 'attachment':
768 disposition = self._get_attachement_disposition(f_path)
774 disposition = self._get_attachement_headers(f_path)
769
775
770 def stream_node():
776 def stream_node():
771 yield file_node.raw_bytes
777 yield file_node.raw_bytes
@@ -804,7 +810,7 b' class RepoFilesView(RepoAppView):'
804 # overwrite our pointer with the REAL large-file
810 # overwrite our pointer with the REAL large-file
805 file_node = lf_node
811 file_node = lf_node
806
812
807 disposition = self._get_attachement_disposition(f_path)
813 disposition = self._get_attachement_headers(f_path)
808
814
809 def stream_node():
815 def stream_node():
810 yield file_node.raw_bytes
816 yield file_node.raw_bytes
General Comments 0
You need to be logged in to leave comments. Login now