From 0d2db387a88bde5145f0ba746d82cd308738ff91 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Tue, 24 Aug 2021 20:27:06 +0200 Subject: [PATCH] Fix URI captures matching empty segments (#264) It was never the intention that `/:key` should match `/`. This fixes that. Part of https://github.com/tokio-rs/axum/issues/259 --- CHANGELOG.md | 3 ++- src/routing/mod.rs | 2 +- src/tests/mod.rs | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d312e172..94b24f1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased -- 👀 +- **fixed:** Fix URI captures matching empty segments. This means requests with + URI `/` will no longer be matched by `/:key` ([#264](https://github.com/tokio-rs/axum/pull/264)) # 0.2.1 (24. August, 2021) diff --git a/src/routing/mod.rs b/src/routing/mod.rs index 716a974d..641093cb 100644 --- a/src/routing/mod.rs +++ b/src/routing/mod.rs @@ -762,7 +762,7 @@ impl PathPattern { if let Some(key) = part.strip_prefix(':') { capture_group_names.push(Bytes::copy_from_slice(key.as_bytes())); - Cow::Owned(format!("(?P<{}>[^/]*)", key)) + Cow::Owned(format!("(?P<{}>[^/]+)", key)) } else { Cow::Borrowed(part) } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index aea1b288..81046942 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -672,6 +672,25 @@ async fn when_multiple_routes_match() { assert_eq!(res.status(), StatusCode::OK); } +#[tokio::test] +async fn captures_dont_match_empty_segments() { + let app = Router::new().route("/:key", get(|| async {})); + + let addr = run_in_background(app).await; + + let client = reqwest::Client::new(); + + let res = client.get(format!("http://{}", addr)).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::NOT_FOUND); + + let res = client + .get(format!("http://{}/foo", addr)) + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); +} + /// Run a `tower::Service` in the background and get a URI for it. pub(crate) async fn run_in_background(svc: S) -> SocketAddr where