diff options
author | Vika <vika@fireburn.ru> | 2022-02-21 22:48:11 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2022-02-21 22:48:11 +0300 |
commit | 441389d1e1a6856894ed5d4f449631cde9af9254 (patch) | |
tree | 7ddf3e1ba3a33b06409e273c409628a3be39cf89 /src/micropub | |
parent | 55ba0a507bd310e3b04ac23e0311666968c2e1f1 (diff) | |
download | kittybox-441389d1e1a6856894ed5d4f449631cde9af9254.tar.zst |
Added stubs for Micropub posts and the media endpoint
Diffstat (limited to 'src/micropub')
-rw-r--r-- | src/micropub/mod.rs | 84 |
1 files changed, 83 insertions, 1 deletions
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<Extract = (impl Reply,), Error = Rejection> + Clone { + warp::get() + .and(crate::util::require_host()) + .map(|host| "media endpoint query...") + } + + pub fn options() -> impl Filter<Extract = (impl Reply,), Error = Rejection> + Clone { + warp::options() + .map(|| warp::reply::json::<Option<()>>(&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<Extract = (impl Reply,), Error = Rejection> + 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<Extract = (impl Reply,), Error = Rejection> + Clone { + upload() + .or(query()) + .or(options()) + } +} + +async fn _post<D: Storage>(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<D: Storage, T>(db: D, token_endpoint: String, http: hyper::Client<T, hyper::Body>) -> impl Filter<Extract = (impl warp::Reply,), Error = warp::Rejection> + 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<Extract = (impl warp::Reply,), Error = warp::Rejection> + Copy { + warp::options() + // TODO make it reply with a basic description of Micropub spec + .map(|| warp::reply::json::<Option<()>>(&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<D: Storage>(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<impl warp::Reply, Infallible> { Ok(warp::reply::with_status(warp::reply::json(&error), error.into())) } +pub fn micropub<D: Storage, T>(db: D, token_endpoint: String, http: hyper::Client<T, hyper::Body>) -> impl Filter<Extract = (impl warp::Reply,), Error = Infallible> + 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; |