diff options
author | metamuffin <metamuffin@disroot.org> | 2024-06-22 13:05:21 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-06-22 13:05:21 +0200 |
commit | b28c5418b0635bf2fc3b0d18922df4ebb7cccd57 (patch) | |
tree | dbb99cde2eee412b1744bcc39827d31ce4e9606c /src/modules/redirect.rs | |
parent | 4da8fe84c07e3f9e83f9b769f1670f4d52466001 (diff) | |
download | gnix-b28c5418b0635bf2fc3b0d18922df4ebb7cccd57.tar gnix-b28c5418b0635bf2fc3b0d18922df4ebb7cccd57.tar.bz2 gnix-b28c5418b0635bf2fc3b0d18922df4ebb7cccd57.tar.zst |
add redirect modulev2.1.0
Diffstat (limited to 'src/modules/redirect.rs')
-rw-r--r-- | src/modules/redirect.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/modules/redirect.rs b/src/modules/redirect.rs new file mode 100644 index 0000000..e3fa599 --- /dev/null +++ b/src/modules/redirect.rs @@ -0,0 +1,50 @@ +use super::{Node, NodeContext, NodeKind, NodeRequest, NodeResponse}; +use crate::error::ServiceError; +use anyhow::Result; +use futures::Future; +use http_body_util::BodyExt; +use hyper::{header::HeaderValue, Response, StatusCode}; +use serde::Deserialize; +use std::{pin::Pin, sync::Arc}; + +pub struct RedirectKind; + +#[derive(Deserialize)] +pub struct Redirect(HeaderValueWrap); + +impl NodeKind for RedirectKind { + fn name(&self) -> &'static str { + "redirect" + } + fn instanciate(&self, config: serde_yaml::Value) -> Result<Arc<dyn Node>> { + Ok(Arc::new(serde_yaml::from_value::<Redirect>(config)?)) + } +} + +impl Node for Redirect { + fn handle<'a>( + &'a self, + _context: &'a mut NodeContext, + _request: NodeRequest, + ) -> Pin<Box<dyn Future<Output = Result<NodeResponse, ServiceError>> + Send + Sync + 'a>> { + Box::pin(async move { + let mut resp = Response::new("".to_string()).map(|b| b.map_err(|e| match e {}).boxed()); + *resp.status_mut() = StatusCode::MOVED_PERMANENTLY; + resp.headers_mut().insert("Location", self.0 .0.clone()); + Ok(resp) + }) + } +} + +struct HeaderValueWrap(HeaderValue); +impl<'de> Deserialize<'de> for HeaderValueWrap { + fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error> + where + D: serde::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + Ok(HeaderValueWrap( + HeaderValue::from_str(&s).map_err(|e| serde::de::Error::custom(format!("{e}")))?, + )) + } +} |