diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/auth/openid.rs | 1 | ||||
-rw-r--r-- | src/modules/paths.rs | 30 |
2 files changed, 27 insertions, 4 deletions
diff --git a/src/modules/auth/openid.rs b/src/modules/auth/openid.rs index 7253ba8..1e5a063 100644 --- a/src/modules/auth/openid.rs +++ b/src/modules/auth/openid.rs @@ -43,6 +43,7 @@ pub struct OpenIDAuth { authorize_endpoint: String, token_endpoint: String, scope: String, + #[allow(unused)] next: DynNode, } diff --git a/src/modules/paths.rs b/src/modules/paths.rs index b994d48..8c6d0c5 100644 --- a/src/modules/paths.rs +++ b/src/modules/paths.rs @@ -1,7 +1,8 @@ use super::{Node, NodeContext, NodeKind, NodeRequest, NodeResponse}; use crate::{config::DynNode, error::ServiceError}; use futures::Future; -use regex::RegexSet; +use http::Uri; +use regex::{Regex, RegexSet}; use serde_yaml::Value; use std::{collections::BTreeMap, pin::Pin, sync::Arc}; @@ -9,6 +10,7 @@ pub struct PathsKind; struct Paths { matcher: RegexSet, + extractors: Vec<Regex>, handlers: Vec<DynNode>, } @@ -23,20 +25,27 @@ impl NodeKind for PathsKind { let mut handlers = Vec::new(); let mut patterns = Vec::new(); + let mut extractors = Vec::new(); for (k, v) in routes { + let pattern = format!("^{k}$"); handlers.push(v); - patterns.push(format!("^{}$", k)); + extractors.push(Regex::new(&pattern)?); + patterns.push(pattern); } let matcher = RegexSet::new(&patterns)?; - Ok(Arc::new(Paths { handlers, matcher })) + Ok(Arc::new(Paths { + handlers, + matcher, + extractors, + })) } } impl Node for Paths { fn handle<'a>( &'a self, context: &'a mut NodeContext, - request: NodeRequest, + mut request: NodeRequest, ) -> Pin<Box<dyn Future<Output = Result<NodeResponse, ServiceError>> + Send + Sync + 'a>> { Box::pin(async move { let path = request.uri().path(); @@ -48,6 +57,19 @@ impl Node for Paths { .next() .ok_or(ServiceError::UnknownPath)?; + let caps = self.extractors[index] + .captures(path) + .ok_or(ServiceError::Other)?; + + if let Some(rest) = caps.get(1) { + let mut parts = http::uri::Parts::default(); + parts.scheme = request.uri().scheme().cloned(); + parts.authority = request.uri().authority().cloned(); + parts.path_and_query = + Some(rest.as_str().parse().map_err(|_| ServiceError::Other)?); + *request.uri_mut() = Uri::from_parts(parts).map_err(|_| ServiceError::InvalidUri)? + } + self.handlers[index].handle(context, request).await }) } |