aboutsummaryrefslogtreecommitdiff
path: root/src/utils/serve_static.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/serve_static.rs')
-rw-r--r--src/utils/serve_static.rs102
1 files changed, 44 insertions, 58 deletions
diff --git a/src/utils/serve_static.rs b/src/utils/serve_static.rs
index 2ec0a90..c087c21 100644
--- a/src/utils/serve_static.rs
+++ b/src/utils/serve_static.rs
@@ -1,75 +1,61 @@
use std::fs::File;
use std::io::{ErrorKind, Read};
use std::path::PathBuf;
-use std::rc::Rc;
use hyper::{Body, Request, Response, StatusCode};
-use rhai::{Dynamic, FnPtr, Map};
+
+use super::{async_trait, HttpHandler};
#[derive(Clone, Debug)]
pub struct Params {
root: PathBuf,
}
-#[derive(Debug)]
-pub struct KeyError(&'static str);
-
-impl TryFrom<Map> for Params {
- type Error = KeyError;
-
- fn try_from(mut value: Map) -> Result<Self, Self::Error> {
- let root = value
- .remove("root")
- .and_then(|value| value.into_immutable_string().ok())
- .ok_or(KeyError("root"))?;
- let root: PathBuf = root.parse().unwrap();
+impl Params {
+ pub fn new(root: PathBuf) -> Self {
let root = root.canonicalize().unwrap();
- Ok(Self { root })
+ Self { root }
}
}
-pub fn handle_request(params: &mut Params, request: Rc<Request<Body>>) -> Rc<Response<Body>> {
- let Params { root } = params;
- eprintln!("handling request {:?}", request);
- let request_path = request.uri().path();
- let request_path = request_path.trim_start_matches("/");
- let target = root.join(request_path);
- let target = if target.is_dir() {
- target.join("index.html")
- } else {
- target
- };
- eprintln!("target is {}", target.display());
- let response = if target.ancestors().all(|ancestor| ancestor != root) {
- // oops! all directory traversal
- Response::builder()
- .status(StatusCode::BAD_REQUEST)
- .body(Body::empty())
- } else {
- let file = File::open(target);
- match file {
- Ok(mut file) => {
- let mut result = Vec::new();
- file.read_to_end(&mut result).unwrap();
- Response::builder().body(Body::from(result))
- }
- Err(err) => {
- let status_code = match err.kind() {
- ErrorKind::NotFound => StatusCode::NOT_FOUND,
- _ => StatusCode::BAD_REQUEST,
- };
- Response::builder()
- .status(status_code)
- .body(Body::from(status_code.canonical_reason().unwrap_or("")))
+#[async_trait]
+impl HttpHandler for Params {
+ async fn handle(&self, request: Request<Body>) -> Response<Body> {
+ let Params { root } = self;
+ eprintln!("handling request {:?}", request);
+ let request_path = request.uri().path();
+ let request_path = request_path.trim_start_matches("/");
+ let target = root.join(request_path);
+ let target = if target.is_dir() {
+ target.join("index.html")
+ } else {
+ target
+ };
+ eprintln!("target is {}", target.display());
+ let response = if target.ancestors().all(|ancestor| ancestor != root) {
+ // oops! all directory traversal
+ Response::builder()
+ .status(StatusCode::BAD_REQUEST)
+ .body(Body::empty())
+ } else {
+ let file = File::open(target);
+ match file {
+ Ok(mut file) => {
+ let mut result = Vec::new();
+ file.read_to_end(&mut result).unwrap();
+ Response::builder().body(Body::from(result))
+ }
+ Err(err) => {
+ let status_code = match err.kind() {
+ ErrorKind::NotFound => StatusCode::NOT_FOUND,
+ _ => StatusCode::BAD_REQUEST,
+ };
+ Response::builder()
+ .status(status_code)
+ .body(Body::from(status_code.canonical_reason().unwrap_or("")))
+ }
}
- }
- };
- Rc::new(response.unwrap())
-}
-
-pub fn serve_static(params: Map) -> FnPtr {
- let params: Params = params.try_into().unwrap();
- let mut result = FnPtr::new("handle_request_serve_static").unwrap();
- result.add_curry(Dynamic::from(params));
- result
+ };
+ response.unwrap()
+ }
}