From 45e2e401401fb62d69fa90424fda45962b1d4e5d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 14 Apr 2020 02:33:19 +0100 Subject: [PATCH 1/2] set data container on default service calls closes #1450 --- CHANGES.md | 2 ++ src/resource.rs | 30 ++++++++++++++++---- src/scope.rs | 74 +++++++++++++++++++++++++++---------------------- 3 files changed, 68 insertions(+), 38 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4a7862543..db2c8e8f5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,10 +4,12 @@ ### Changed +* `{Resource,Scope}::default_service(f)` handlers now support app data extraction. [#1452] * Implement `std::error::Error` for our custom errors [#1422] * NormalizePath middleware now appends trailing / so that routes of form /example/ respond to /example requests. [#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 diff --git a/src/resource.rs b/src/resource.rs index d03024a07..a4ab19052 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -542,6 +542,9 @@ impl Service for ResourceService { } } 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)) } else { let req = req.into_parts().0; @@ -649,11 +652,9 @@ mod tests { #[actix_rt::test] async fn test_to() { let mut srv = - init_service(App::new().service(web::resource("/test").to(|| { - async { - delay_for(Duration::from_millis(100)).await; - Ok::<_, Error>(HttpResponse::Ok()) - } + init_service(App::new().service(web::resource("/test").to(|| async { + delay_for(Duration::from_millis(100)).await; + Ok::<_, Error>(HttpResponse::Ok()) }))) .await; let req = TestRequest::with_uri("/test").to_request(); @@ -793,4 +794,23 @@ mod tests { let resp = call_service(&mut srv, req).await; 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| { + 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); + } } diff --git a/src/scope.rs b/src/scope.rs index 18e775e61..7ead71787 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -54,7 +54,7 @@ type BoxedResponse = LocalBoxFuture<'static, Result>; /// ``` /// /// 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}/path3 - `HEAD` requests /// @@ -626,6 +626,9 @@ impl Service for ScopeService { } Either::Left(srv.call(req)) } 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)) } else { let req = req.into_parts().0; @@ -825,11 +828,9 @@ mod tests { async fn test_scope_variable_segment() { let mut srv = init_service(App::new().service(web::scope("/ab-{project}").service( - web::resource("/path1").to(|r: HttpRequest| { - async move { - HttpResponse::Ok() - .body(format!("project: {}", &r.match_info()["project"])) - } + web::resource("/path1").to(|r: HttpRequest| async move { + HttpResponse::Ok() + .body(format!("project: {}", &r.match_info()["project"])) }), ))) .await; @@ -937,11 +938,9 @@ mod tests { async fn test_nested_scope_with_variable_segment() { let mut srv = init_service(App::new().service(web::scope("/app").service( web::scope("/{project_id}").service(web::resource("/path1").to( - |r: HttpRequest| { - async move { - HttpResponse::Created() - .body(format!("project: {}", &r.match_info()["project_id"])) - } + |r: HttpRequest| async move { + HttpResponse::Created() + .body(format!("project: {}", &r.match_info()["project_id"])) }, )), ))) @@ -964,14 +963,12 @@ mod tests { async fn test_nested2_scope_with_variable_segment() { let mut srv = init_service(App::new().service(web::scope("/app").service( web::scope("/{project}").service(web::scope("/{id}").service( - web::resource("/path1").to(|r: HttpRequest| { - async move { - HttpResponse::Created().body(format!( - "project: {} - {}", - &r.match_info()["project"], - &r.match_info()["id"], - )) - } + web::resource("/path1").to(|r: HttpRequest| async move { + HttpResponse::Created().body(format!( + "project: {} - {}", + &r.match_info()["project"], + &r.match_info()["id"], + )) }), )), ))) @@ -1119,6 +1116,23 @@ mod tests { 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| { + 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] async fn test_override_app_data() { let mut srv = init_service(App::new().app_data(web::Data::new(1usize)).service( @@ -1177,15 +1191,11 @@ mod tests { ); s.route( "/", - web::get().to(|req: HttpRequest| { - async move { - HttpResponse::Ok().body(format!( - "{}", - req.url_for("youtube", &["xxxxxx"]) - .unwrap() - .as_str() - )) - } + web::get().to(|req: HttpRequest| async move { + HttpResponse::Ok().body(format!( + "{}", + req.url_for("youtube", &["xxxxxx"]).unwrap().as_str() + )) }), ); })); @@ -1203,11 +1213,9 @@ mod tests { async fn test_url_for_nested() { let mut srv = init_service(App::new().service(web::scope("/a").service( web::scope("/b").service(web::resource("/c/{stuff}").name("c").route( - web::get().to(|req: HttpRequest| { - async move { - HttpResponse::Ok() - .body(format!("{}", req.url_for("c", &["12345"]).unwrap())) - } + web::get().to(|req: HttpRequest| async move { + HttpResponse::Ok() + .body(format!("{}", req.url_for("c", &["12345"]).unwrap())) }), )), ))) From 54619cb6802439a123d922fefb3578b68c8580cc Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Apr 2020 06:54:34 +0900 Subject: [PATCH 2/2] actix-http: Remove `failure` support (#1449) --- Cargo.toml | 4 +--- actix-http/CHANGES.md | 2 ++ actix-http/Cargo.toml | 8 +------- actix-http/src/error.rs | 6 +----- test-server/Cargo.toml | 2 +- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 84f876579..7a0bef858 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ members = [ ] [features] -default = ["compress", "failure"] +default = ["compress"] # content-encoding support compress = ["actix-http/compress", "awc/compress"] @@ -50,8 +50,6 @@ compress = ["actix-http/compress", "awc/compress"] # sessions feature, session require "ring" crate and c compiler secure-cookies = ["actix-http/secure-cookies"] -failure = ["actix-http/failure"] - # openssl openssl = ["actix-tls/openssl", "awc/openssl", "open-ssl"] diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 9d75e1a05..140d78e95 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -5,6 +5,8 @@ ### Changed * Implement `std::error::Error` for our custom errors [#1422] +* Remove `failure` support for `ResponseError` since that crate + will be deprecated in the near future. [#1422]: https://github.com/actix/actix-web/pull/1422 diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index e78c74624..fcb05dd37 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -15,7 +15,7 @@ license = "MIT/Apache-2.0" edition = "2018" [package.metadata.docs.rs] -features = ["openssl", "rustls", "failure", "compress", "secure-cookies","actors"] +features = ["openssl", "rustls", "compress", "secure-cookies", "actors"] [lib] name = "actix_http" @@ -33,9 +33,6 @@ rustls = ["actix-tls/rustls", "actix-connect/rustls"] # enable compressison support compress = ["flate2", "brotli2"] -# failure integration. actix does not use failure anymore -failure = ["fail-ure"] - # support for secure cookies secure-cookies = ["ring"] @@ -89,9 +86,6 @@ ring = { version = "0.16.9", optional = true } brotli2 = { version="0.3.2", optional = true } flate2 = { version = "1.0.13", optional = true } -# optional deps -fail-ure = { version = "0.1.5", package="failure", optional = true } - [dev-dependencies] actix-server = "1.0.1" actix-connect = { version = "2.0.0-alpha.2", features=["openssl"] } diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index 7ecdc6394..70cfa053f 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -34,7 +34,7 @@ pub type Result = result::Result; /// General purpose actix web error. /// -/// An actix web error is used to carry errors from `failure` or `std::error` +/// An actix web error is used to carry errors from `std::error` /// through actix in a convenient way. It can be created through /// converting errors with `into()`. /// @@ -950,10 +950,6 @@ where InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED).into() } -#[cfg(feature = "failure")] -/// Compatibility for `failure::Error` -impl ResponseError for fail_ure::Error {} - #[cfg(feature = "actors")] /// `InternalServerError` for `actix::MailboxError` /// This is supported on feature=`actors` only diff --git a/test-server/Cargo.toml b/test-server/Cargo.toml index 29896898e..97581585d 100644 --- a/test-server/Cargo.toml +++ b/test-server/Cargo.toml @@ -52,7 +52,7 @@ sha1 = "0.6" slab = "0.4" serde_urlencoded = "0.6.1" time = { version = "0.2.7", default-features = false, features = ["std"] } -open-ssl = { version="0.10", package="openssl", optional = true } +open-ssl = { version="0.10", package = "openssl", optional = true } [dev-dependencies] actix-web = "3.0.0-alpha.1"