Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add /* matching to router. #885

Merged
merged 2 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions http/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

## Changed
- `h1::proto::context::Context::encode_headers` does not want `Extensions` type argument anymore. It also wants `&mut HeaderMap` instead of `HeaderMap` to avoid consuming ownership of it.
- update `xitca-router` to `0.2.0`
2 changes: 1 addition & 1 deletion http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ http_0dot2 = { package = "http", version = "0.2", optional = true }
tokio = { version = "1.30", features = ["rt", "time"], optional = true }

# util service support
xitca-router = { version = "0.1", optional = true }
xitca-router = { version = "0.2", optional = true }

# io-uring support
tokio-uring = { version = "0.4.0", features = ["bytes"], optional = true }
Expand Down
2 changes: 1 addition & 1 deletion http/src/util/service/router_priv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl<Obj> RouterGen for Router<Obj> {
})
.collect();

path.push_str("/:r");
path.push_str("/*");

Cow::Owned(path)
}
Expand Down
21 changes: 21 additions & 0 deletions router/CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
unreleased version 0.2

# Add
- add catch all matching for `/*`. It will match on `/*p` and `/`. This enables nesting `Router` types and other similar use case where the path matching is break up into separate segments between multiple scopes.

Example:
```rust
// a scoped router match against relative path of / and /login
let mut router_scope = xitca_router::Router::new();
router_scope.insert("/", true);
router_scope.insert("/login", true);

// add scoped router to root router where /users is used as
// prefix
let mut router = xitca_router::Router::new();
router.insert("/users/*", router_scope);

// handling /users as prefix and / and /login as suffix
assert!(m.at("/users/").is_ok());
assert!(m.at("/users/login").is_ok());
```
2 changes: 1 addition & 1 deletion router/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "xitca-router"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT"
description = "router for xitca"
Expand Down
15 changes: 13 additions & 2 deletions router/src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,17 @@ impl<T> Node<T> {
break;
}

// a non aggressive way to handle single * wildcard
if current.prefix == path {
if let Some(val) = current.children.first() {
if val.prefix == "*" {
if let Some(ref val) = val.value {
return Ok((val, params));
}
}
}
}

Err(MatchError)
}

Expand Down Expand Up @@ -507,8 +518,8 @@ fn normalize_params(mut path: Vec<u8>) -> Result<(Vec<u8>, ParamRemapping), Inse
None => return Ok((path, original)),
};

// makes sure the param has a valid name
if wildcard.len() < 2 {
// makes sure the param has a valid name unless it's * catch all
if wildcard.len() < 2 && wildcard.first().filter(|w| **w == b'*').is_none() {
return Err(InsertError::UnnamedParam);
}

Expand Down
2 changes: 1 addition & 1 deletion router/tests/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ insert_tests! {
"/user:" => Err(InsertError::UnnamedParam),
"/user:/" => Err(InsertError::UnnamedParam),
"/cmd/:/" => Err(InsertError::UnnamedParam),
"/src/*" => Err(InsertError::UnnamedParam),
// "/src/*" => Err(InsertError::UnnamedParam),
},
double_params {
"/:foo:bar" => Err(InsertError::TooManyParams),
Expand Down