aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-06-22 12:30:13 +0200
committermetamuffin <metamuffin@disroot.org>2024-06-22 12:30:13 +0200
commit1451273fa59d14070e525562ec466a21128fa671 (patch)
treec3c83240b995173d13702a198f32afab5ea7c2be /src
parent9f4a1617fbd4d1f87a8bf6d882bdf739a08fb422 (diff)
downloadgnix-1451273fa59d14070e525562ec466a21128fa671.tar
gnix-1451273fa59d14070e525562ec466a21128fa671.tar.bz2
gnix-1451273fa59d14070e525562ec466a21128fa671.tar.zst
headers module
Diffstat (limited to 'src')
-rw-r--r--src/modules/headers.rs60
-rw-r--r--src/modules/mod.rs3
2 files changed, 63 insertions, 0 deletions
diff --git a/src/modules/headers.rs b/src/modules/headers.rs
new file mode 100644
index 0000000..b1e452e
--- /dev/null
+++ b/src/modules/headers.rs
@@ -0,0 +1,60 @@
+use super::{Node, NodeKind, NodeResponse};
+use crate::{config::DynNode, error::ServiceError};
+use anyhow::Result;
+use futures::Future;
+use hyper::{
+ header::{HeaderName, HeaderValue},
+ HeaderMap,
+};
+use serde::Deserialize;
+use std::{collections::BTreeMap, pin::Pin, str::FromStr, sync::Arc};
+
+pub struct HeadersKind;
+
+#[derive(Deserialize)]
+pub struct Headers {
+ headers: HeaderMapWrap,
+ inner: DynNode,
+}
+
+impl NodeKind for HeadersKind {
+ fn name(&self) -> &'static str {
+ "headers"
+ }
+ fn instanciate(&self, config: serde_yaml::Value) -> Result<Arc<dyn Node>> {
+ Ok(Arc::new(serde_yaml::from_value::<Headers>(config)?))
+ }
+}
+
+impl Node for Headers {
+ fn handle<'a>(
+ &'a self,
+ context: &'a mut super::NodeContext,
+ request: super::NodeRequest,
+ ) -> Pin<Box<dyn Future<Output = Result<NodeResponse, ServiceError>> + Send + Sync + 'a>> {
+ Box::pin(async move {
+ let mut resp = self.inner.handle(context, request).await?;
+ resp.headers_mut()
+ .extend(self.headers.0.clone().into_iter());
+ Ok(resp)
+ })
+ }
+}
+
+struct HeaderMapWrap(HeaderMap);
+impl<'de> Deserialize<'de> for HeaderMapWrap {
+ fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let headers = BTreeMap::<String, String>::deserialize(deserializer)?;
+ let mut hm = HeaderMap::new();
+ for (k, v) in headers {
+ hm.insert(
+ HeaderName::from_str(&k).map_err(|e| serde::de::Error::custom(format!("{e}")))?,
+ HeaderValue::from_str(&v).map_err(|e| serde::de::Error::custom(format!("{e}")))?,
+ );
+ }
+ Ok(HeaderMapWrap(hm))
+ }
+}
diff --git a/src/modules/mod.rs b/src/modules/mod.rs
index d96c24b..2e08142 100644
--- a/src/modules/mod.rs
+++ b/src/modules/mod.rs
@@ -7,6 +7,7 @@ use error::ErrorKind;
use file::FileKind;
use files::FilesKind;
use futures::Future;
+use headers::HeadersKind;
use hosts::HostsKind;
use http_body_util::combinators::BoxBody;
use hyper::{body::Incoming, Request, Response};
@@ -19,6 +20,7 @@ pub mod auth;
pub mod error;
pub mod file;
pub mod files;
+pub mod headers;
pub mod hosts;
pub mod proxy;
@@ -34,6 +36,7 @@ pub static MODULES: &[&dyn NodeKind] = &[
&FileKind,
&AccessLogKind,
&ErrorKind,
+ &HeadersKind,
];
pub struct NodeContext {