Skip to content

Commit d288428

Browse files
committed
test(api): cover download filename headers
1 parent 0b699b3 commit d288428

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

test/services/test_controller_video.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,46 @@ def test_download_video_uses_resolved_file(self):
540540
self.assertEqual(response.filename, "final-1.mp4")
541541
self.assertEqual(response.media_type, "video/mp4")
542542

543+
def test_download_video_encodes_content_disposition_filename(self):
544+
"""
545+
下载文件名必须按 HTTP 标准编码。
546+
547+
普通 ASCII 文件名继续使用兼容性更好的 filename 参数;只要名称包含
548+
空格、中文或响应头敏感符号,就应改用 UTF-8 filename*,避免浏览器下载
549+
失败、文件名乱码,或特殊字符破坏 Content-Disposition 响应头结构。
550+
"""
551+
cases = (
552+
("final-1.mp4", 'attachment; filename="final-1.mp4"'),
553+
("video name.mp4", "attachment; filename*=utf-8''video%20name.mp4"),
554+
(
555+
"中文 视频.mp4",
556+
"attachment; filename*=utf-8''%E4%B8%AD%E6%96%87%20"
557+
"%E8%A7%86%E9%A2%91.mp4",
558+
),
559+
(
560+
'name="draft";v1\\test.mp4',
561+
"attachment; filename*=utf-8''name%3D%22draft%22%3Bv1%5Ctest.mp4",
562+
),
563+
)
564+
565+
with tempfile.TemporaryDirectory() as temp_dir:
566+
with patch.object(
567+
video_controller.utils,
568+
"task_dir",
569+
return_value=temp_dir,
570+
):
571+
for filename, expected_header in cases:
572+
with self.subTest(filename=filename):
573+
Path(temp_dir, filename).write_bytes(b"video")
574+
response = asyncio.run(
575+
video_controller.download_video(self._request(), filename)
576+
)
577+
578+
self.assertEqual(
579+
response.headers["content-disposition"],
580+
expected_header,
581+
)
582+
543583

544584
if __name__ == "__main__":
545585
unittest.main()

0 commit comments

Comments
 (0)