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 {
);
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());
*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 {
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()?;