diff options
Diffstat (limited to 'src/web/http.rs')
-rw-r--r-- | src/web/http.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/web/http.rs b/src/web/http.rs new file mode 100644 index 0000000..7ab1b11 --- /dev/null +++ b/src/web/http.rs @@ -0,0 +1,50 @@ +use axum::{ + body::Body, + http::{header::HeaderName, HeaderValue, Request, StatusCode}, + response::{IntoResponse, Response}, +}; +use std::str; +use tower::ServiceExt; +use tower_http::services::ServeFile; + +pub fn text(code: u16, msg: &str) -> Response { + (status_code(code), msg.to_owned()).into_response() +} + +pub fn json(code: u16, json: &str) -> Response { + let mut res = (status_code(code), json.to_owned()).into_response(); + res.headers_mut().insert( + HeaderName::from_static("content-type"), + HeaderValue::from_static("application/json"), + ); + res +} + +pub async fn serve(path: &str) -> Response { + if !path.chars().any(|c| c == '.') { + return text(403, "Invalid file path"); + } + + let path = format!("public{path}"); + let file = ServeFile::new(path); + + let Ok(mut res) = file.oneshot(Request::new(Body::empty())).await else { + tracing::error!("Error while fetching file"); + return text(500, "Error when fetching file") + }; + + if res.status() != StatusCode::OK { + return text(404, "File not found"); + } + + res.headers_mut().insert( + HeaderName::from_static("cache-control"), + HeaderValue::from_static("max-age=300"), + ); + + res.into_response() +} + +fn status_code(code: u16) -> StatusCode { + StatusCode::from_u16(code).map_or(StatusCode::OK, |code| code) +} |