From ebbea875324d2d097b359f64d2a3fcb0f78ee56f Mon Sep 17 00:00:00 2001 From: blek Date: Sat, 4 Nov 2023 14:44:41 +1000 Subject: [PATCH] resource get method --- filed/src/config/resource/types.rs | 2 +- filed/src/web/mod.rs | 4 ++- filed/src/web/pages.rs | 12 ++++++++ filed/src/web/resource.rs | 49 ++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 filed/src/web/resource.rs diff --git a/filed/src/config/resource/types.rs b/filed/src/config/resource/types.rs index 407f75f..e48908f 100644 --- a/filed/src/config/resource/types.rs +++ b/filed/src/config/resource/types.rs @@ -74,7 +74,7 @@ impl Resource { Ok(()) } - pub fn get(self: &mut Self) -> Result, Box> { + pub fn get(self: &Self) -> Result, Box> { if let Some(cached) = self.cached_data.clone() { Ok(cached) } else { diff --git a/filed/src/web/mod.rs b/filed/src/web/mod.rs index bbc786d..ec2a1da 100644 --- a/filed/src/web/mod.rs +++ b/filed/src/web/mod.rs @@ -14,6 +14,7 @@ mod rejection; mod api; mod uploaded; mod curlapi; +mod resource; use state::SharedState; @@ -23,7 +24,8 @@ pub fn routes(state: SharedState) -> impl Filter } +impl ErrorPage { + pub fn not_found(state: SharedState) -> Self { + ErrorPage { + env: state.env, + conf: state.config, + error_text: "404 Not Found".into(), + link: Some("/".into()), + link_text: Some("Go back".into()) + } + } +} + #[derive(Template)] #[template( path = "curlapi_help.html" )] #[allow(dead_code)] diff --git a/filed/src/web/resource.rs b/filed/src/web/resource.rs new file mode 100644 index 0000000..73375bf --- /dev/null +++ b/filed/src/web/resource.rs @@ -0,0 +1,49 @@ +use askama::Template; +use warp::{Filter, reply::Reply, reject::Rejection}; +use warp::{reply::{with_status, with_header, html}, http::StatusCode}; + +use super::pages::ErrorPage; +use super::rejection::HttpReject; +use super::state::SharedState; + +fn not_found_res(state: SharedState) -> Result, Rejection> { + let nf = ErrorPage::not_found(state.clone()); + Ok( + Box::new( + with_status( + html(nf.render().map_err(|x| HttpReject::AskamaError(x))?), + StatusCode::NOT_FOUND + ) + ) + ) +} + +pub async fn get_resource((state, id): (SharedState, String)) -> Result, Rejection> { + if let Some(ref store) = state.config.resources { + if let Some(ref res) = store.get(id) { + Ok( + Box::new( + with_header( + res.get().map_err(|x| HttpReject::StringError(x.to_string()))?, + "Content-Type", + res.mime.clone() + ) + ) + ) + } else { + not_found_res(state) + } + } else { + not_found_res(state) + } +} + +pub fn get_filter(state: SharedState) -> impl Filter + Clone { + warp::path!("resource" / "get" / String) + .map(move |id| (state.clone(), id)) + .and_then(get_resource) +} + +pub fn get_routes(state: SharedState) -> impl Filter + Clone { + get_filter(state) +} \ No newline at end of file