add handle static file path

This commit is contained in:
xfy
2024-04-23 13:45:05 +08:00
parent 1d3e9a106b
commit 6a9125f759
3 changed files with 50 additions and 10 deletions

1
Cargo.lock generated
View File

@ -89,6 +89,7 @@ dependencies = [
"serde",
"thiserror",
"tokio",
"tokio-util",
"toml",
"tracing",
"tracing-subscriber",

View File

@ -23,6 +23,7 @@ toml = "0.8.12"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
futures-util = "0.3.30"
tokio-util = "0.7.10"
[profile.release]
lto = true

View File

@ -1,16 +1,17 @@
use std::pin::Pin;
use crate::error::{Error, Result};
use futures_util::Future;
use http_body_util::Full;
use futures_util::{Future, TryStreamExt};
use http_body_util::{combinators::BoxBody, BodyExt, Full, StreamBody};
use hyper::{
body::{Bytes, Incoming as IncomingBody},
body::{Bytes, Frame, Incoming as IncomingBody},
server::conn::http1,
service::Service,
Request, Response,
Request, Response, StatusCode,
};
use hyper_util::rt::TokioIo;
use tokio::net::TcpListener;
use tokio::{fs::File, net::TcpListener};
use tokio_util::io::ReaderStream;
use tracing::error;
use crate::config::SettingHost;
@ -39,7 +40,7 @@ impl SettingHost {
}
impl Service<Request<IncomingBody>> for SettingHost {
type Response = Response<Full<Bytes>>;
type Response = Response<Test<Bytes>>;
type Error = Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
@ -48,15 +49,52 @@ impl Service<Request<IncomingBody>> for SettingHost {
}
}
pub async fn mk_response(req: Request<IncomingBody>) -> Result<Response<Full<Bytes>>> {
pub async fn mk_response(req: Request<IncomingBody>) -> Result<Response<Test<Bytes>>> {
// let route = &self.route;
let req_path = req.uri().path();
let res = match req_path {
let req_method = req.method();
let res = match (req_method, req_path) {
// Return the 404 Not Found for other routes.
_ => "404",
_ => not_found(),
};
let res = Response::builder().body(Full::new(Bytes::from(res)))?;
Ok(res)
}
type Test<T, E = Error> = BoxBody<T, E>;
async fn handle_file(path: &str) -> Result<Response<Test<Bytes>>> {
// Open file for reading
let file = File::open(path).await;
let file = match file {
Ok(f) => f,
Err(err) => {
error!("Unable to open file {err}");
return Ok(not_found());
}
};
// Wrap to a tokio_util::io::ReaderStream
let reader_stream = ReaderStream::new(file);
// Convert to http_body_util::BoxBody
let stream_body = StreamBody::new(reader_stream.map_ok(Frame::data));
// let boxed_body = stream_body.map_err(|e| Error::IoError(e)).boxed();
let boxed_body = BodyExt::map_err(stream_body, Error::IoError).boxed();
// Send response
let response = Response::builder()
.status(StatusCode::OK)
.body(boxed_body)?;
Ok(response)
}
// HTTP status code 404
static NOT_FOUND: &[u8] = b"Not Found";
fn not_found() -> Response<Test<Bytes>> {
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Full::new(NOT_FOUND.into()).map_err(|e| match e {}).boxed())
.unwrap()
}