- Published on
tower-http 和 axum 构建file server
- Authors
- Name
- Cupid Valentine
安装tower-http
cargo add tower-http --features compression-full --features cors --features trace --features fs
http_serve.rs
中使用
在我们主要使用tower_http
的 nest_service
方法定义一个嵌套的服务,路径为 "/tower",服务类型为 ServeDir::new(path)
,这样就可以了。
代码具体修改如下:
pub async fn process_http_serve(path: PathBuf, port: u16) -> Result<()> {
let addr = SocketAddr::from(([0, 0, 0, 0], port));
info!("Serving {:?} on port {}", path, port);
let state = HttpServeState { path:path.clone() };
// axum router
let router = Router::new()
.nest_service("/tower", ServeDir::new(path))
.route("/*path", get(file_handler))
.with_state(Arc::new(state));
let listener = tokio::net::TcpListener::bind(addr).await?;
axum::serve(listener, router).await?;
Ok(())
}
在test.http中进行测试
### test static file with tower-http
GET http://localhost:8080/tower/Cargo.toml
如图:
单元测试
在http_serve.rs
中添加如下代码:
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_file_handler() {
let state = Arc::new(HttpServeState {
path: PathBuf::from("."),
});
let (status, content) = file_handler(
State(state),
axum::extract::Path(Path("Cargo.toml").to_string()),
)
.await;
assert_eq!(status, StatusCode::OK);
assert!(content.trim().starts_with("[package]"));
}
}
这个测试用例的目的是验证 file_handler
函数能够正确处理指定的文件路径,并返回预期的状态码和文件内容。通过创建一个共享状态 HttpServeState
,并将其与文件路径一起传递给 file_handler
函数,测试用例模拟了实际的请求处理过程。
运行这个测试用例:
cargo nextest run -- test_file_handler
运行结果如下:
总结
本文主要通过Cargo添加了tower-http库的依赖,并启用了一些有用的特性。然后,在http_serve.rs
文件中,我们使用了nest_service
方法将一个ServeDir
服务嵌套到"/tower"路径下,实现了静态文件服务的功能。接着,我们在test.http
文件中编写了一个测试请求,验证了静态文件服务是否正常工作。最后,为了确保file_handler
函数的正确性,编写了一个单元测试用例,模拟了实际的请求处理过程,并断言了返回的状态码和文件内容。
Happy Coding!