actix_quick_extract/headers/
mod.rs1mod authorization;
10mod host;
11mod origin;
12mod origin_or_host;
13mod user_agent;
14use actix_web::FromRequest;
15#[doc(inline)]
16pub use authorization::RawAuthorization;
17use derive_more::Into;
18#[doc(inline)]
19pub use host::Host;
20#[doc(inline)]
21pub use origin::Origin;
22#[doc(inline)]
23pub use origin_or_host::OriginOrHost;
24#[doc(inline)]
25pub use user_agent::UserAgent;
26
27use crate::ExtractError;
28
29#[derive(Debug, Clone, PartialEq, Eq, Hash, Into)]
45#[repr(transparent)]
46pub struct AcceptNoneDenyBad<T: HeaderType>(pub Option<T>);
47
48pub trait HeaderType {
50 fn from_request(req: &actix_web::HttpRequest) -> Result<Self, crate::ExtractError>
51 where
52 Self: Sized;
53}
54
55impl<T: HeaderType> FromRequest for AcceptNoneDenyBad<T> {
56 type Error = ExtractError;
57 type Future = futures_util::future::Ready<Result<Self, crate::ExtractError>>;
58
59 fn from_request(req: &actix_web::HttpRequest, _: &mut actix_web::dev::Payload) -> Self::Future {
60 let result = <T>::from_request(req).map(|v| AcceptNoneDenyBad(Some(v)));
61 let result = if let Err(ExtractError::MissingHeader(_)) = &result {
62 Ok(AcceptNoneDenyBad(None))
63 } else {
64 result
65 };
66 futures_util::future::ready(result)
67 }
68}
69
70macro_rules! simple_header {
71 ($for_type:ty, $header:ident, $header_name:literal) => {
72 impl crate::headers::HeaderType for $for_type {
73 #[inline]
74 fn from_request(req: &actix_web::HttpRequest) -> Result<Self, crate::ExtractError> {
75 let header_value = if let Some(value) = req.headers().get($header) {
76 value
77 .to_str()
78 .map(|value| value.to_owned())
79 .map_err(|v| crate::ExtractError::ToStrError($header_name, v))?
80 } else {
81 log::debug!(concat!("No `", $header_name, "` Header Found"));
82 return Err(crate::ExtractError::MissingHeader($header_name));
83 };
84
85 Ok(<$for_type>::from(header_value))
86 }
87 }
88 crate::ready_impl_from_request!($for_type as Header);
89 };
90}
91
92pub(crate) use simple_header;