From 441389d1e1a6856894ed5d4f449631cde9af9254 Mon Sep 17 00:00:00 2001 From: Vika Date: Mon, 21 Feb 2022 22:48:11 +0300 Subject: Added stubs for Micropub posts and the media endpoint --- src/micropub/mod.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'src/micropub') diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs index dc74d6e..b81ac17 100644 --- a/src/micropub/mod.rs +++ b/src/micropub/mod.rs @@ -57,6 +57,82 @@ impl MicropubError { } } +pub mod media { + use futures_util::{Stream, StreamExt}; + use bytes::buf::Buf; + use warp::{Filter, Rejection, Reply, multipart::{FormData, Part}}; + + pub fn query() -> impl Filter + Clone { + warp::get() + .and(crate::util::require_host()) + .map(|host| "media endpoint query...") + } + + pub fn options() -> impl Filter + Clone { + warp::options() + .map(|| warp::reply::json::>(&None)) + // TODO: why doesn't this work? + // .map(warp::reply::with::header("Allow", "GET, POST")) + .map(|reply| warp::reply::with_header(reply, "Allow", "GET, POST")) + } + + pub fn upload() -> impl Filter + Clone { + warp::post() + .and(crate::util::require_host()) + .and(warp::multipart::form().max_length(1024*1024*150/*mb*/)) + .and_then(|host, mut form: FormData| async move { + // TODO get rid of the double unwrap() here + let file: Part = form.next().await.unwrap().unwrap(); + log::debug!("Uploaded: {:?}, type: {:?}", file.filename(), file.content_type()); + + let mut data = file.stream(); + while let Some(buf) = data.next().await { + // TODO save it into a file + log::debug!("buffer length: {:?}", buf.map(|b| b.remaining())); + } + Ok::<_, warp::Rejection>(warp::reply::with_header( + warp::reply::with_status( + "", + warp::http::StatusCode::CREATED + ), + "Location", + "./awoo.png" + )) + }) + } + + pub fn media() -> impl Filter + Clone { + upload() + .or(query()) + .or(options()) + } +} + +async fn _post(db: D, host: warp::host::Authority, user: crate::indieauth::User) -> impl warp::Reply { + todo!("post to database {:?} for host {:?} using user {:?}", db, host, user); + #[allow(unreachable_code)] + "" +} + +pub fn post(db: D, token_endpoint: String, http: hyper::Client) -> impl Filter + Clone +where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { + warp::post() + .map(move || db.clone()) + .and(crate::util::require_host()) + .and(crate::indieauth::require_token(token_endpoint, http)) + // TODO get body and process it + .then(_post) +} + +pub fn options() -> impl Filter + Copy { + warp::options() + // TODO make it reply with a basic description of Micropub spec + .map(|| warp::reply::json::>(&None)) + // TODO: why doesn't this work? + // .map(warp::reply::with::header("Allow", "GET, POST")) + .map(|reply| warp::reply::with_header(reply, "Allow", "GET, POST")) +} + async fn _query(db: D, host: warp::host::Authority, query: MicropubQuery, user: crate::indieauth::User) -> impl warp::Reply { let user_authority = warp::http::Uri::try_from(user.me.as_str()).unwrap().authority().unwrap().clone(); // TODO compare with potential list of allowed websites @@ -161,6 +237,13 @@ pub async fn recover(err: Rejection) -> Result { Ok(warp::reply::with_status(warp::reply::json(&error), error.into())) } +pub fn micropub(db: D, token_endpoint: String, http: hyper::Client) -> impl Filter + Clone +where T: hyper::client::connect::Connect + Clone + Send + Sync + 'static { + query(db.clone(), token_endpoint.clone(), http.clone()) + .or(post(db.clone(), token_endpoint.clone(), http.clone())) + .or(options()) + .recover(recover) +} #[cfg(test)] impl MicropubQuery { fn config() -> Self { @@ -178,7 +261,6 @@ impl MicropubQuery { } } - #[cfg(test)] mod tests { use hyper::body::HttpBody; -- cgit 1.4.1