1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-12-22 08:07:18 +00:00

Merge pull request #1452 from actix/fix/default-service-data

set data container on default service calls
This commit is contained in:
Yuki Okushi 2020-04-16 06:01:56 +09:00 committed by GitHub
commit 5b36381cb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 38 deletions

View file

@ -4,10 +4,12 @@
### Changed ### Changed
* `{Resource,Scope}::default_service(f)` handlers now support app data extraction. [#1452]
* Implement `std::error::Error` for our custom errors [#1422] * Implement `std::error::Error` for our custom errors [#1422]
* NormalizePath middleware now appends trailing / so that routes of form /example/ respond to /example requests. * NormalizePath middleware now appends trailing / so that routes of form /example/ respond to /example requests.
[#1422]: https://github.com/actix/actix-web/pull/1422 [#1422]: https://github.com/actix/actix-web/pull/1422
[#1452]: https://github.com/actix/actix-web/pull/1452
## [3.0.0-alpha.1] - 2020-03-11 ## [3.0.0-alpha.1] - 2020-03-11

View file

@ -542,6 +542,9 @@ impl Service for ResourceService {
} }
} }
if let Some(ref mut default) = self.default { if let Some(ref mut default) = self.default {
if let Some(ref data) = self.data {
req.set_data_container(data.clone());
}
Either::Right(default.call(req)) Either::Right(default.call(req))
} else { } else {
let req = req.into_parts().0; let req = req.into_parts().0;
@ -649,11 +652,9 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_to() { async fn test_to() {
let mut srv = let mut srv =
init_service(App::new().service(web::resource("/test").to(|| { init_service(App::new().service(web::resource("/test").to(|| async {
async { delay_for(Duration::from_millis(100)).await;
delay_for(Duration::from_millis(100)).await; Ok::<_, Error>(HttpResponse::Ok())
Ok::<_, Error>(HttpResponse::Ok())
}
}))) })))
.await; .await;
let req = TestRequest::with_uri("/test").to_request(); let req = TestRequest::with_uri("/test").to_request();
@ -793,4 +794,23 @@ mod tests {
let resp = call_service(&mut srv, req).await; let resp = call_service(&mut srv, req).await;
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
} }
#[actix_rt::test]
async fn test_data_default_service() {
let mut srv = init_service(
App::new().data(1usize).service(
web::resource("/test")
.data(10usize)
.default_service(web::to(|data: web::Data<usize>| {
assert_eq!(**data, 10);
HttpResponse::Ok()
})),
),
)
.await;
let req = TestRequest::get().uri("/test").to_request();
let resp = call_service(&mut srv, req).await;
assert_eq!(resp.status(), StatusCode::OK);
}
} }

View file

@ -54,7 +54,7 @@ type BoxedResponse = LocalBoxFuture<'static, Result<ServiceResponse, Error>>;
/// ``` /// ```
/// ///
/// In the above example three routes get registered: /// In the above example three routes get registered:
/// * /{project_id}/path1 - reponds to all http method /// * /{project_id}/path1 - responds to all http method
/// * /{project_id}/path2 - `GET` requests /// * /{project_id}/path2 - `GET` requests
/// * /{project_id}/path3 - `HEAD` requests /// * /{project_id}/path3 - `HEAD` requests
/// ///
@ -626,6 +626,9 @@ impl Service for ScopeService {
} }
Either::Left(srv.call(req)) Either::Left(srv.call(req))
} else if let Some(ref mut default) = self.default { } else if let Some(ref mut default) = self.default {
if let Some(ref data) = self.data {
req.set_data_container(data.clone());
}
Either::Left(default.call(req)) Either::Left(default.call(req))
} else { } else {
let req = req.into_parts().0; let req = req.into_parts().0;
@ -825,11 +828,9 @@ mod tests {
async fn test_scope_variable_segment() { async fn test_scope_variable_segment() {
let mut srv = let mut srv =
init_service(App::new().service(web::scope("/ab-{project}").service( init_service(App::new().service(web::scope("/ab-{project}").service(
web::resource("/path1").to(|r: HttpRequest| { web::resource("/path1").to(|r: HttpRequest| async move {
async move { HttpResponse::Ok()
HttpResponse::Ok() .body(format!("project: {}", &r.match_info()["project"]))
.body(format!("project: {}", &r.match_info()["project"]))
}
}), }),
))) )))
.await; .await;
@ -937,11 +938,9 @@ mod tests {
async fn test_nested_scope_with_variable_segment() { async fn test_nested_scope_with_variable_segment() {
let mut srv = init_service(App::new().service(web::scope("/app").service( let mut srv = init_service(App::new().service(web::scope("/app").service(
web::scope("/{project_id}").service(web::resource("/path1").to( web::scope("/{project_id}").service(web::resource("/path1").to(
|r: HttpRequest| { |r: HttpRequest| async move {
async move { HttpResponse::Created()
HttpResponse::Created() .body(format!("project: {}", &r.match_info()["project_id"]))
.body(format!("project: {}", &r.match_info()["project_id"]))
}
}, },
)), )),
))) )))
@ -964,14 +963,12 @@ mod tests {
async fn test_nested2_scope_with_variable_segment() { async fn test_nested2_scope_with_variable_segment() {
let mut srv = init_service(App::new().service(web::scope("/app").service( let mut srv = init_service(App::new().service(web::scope("/app").service(
web::scope("/{project}").service(web::scope("/{id}").service( web::scope("/{project}").service(web::scope("/{id}").service(
web::resource("/path1").to(|r: HttpRequest| { web::resource("/path1").to(|r: HttpRequest| async move {
async move { HttpResponse::Created().body(format!(
HttpResponse::Created().body(format!( "project: {} - {}",
"project: {} - {}", &r.match_info()["project"],
&r.match_info()["project"], &r.match_info()["id"],
&r.match_info()["id"], ))
))
}
}), }),
)), )),
))) )))
@ -1119,6 +1116,23 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
} }
#[actix_rt::test]
async fn test_override_data_default_service() {
let mut srv = init_service(App::new().data(1usize).service(
web::scope("app").data(10usize).default_service(web::to(
|data: web::Data<usize>| {
assert_eq!(**data, 10);
HttpResponse::Ok()
},
)),
))
.await;
let req = TestRequest::with_uri("/app/t").to_request();
let resp = call_service(&mut srv, req).await;
assert_eq!(resp.status(), StatusCode::OK);
}
#[actix_rt::test] #[actix_rt::test]
async fn test_override_app_data() { async fn test_override_app_data() {
let mut srv = init_service(App::new().app_data(web::Data::new(1usize)).service( let mut srv = init_service(App::new().app_data(web::Data::new(1usize)).service(
@ -1177,15 +1191,11 @@ mod tests {
); );
s.route( s.route(
"/", "/",
web::get().to(|req: HttpRequest| { web::get().to(|req: HttpRequest| async move {
async move { HttpResponse::Ok().body(format!(
HttpResponse::Ok().body(format!( "{}",
"{}", req.url_for("youtube", &["xxxxxx"]).unwrap().as_str()
req.url_for("youtube", &["xxxxxx"]) ))
.unwrap()
.as_str()
))
}
}), }),
); );
})); }));
@ -1203,11 +1213,9 @@ mod tests {
async fn test_url_for_nested() { async fn test_url_for_nested() {
let mut srv = init_service(App::new().service(web::scope("/a").service( let mut srv = init_service(App::new().service(web::scope("/a").service(
web::scope("/b").service(web::resource("/c/{stuff}").name("c").route( web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(
web::get().to(|req: HttpRequest| { web::get().to(|req: HttpRequest| async move {
async move { HttpResponse::Ok()
HttpResponse::Ok() .body(format!("{}", req.url_for("c", &["12345"]).unwrap()))
.body(format!("{}", req.url_for("c", &["12345"]).unwrap()))
}
}), }),
)), )),
))) )))