diff --git a/CHANGES.md b/CHANGES.md index 1175aa54..edf4380f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,9 @@ ### Fixed * Ensure `actix-http` dependency uses same `serde_urlencoded`. * Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`. +* Fix match_pattern() returning None for scope with resource of empty path. [#1798] + +[#1798]: https://github.com/actix/actix-web/pull/1798 ## 3.3.0 - 2020-11-25 diff --git a/src/request.rs b/src/request.rs index a1b42f92..bd4bbbf5 100644 --- a/src/request.rs +++ b/src/request.rs @@ -675,4 +675,40 @@ mod tests { let res = call_service(&mut srv, req).await; assert_eq!(res.status(), StatusCode::OK); } + + #[actix_rt::test] + async fn extract_path_pattern_complex() { + let mut srv = init_service( + App::new() + .service(web::scope("/user").service(web::scope("/{id}").service( + web::resource("").to(move |req: HttpRequest| { + assert_eq!(req.match_pattern(), Some("/user/{id}".to_owned())); + + HttpResponse::Ok().finish() + }), + ))) + .service(web::resource("/").to(move |req: HttpRequest| { + assert_eq!(req.match_pattern(), Some("/".to_owned())); + + HttpResponse::Ok().finish() + })) + .default_service(web::to(move |req: HttpRequest| { + assert!(req.match_pattern().is_none()); + HttpResponse::Ok().finish() + })), + ) + .await; + + let req = TestRequest::get().uri("/user/test").to_request(); + let res = call_service(&mut srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + + let req = TestRequest::get().uri("/").to_request(); + let res = call_service(&mut srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + + let req = TestRequest::get().uri("/not-exist").to_request(); + let res = call_service(&mut srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + } } diff --git a/src/rmap.rs b/src/rmap.rs index 05c1f3f1..6827a11b 100644 --- a/src/rmap.rs +++ b/src/rmap.rs @@ -86,7 +86,7 @@ impl ResourceMap { if let Some(plen) = pattern.is_prefix_match(path) { return rmap.has_resource(&path[plen..]); } - } else if pattern.is_match(path) { + } else if pattern.is_match(path) || pattern.pattern() == "" && path == "/" { return true; } }