1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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)
}
|