diff --git a/src/lib.rs b/src/lib.rs index edc8456ba..f771b1954 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,6 +82,7 @@ mod handler; mod info; pub mod middleware; mod request; +mod request_data; mod resource; mod responder; mod rmap; diff --git a/src/request_data.rs b/src/request_data.rs new file mode 100644 index 000000000..3eef9e07a --- /dev/null +++ b/src/request_data.rs @@ -0,0 +1,51 @@ +use std::ops::{Deref, DerefMut}; + +use actix_http::error::{Error, ErrorInternalServerError}; +use futures_util::future; + +use crate::{dev::Payload, FromRequest, HttpRequest}; + +/// Request data. +/// +/// Request data is a piece of arbitrary data attached to a request. +/// +/// It can be set via [`HttpMessage::extensions_mut`]. +/// +/// [`HttpMessage::extensions_mut`]: crate::HttpMessage::extensions_mut +#[derive(Clone, Debug)] +pub struct ReqData(pub T); + +impl Deref for ReqData { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl DerefMut for ReqData { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl FromRequest for ReqData { + type Config = (); + type Error = Error; + type Future = future::Ready>; + + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + if let Some(st) = req.extensions().get::() { + future::ok(ReqData(st.clone())) + } else { + log::debug!( + "Failed to construct App-level ReqData extractor. \ + Request path: {:?}", + req.path() + ); + future::err(ErrorInternalServerError( + "Missing expected request extension data", + )) + } + } +} diff --git a/src/web.rs b/src/web.rs index 1d1174f41..ee895f8e7 100644 --- a/src/web.rs +++ b/src/web.rs @@ -19,6 +19,7 @@ use crate::service::WebService; pub use crate::config::ServiceConfig; pub use crate::data::Data; pub use crate::request::HttpRequest; +pub use crate::request_data::ReqData; pub use crate::types::*; /// Create resource for a specific path.