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<()> {
|
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 (mut writer, reader) = tokio::io::duplex(BUF_SIZE);
|
||||||
let filename = try_get_file_name(path)?;
|
let filename = try_get_file_name(path)?;
|
||||||
res.headers_mut().insert(
|
set_content_diposition(res, false, &format!("{}.zip", filename))?;
|
||||||
CONTENT_DISPOSITION,
|
|
||||||
HeaderValue::from_str(&format!(
|
|
||||||
"attachment; filename=\"{}.zip\"",
|
|
||||||
encode_uri(filename),
|
|
||||||
))?,
|
|
||||||
);
|
|
||||||
res.headers_mut()
|
res.headers_mut()
|
||||||
.insert("content-type", HeaderValue::from_static("application/zip"));
|
.insert("content-type", HeaderValue::from_static("application/zip"));
|
||||||
if head_only {
|
if head_only {
|
||||||
|
@ -644,10 +638,7 @@ impl Server {
|
||||||
);
|
);
|
||||||
|
|
||||||
let filename = try_get_file_name(path)?;
|
let filename = try_get_file_name(path)?;
|
||||||
res.headers_mut().insert(
|
set_content_diposition(res, true, filename)?;
|
||||||
CONTENT_DISPOSITION,
|
|
||||||
HeaderValue::from_str(&format!("inline; filename=\"{}\"", encode_uri(filename),))?,
|
|
||||||
);
|
|
||||||
|
|
||||||
res.headers_mut().typed_insert(AcceptRanges::bytes());
|
res.headers_mut().typed_insert(AcceptRanges::bytes());
|
||||||
|
|
||||||
|
@ -1359,6 +1350,21 @@ fn status_no_content(res: &mut Response) {
|
||||||
*res.status_mut() = StatusCode::NO_CONTENT;
|
*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 {
|
fn is_hidden(hidden: &[String], file_name: &str, is_dir_type: bool) -> bool {
|
||||||
hidden.iter().any(|v| {
|
hidden.iter().any(|v| {
|
||||||
if is_dir_type {
|
if is_dir_type {
|
||||||
|
|
|
@ -184,6 +184,17 @@ fn get_file_404(server: TestServer) -> Result<(), Error> {
|
||||||
Ok(())
|
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]
|
#[rstest]
|
||||||
fn get_file_edit(server: TestServer) -> Result<(), Error> {
|
fn get_file_edit(server: TestServer) -> Result<(), Error> {
|
||||||
let resp = fetch!(b"GET", format!("{}index.html?edit", server.url())).send()?;
|
let resp = fetch!(b"GET", format!("{}index.html?edit", server.url())).send()?;
|
||||||
|
|
Loading…
Reference in a new issue