mirror of https://github.com/fafhrd91/actix-web
add scope test
This commit is contained in:
parent
1c394c803a
commit
e36d171f1e
|
@ -21,7 +21,7 @@ default = ["http"]
|
|||
|
||||
[dependencies]
|
||||
bytestring = ">=0.1.5, <2"
|
||||
firestorm = "0.4"
|
||||
firestorm = "0.5"
|
||||
http = { version = "0.2.3", optional = true }
|
||||
log = "0.4"
|
||||
regex = "1.5"
|
||||
|
@ -29,7 +29,7 @@ serde = "1"
|
|||
|
||||
[dev-dependencies]
|
||||
criterion = { version = "0.3", features = ["html_reports"] }
|
||||
firestorm = { version = "0.4", features = ["enable_system_time"] }
|
||||
firestorm = { version = "0.5", features = ["enable_system_time"] }
|
||||
http = "0.2.3"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
|
|
|
@ -104,11 +104,11 @@ const REGEX_FLAGS: &str = "(?s-m)";
|
|||
///
|
||||
///
|
||||
/// # Prefix Resources
|
||||
/// A prefix resource is defined as pattern that can match just the start of a path.
|
||||
/// A prefix resource is defined as pattern that can match just the start of a path, up to a
|
||||
/// segment boundary.
|
||||
///
|
||||
/// Prefix patterns with a trailing slash may have a weird, though correct, behavior.
|
||||
/// They basically define and require an empty segment to match.
|
||||
/// Examples are given below.
|
||||
/// Prefix patterns with a trailing slash may have an unexpected, though correct, behavior.
|
||||
/// They define and therefore require an empty segment in order to match. Examples are given below.
|
||||
///
|
||||
/// Empty pattern matches any path as a prefix.
|
||||
///
|
||||
|
@ -140,7 +140,7 @@ const REGEX_FLAGS: &str = "(?s-m)";
|
|||
/// `{name:regex}`. For example, `/user/{id:\d+}` will only match paths where the user ID
|
||||
/// is numeric.
|
||||
///
|
||||
/// The regex could pontentially match multiple segments. If this is not wanted, then care must be
|
||||
/// The regex could potentially match multiple segments. If this is not wanted, then care must be
|
||||
/// taken to avoid matching a slash `/`. It is guaranteed, however, that the match ends at a
|
||||
/// segment boundary; the pattern `r"(/|$)` is always appended to the regex.
|
||||
///
|
||||
|
@ -1104,10 +1104,12 @@ impl ResourceDef {
|
|||
let mut re = format!("({})", re);
|
||||
|
||||
// Ensure the match ends at a segment boundary
|
||||
if !is_prefix && !has_tail_segment {
|
||||
re.push('$');
|
||||
} else if is_prefix && !has_tail_segment {
|
||||
re.push_str(r"(/|$)");
|
||||
if !has_tail_segment {
|
||||
if is_prefix {
|
||||
re.push_str(r"(/|$)");
|
||||
} else {
|
||||
re.push('$');
|
||||
}
|
||||
}
|
||||
|
||||
let re = match Regex::new(&re) {
|
||||
|
|
66
src/scope.rs
66
src/scope.rs
|
@ -1153,4 +1153,70 @@ mod tests {
|
|||
Bytes::from_static(b"http://localhost:8080/a/b/c/12345")
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn dynamic_scopes() {
|
||||
let srv = init_service(
|
||||
App::new().service(
|
||||
web::scope("/{a}/").service(
|
||||
web::scope("/{b}/")
|
||||
.route("", web::get().to(|_: HttpRequest| HttpResponse::Created()))
|
||||
.route(
|
||||
"/",
|
||||
web::get().to(|_: HttpRequest| HttpResponse::Accepted()),
|
||||
)
|
||||
.route("/{c}", web::get().to(|_: HttpRequest| HttpResponse::Ok())),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
// note the unintuitive behavior with trailing slashes on scopes with dynamic segments
|
||||
let req = TestRequest::with_uri("/a//b//c").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let req = TestRequest::with_uri("/a//b/").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::CREATED);
|
||||
|
||||
let req = TestRequest::with_uri("/a//b//").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::ACCEPTED);
|
||||
|
||||
let req = TestRequest::with_uri("/a//b//c/d").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let srv = init_service(
|
||||
App::new().service(
|
||||
web::scope("/{a}").service(
|
||||
web::scope("/{b}")
|
||||
.route("", web::get().to(|_: HttpRequest| HttpResponse::Created()))
|
||||
.route(
|
||||
"/",
|
||||
web::get().to(|_: HttpRequest| HttpResponse::Accepted()),
|
||||
)
|
||||
.route("/{c}", web::get().to(|_: HttpRequest| HttpResponse::Ok())),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = TestRequest::with_uri("/a/b/c").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
let req = TestRequest::with_uri("/a/b").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::CREATED);
|
||||
|
||||
let req = TestRequest::with_uri("/a/b/").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::ACCEPTED);
|
||||
|
||||
let req = TestRequest::with_uri("/a/b/c/d").to_request();
|
||||
let resp = call_service(&srv, req).await;
|
||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue