use axum::{ async_trait, body::{Bytes, HttpBody}, extract::FromRequest, http::{Request, StatusCode}, response::{IntoResponse, Response}, }; use http::{HeaderMap, Method, Uri}; /// Handles incoming activities, verifying HTTP signatures and other checks pub mod inbox; /// Wrapper struct to respond with `application/activity+json` in axum handlers pub mod json; #[doc(hidden)] pub mod middleware; /// Contains everything that is necessary to verify HTTP signatures and receive an /// activity, including the request body. #[derive(Debug)] pub struct ActivityData { headers: HeaderMap, method: Method, uri: Uri, body: Vec, } #[async_trait] impl FromRequest for ActivityData where Bytes: FromRequest, B: HttpBody + Send + 'static, S: Send + Sync, ::Error: std::fmt::Display, ::Data: Send, { type Rejection = Response; async fn from_request(req: Request, _state: &S) -> Result { let (parts, body) = req.into_parts(); // this wont work if the body is an long running stream let bytes = hyper::body::to_bytes(body) .await .map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response())?; Ok(Self { headers: parts.headers, method: parts.method, uri: parts.uri, body: bytes.to_vec(), }) } }