From 63406de7ec1c1307921930d4e6ae75f0ecfc5121 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Mon, 29 Jul 2024 21:01:56 +0800 Subject: [PATCH] fix: fix issues with chinese directory. --- Cargo.toml | 3 ++- src/file_server.rs | 15 +++++++++------ src/main.rs | 5 ++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2cb6c11..a226c7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,5 @@ tokio = { version = "1", features = ["full"] } colored = "2" # 用于输出彩色日志 clap = "4.1" # 解析命令行参数 mime_guess = "2.0" # 用于猜测文件的 MIME 类型 -tokio-stream = { version = "0.1", features = ["fs"] } \ No newline at end of file +tokio-stream = { version = "0.1", features = ["fs"] } +percent-encoding = "2.1" # URL 编码 \ No newline at end of file diff --git a/src/file_server.rs b/src/file_server.rs index 4a4664d..4a19c8b 100644 --- a/src/file_server.rs +++ b/src/file_server.rs @@ -5,6 +5,7 @@ use warp::Reply; use std::sync::Arc; use tokio_stream::wrappers::ReadDirStream; use tokio_stream::StreamExt; +use percent_encoding::percent_decode_str; use mime_guess::mime; pub async fn serve_files( @@ -14,14 +15,16 @@ pub async fn serve_files( enable_cors: bool, ) -> Result { let path_str = path.as_str(); - - let full_path = Path::new(&**base_dir).join(path_str); - let full_path_clone = full_path.clone(); // 克隆 PathBuf + // 解码路径 + let decoded_path_str = percent_decode_str(path_str).decode_utf8_lossy(); + // 转换 Cow 为 &str + let decoded_path = decoded_path_str.as_ref(); + let full_path = Path::new(&**base_dir).join(decoded_path); + let full_path_clone = full_path.clone(); let response = if full_path.is_dir() { match fs::read_dir(full_path).await { Ok(entries) => { - let mut dir_stream = ReadDirStream::new(entries); let mut entries_vec: Vec<_> = Vec::new(); while let Some(entry) = dir_stream.next().await { @@ -30,10 +33,10 @@ pub async fn serve_files( Err(e) => eprintln!("Error reading entry: {}", e), } } - // Sort the entries entries_vec.sort_by(|a, b| a.file_name().cmp(&b.file_name())); - let relative_path: String = Path::new(path_str).to_str().unwrap_or(&base_dir).to_string(); + + let relative_path: String = Path::new(decoded_path).to_str().unwrap_or(&base_dir).to_string(); // 检查 relative_path 是否为空 let relative_path = if relative_path.is_empty() { diff --git a/src/main.rs b/src/main.rs index 8ea82b7..e0fe030 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use colored::Colorize; use warp::Filter; use warp::http::Method; use std::sync::Arc; +use percent_encoding::percent_decode_str; mod file_server; mod cli; @@ -37,11 +38,13 @@ async fn main() { let css_content_arc = css_content_arc.clone(); move |path: warp::path::Tail, method: Method| { if !no_request_logging { + // 解码路径 + let request_url = percent_decode_str(path.as_str()).decode_utf8_lossy(); // 打印请求方法 println!("{}: {} {}", " HTTP ".on_blue().white().bold(), method.to_string().green(), - if path.as_str().is_empty() { "/".green() } else { path.as_str().green() } + if path.as_str().is_empty() { "/".green() } else { request_url.to_string().green() } ); } file_server::serve_files(path, css_content_arc.clone(), base_dir.clone(), enable_cors.clone())