fix: URL-encoded filename when downloading in safari (#203)
* fix: URL-encoded filename when downloading in safari * add test
This commit is contained in:
parent
e43554b795
commit
fb5b50f059
2 changed files with 28 additions and 11 deletions
|
@ -479,13 +479,7 @@ impl Server {
|
|||
async fn handle_zip_dir(&self, path: &Path, head_only: bool, res: &mut Response) -> Result<()> {
|
||||
let (mut writer, reader) = tokio::io::duplex(BUF_SIZE);
|
||||
let filename = try_get_file_name(path)?;
|
||||
res.headers_mut().insert(
|
||||
CONTENT_DISPOSITION,
|
||||
HeaderValue::from_str(&format!(
|
||||
"attachment; filename=\"{}.zip\"",
|
||||
encode_uri(filename),
|
||||
))?,
|
||||
);
|
||||
set_content_diposition(res, false, &format!("{}.zip", filename))?;
|
||||
res.headers_mut()
|
||||
.insert("content-type", HeaderValue::from_static("application/zip"));
|
||||
if head_only {
|
||||
|
@ -644,10 +638,7 @@ impl Server {
|
|||
);
|
||||
|
||||
let filename = try_get_file_name(path)?;
|
||||
res.headers_mut().insert(
|
||||
CONTENT_DISPOSITION,
|
||||
HeaderValue::from_str(&format!("inline; filename=\"{}\"", encode_uri(filename),))?,
|
||||
);
|
||||
set_content_diposition(res, true, filename)?;
|
||||
|
||||
res.headers_mut().typed_insert(AcceptRanges::bytes());
|
||||
|
||||
|
@ -1359,6 +1350,21 @@ fn status_no_content(res: &mut Response) {
|
|||
*res.status_mut() = StatusCode::NO_CONTENT;
|
||||
}
|
||||
|
||||
fn set_content_diposition(res: &mut Response, inline: bool, filename: &str) -> Result<()> {
|
||||
let kind = if inline { "inline" } else { "attachment" };
|
||||
let value = if filename.is_ascii() {
|
||||
HeaderValue::from_str(&format!("{kind}; filename=\"{}\"", filename,))?
|
||||
} else {
|
||||
HeaderValue::from_str(&format!(
|
||||
"{kind}; filename=\"{}\"; filename*=UTF-8''{}",
|
||||
filename,
|
||||
encode_uri(filename),
|
||||
))?
|
||||
};
|
||||
res.headers_mut().insert(CONTENT_DISPOSITION, value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_hidden(hidden: &[String], file_name: &str, is_dir_type: bool) -> bool {
|
||||
hidden.iter().any(|v| {
|
||||
if is_dir_type {
|
||||
|
|
|
@ -184,6 +184,17 @@ fn get_file_404(server: TestServer) -> Result<(), Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn get_file_emoji_path(server: TestServer) -> Result<(), Error> {
|
||||
let resp = reqwest::blocking::get(format!("{}{BIN_FILE}", server.url()))?;
|
||||
assert_eq!(resp.status(), 200);
|
||||
assert_eq!(
|
||||
resp.headers().get("content-disposition").unwrap(),
|
||||
"inline; filename=\"😀.bin\"; filename*=UTF-8''%F0%9F%98%80.bin"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn get_file_edit(server: TestServer) -> Result<(), Error> {
|
||||
let resp = fetch!(b"GET", format!("{}index.html?edit", server.url())).send()?;
|
||||
|
|
Loading…
Reference in a new issue