summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-02-05 12:45:56 +0100
committermetamuffin <metamuffin@disroot.org>2025-02-05 12:45:56 +0100
commit27a503c1a92c8f8b0e398187d58e677ecf68e915 (patch)
tree505393926d7208dd3e5c9acd923f140b6a60259a /src/modules
parent65ceb5683340726ff2ee831181dd9d60da2456b3 (diff)
downloadgnix-27a503c1a92c8f8b0e398187d58e677ecf68e915.tar
gnix-27a503c1a92c8f8b0e398187d58e677ecf68e915.tar.bz2
gnix-27a503c1a92c8f8b0e398187d58e677ecf68e915.tar.zst
fallback handler
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/fallback.rs61
-rw-r--r--src/modules/mod.rs6
2 files changed, 65 insertions, 2 deletions
diff --git a/src/modules/fallback.rs b/src/modules/fallback.rs
new file mode 100644
index 0000000..b0deed1
--- /dev/null
+++ b/src/modules/fallback.rs
@@ -0,0 +1,61 @@
+use super::{Node, NodeContext, NodeKind, NodeRequest, NodeResponse};
+use crate::{config::DynNode, error::ServiceError};
+use anyhow::Result;
+use http::Request;
+use http_body_util::{combinators::BoxBody, BodyExt, Full};
+use serde::Deserialize;
+use serde_yml::Value;
+use std::{future::Future, pin::Pin, sync::Arc};
+
+pub struct FallbackKind;
+
+#[derive(Deserialize)]
+struct Fallback(Vec<DynNode>);
+
+impl NodeKind for FallbackKind {
+ fn name(&self) -> &'static str {
+ "fallback"
+ }
+ fn instanciate(&self, config: Value) -> Result<Arc<dyn Node>> {
+ Ok(Arc::new(serde_yml::from_value::<Fallback>(config)?))
+ }
+}
+impl Node for Fallback {
+ 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 (parts, body) = request.into_parts();
+ let body = body
+ .collect()
+ .await
+ .map_err(|_| ServiceError::Other)?
+ .to_bytes();
+
+ for (i, h) in self.0.iter().enumerate() {
+ let last = i == self.0.len() - 1;
+ let resp = h
+ .handle(
+ context,
+ Request::from_parts(
+ parts.clone(),
+ BoxBody::new(Full::new(body.clone()).map_err(|x| match x {})),
+ ),
+ )
+ .await?;
+ if resp.status().is_success()
+ || resp.status().is_redirection()
+ || resp.status().is_informational()
+ || last
+ {
+ return Ok(resp);
+ }
+ }
+ return Err(ServiceError::CustomStatic(
+ "fallback module without any handlers",
+ ));
+ })
+ }
+}
diff --git a/src/modules/mod.rs b/src/modules/mod.rs
index 6f945af..97dee1a 100644
--- a/src/modules/mod.rs
+++ b/src/modules/mod.rs
@@ -3,7 +3,7 @@ use crate::State;
use bytes::Bytes;
use futures::Future;
use http_body_util::combinators::BoxBody;
-use hyper::{body::Incoming, Request, Response};
+use hyper::{Request, Response};
use serde_yml::Value;
use std::{net::SocketAddr, pin::Pin, sync::Arc};
@@ -13,6 +13,7 @@ mod cache;
mod cgi;
mod debug;
mod error;
+pub mod fallback;
mod file;
mod files;
mod headers;
@@ -25,7 +26,7 @@ mod redirect;
mod switch;
mod upgrade_insecure;
-pub type NodeRequest = Request<Incoming>;
+pub type NodeRequest = Request<BoxBody<Bytes, hyper::Error>>;
pub type NodeResponse = Response<BoxBody<Bytes, ServiceError>>;
pub static MODULES: &[&dyn NodeKind] = &[
@@ -48,6 +49,7 @@ pub static MODULES: &[&dyn NodeKind] = &[
&loadbalance::LoadBalanceKind,
&upgrade_insecure::UpgradeInsecureKind,
&inspect::InspectKind,
+ &fallback::FallbackKind,
];
pub struct NodeContext {