From b28c5418b0635bf2fc3b0d18922df4ebb7cccd57 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 22 Jun 2024 13:05:21 +0200 Subject: add redirect module --- src/modules/redirect.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/modules/redirect.rs (limited to 'src/modules/redirect.rs') 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> { + Ok(Arc::new(serde_yaml::from_value::(config)?)) + } +} + +impl Node for Redirect { + fn handle<'a>( + &'a self, + _context: &'a mut NodeContext, + _request: NodeRequest, + ) -> Pin> + 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(deserializer: D) -> std::result::Result + 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}")))?, + )) + } +} -- cgit v1.2.3-70-g09d2