actix_quick_extract/headers/
origin_or_host.rs1use actix_web::{http::header::ORIGIN, FromRequest};
2use derive_more::{AsRef, Deref, Display, Into};
3
4use super::HeaderType;
5use crate::ExtractError;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Display, Into, AsRef, Deref)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[display("{url}")]
20pub struct OriginOrHost {
21 #[into]
22 #[as_ref(str)]
23 #[deref(forward)]
24 pub url: String,
25 pub is_https: bool,
27}
28
29impl HeaderType for OriginOrHost {
30 #[inline]
31 fn from_request(req: &actix_web::HttpRequest) -> Result<Self, ExtractError> {
32 let (url, https) = if let Some(value) = req.headers().get(ORIGIN) {
33 value
34 .to_str()
35 .map(|value| (value.to_owned(), value.starts_with("https")))
36 .map_err(|v| ExtractError::ToStrError("Origin", v))?
37 } else if let Some(value) = req.headers().get(actix_web::http::header::HOST) {
38 value
39 .to_str()
40 .map(|value| (value.to_owned(), req.connection_info().scheme() == "https"))
41 .map_err(|v| ExtractError::ToStrError("Host", v))?
42 } else {
43 log::debug!("No Origin or Host Header Found");
44 return Err(ExtractError::MissingHeader("Origin or Host"));
45 };
46
47 Ok(OriginOrHost {
48 url,
49 is_https: https,
50 })
51 }
52}
53crate::ready_impl_from_request!(OriginOrHost as Header);