summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/modules/auth/openid.rs1
-rw-r--r--src/modules/paths.rs30
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
})
}