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 | |
parent | 4da8fe84c07e3f9e83f9b769f1670f4d52466001 (diff) | |
download | gnix-b28c5418b0635bf2fc3b0d18922df4ebb7cccd57.tar gnix-b28c5418b0635bf2fc3b0d18922df4ebb7cccd57.tar.bz2 gnix-b28c5418b0635bf2fc3b0d18922df4ebb7cccd57.tar.zst |
add redirect modulev2.1.0
-rw-r--r-- | readme.md | 4 | ||||
-rw-r--r-- | src/modules/mod.rs | 3 | ||||
-rw-r--r-- | src/modules/redirect.rs | 50 |
3 files changed, 57 insertions, 0 deletions
@@ -174,6 +174,10 @@ themselves; in that case the request is passed on. - `headers`: A map of all header name-value pairs. (object string:string) - `inner`: The handler to add the headers to. (module) +- **module `redirect`** + - Responds with a permanent redirect. + - Takes the location to redirect to. (string) + #### Credentials config format Login credentials for `cookie_auth` and `http_basic_auth` are supplied as either diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 0fe9ca0..00425bf 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -12,6 +12,7 @@ use hosts::HostsKind; use http_body_util::combinators::BoxBody; use hyper::{body::Incoming, Request, Response}; use proxy::ProxyKind; +use redirect::RedirectKind; use serde_yaml::Value; use std::{net::SocketAddr, pin::Pin, sync::Arc}; use switch::SwitchKind; @@ -24,6 +25,7 @@ pub mod files; pub mod headers; pub mod hosts; pub mod proxy; +pub mod redirect; pub mod switch; pub type NodeRequest = Request<Incoming>; @@ -40,6 +42,7 @@ pub static MODULES: &[&dyn NodeKind] = &[ &ErrorKind, &HeadersKind, &SwitchKind, + &RedirectKind, ]; pub struct NodeContext { 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}")))?, + )) + } +} |