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]
|
[dependencies]
|
||||||
bytestring = ">=0.1.5, <2"
|
bytestring = ">=0.1.5, <2"
|
||||||
firestorm = "0.4"
|
firestorm = "0.5"
|
||||||
http = { version = "0.2.3", optional = true }
|
http = { version = "0.2.3", optional = true }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
regex = "1.5"
|
regex = "1.5"
|
||||||
|
@ -29,7 +29,7 @@ serde = "1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = { version = "0.3", features = ["html_reports"] }
|
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"
|
http = "0.2.3"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
|
|
|
@ -104,11 +104,11 @@ const REGEX_FLAGS: &str = "(?s-m)";
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// # Prefix Resources
|
/// # 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.
|
/// Prefix patterns with a trailing slash may have an unexpected, though correct, behavior.
|
||||||
/// They basically define and require an empty segment to match.
|
/// They define and therefore require an empty segment in order to match. Examples are given below.
|
||||||
/// Examples are given below.
|
|
||||||
///
|
///
|
||||||
/// Empty pattern matches any path as a prefix.
|
/// 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
|
/// `{name:regex}`. For example, `/user/{id:\d+}` will only match paths where the user ID
|
||||||
/// is numeric.
|
/// 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
|
/// 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.
|
/// segment boundary; the pattern `r"(/|$)` is always appended to the regex.
|
||||||
///
|
///
|
||||||
|
@ -1104,10 +1104,12 @@ impl ResourceDef {
|
||||||
let mut re = format!("({})", re);
|
let mut re = format!("({})", re);
|
||||||
|
|
||||||
// Ensure the match ends at a segment boundary
|
// Ensure the match ends at a segment boundary
|
||||||
if !is_prefix && !has_tail_segment {
|
if !has_tail_segment {
|
||||||
re.push('$');
|
if is_prefix {
|
||||||
} else if is_prefix && !has_tail_segment {
|
|
||||||
re.push_str(r"(/|$)");
|
re.push_str(r"(/|$)");
|
||||||
|
} else {
|
||||||
|
re.push('$');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let re = match Regex::new(&re) {
|
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")
|
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