From fdf7e61b7f05e0db5ab08812dc322581960ff2fa Mon Sep 17 00:00:00 2001 From: Hung-I Wang Date: Sat, 2 Nov 2019 11:24:13 +0800 Subject: [PATCH] Improve Content-Disposition filename(*) parameters of actix_files::NamedFile --- actix-files/src/lib.rs | 25 +++++++++++++++++++++++++ actix-files/src/named.rs | 17 ++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 61674ca3..16f40a20 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -733,6 +733,31 @@ mod tests { assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none()); } + #[test] + fn test_named_file_non_ascii_file_name() { + let mut file = + NamedFile::from_file(File::open("Cargo.toml").unwrap(), "貨物.toml") + .unwrap(); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } + + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "text/x-toml" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "inline; filename=\"貨物.toml\"; filename*=UTF-8''%E8%B2%A8%E7%89%A9.toml" + ); + } + #[test] fn test_named_file_set_content_type() { let mut file = NamedFile::open("Cargo.toml") diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index d7c3fa88..955982ca 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -93,15 +93,18 @@ impl NamedFile { mime::IMAGE | mime::TEXT | mime::VIDEO => DispositionType::Inline, _ => DispositionType::Attachment, }; + let mut parameters = + vec![DispositionParam::Filename(String::from(filename.as_ref()))]; + if !filename.is_ascii() { + parameters.push(DispositionParam::FilenameExt(ExtendedValue { + charset: Charset::Ext(String::from("UTF-8")), + language_tag: None, + value: filename.into_owned().into_bytes(), + })) + } let cd = ContentDisposition { disposition: disposition_type, - parameters: vec![ - DispositionParam::FilenameExt(ExtendedValue { - charset: Charset::Ext(String::from("UTF-8")), - language_tag: None, - value: filename.as_bytes().to_vec(), - }), - ], + parameters: parameters, }; (ct, cd) };