Fix TSR redirecting to top-level inside nested Router (#2993)

Co-authored-by: David Mládek <david.mladek.cz@gmail.com>
This commit is contained in:
Erin 2024-10-17 16:43:14 +02:00 committed by GitHub
parent 65ad603701
commit 114369418d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 3 deletions

View file

@ -39,7 +39,7 @@ typed-header = ["dep:headers"]
typed-routing = ["dep:axum-macros", "dep:percent-encoding", "dep:serde_html_form", "dep:form_urlencoded"]
[dependencies]
axum = { path = "../axum", version = "0.8.0-alpha.1", default-features = false }
axum = { path = "../axum", version = "0.8.0-alpha.1", default-features = false, features = ["original-uri"] }
axum-core = { path = "../axum-core", version = "0.5.0-alpha.1" }
bytes = "1.1.0"
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }

View file

@ -1,7 +1,7 @@
//! Additional types for defining routes.
use axum::{
extract::Request,
extract::{OriginalUri, Request},
response::{IntoResponse, Redirect, Response},
routing::{any, MethodRouter},
Router,
@ -313,7 +313,7 @@ fn add_tsr_redirect_route<S>(router: Router<S>, path: &str) -> Router<S>
where
S: Clone + Send + Sync + 'static,
{
async fn redirect_handler(uri: Uri) -> Response {
async fn redirect_handler(OriginalUri(uri): OriginalUri) -> Response {
let new_uri = map_path(uri, |path| {
path.strip_suffix('/')
.map(Cow::Borrowed)
@ -432,6 +432,22 @@ mod tests {
assert_eq!(res.headers()["location"], "/foo?a=a");
}
#[tokio::test]
async fn tsr_works_in_nested_router() {
let app = Router::new().nest(
"/neko",
Router::new().route_with_tsr("/nyan/", get(|| async {})),
);
let client = TestClient::new(app);
let res = client.get("/neko/nyan/").await;
assert_eq!(res.status(), StatusCode::OK);
let res = client.get("/neko/nyan").await;
assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);
assert_eq!(res.headers()["location"], "/neko/nyan/");
}
#[test]
#[should_panic = "Cannot add a trailing slash redirect route for `/`"]
fn tsr_at_root() {