From ca85f6b245a4c80cea5ee35a4c3bb1955c7005b7 Mon Sep 17 00:00:00 2001 From: Andrey Kutejko Date: Sun, 21 Mar 2021 23:50:26 +0100 Subject: [PATCH] Update dependencies (Tokio 1.0) (#144) --- .github/workflows/msrv.yml | 2 +- actix-cors/CHANGES.md | 2 +- actix-cors/Cargo.toml | 6 +- actix-cors/README.md | 2 +- actix-cors/src/builder.rs | 28 +-- actix-cors/src/inner.rs | 42 ++-- actix-cors/src/middleware.rs | 33 ++- actix-cors/tests/tests.rs | 136 ++++++----- actix-identity/CHANGES.md | 1 + actix-identity/Cargo.toml | 10 +- actix-identity/src/lib.rs | 100 ++++---- actix-protobuf/CHANGES.md | 1 + actix-protobuf/Cargo.toml | 8 +- .../examples/prost-example/Cargo.toml | 8 +- actix-protobuf/src/lib.rs | 41 ++-- actix-redis/Cargo.toml | 26 +- actix-redis/examples/authentication.rs | 6 +- actix-redis/src/lib.rs | 8 +- actix-redis/src/redis.rs | 224 +++++++----------- actix-redis/src/session.rs | 70 +++--- actix-redis/tests/test_redis.rs | 37 +-- actix-session/CHANGES.md | 1 + actix-session/Cargo.toml | 6 +- actix-session/src/cookie.rs | 34 ++- actix-web-httpauth/CHANGES.md | 1 + actix-web-httpauth/Cargo.toml | 6 +- actix-web-httpauth/src/extractors/errors.rs | 2 +- .../src/headers/authorization/header.rs | 4 +- .../src/headers/authorization/scheme/basic.rs | 4 +- .../headers/authorization/scheme/bearer.rs | 4 +- .../www_authenticate/challenge/basic.rs | 8 +- .../challenge/bearer/challenge.rs | 4 +- .../src/headers/www_authenticate/header.rs | 4 +- actix-web-httpauth/src/middleware.rs | 63 ++--- 34 files changed, 429 insertions(+), 503 deletions(-) diff --git a/.github/workflows/msrv.yml b/.github/workflows/msrv.yml index d2fd7d4da..0edfe4f53 100644 --- a/.github/workflows/msrv.yml +++ b/.github/workflows/msrv.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: version: - - 1.42.0 + - 1.46.0 name: ${{ matrix.version }} - x86_64-unknown-linux-gnu runs-on: ubuntu-latest diff --git a/actix-cors/CHANGES.md b/actix-cors/CHANGES.md index 7b7f3eddc..ba77d9185 100644 --- a/actix-cors/CHANGES.md +++ b/actix-cors/CHANGES.md @@ -1,7 +1,7 @@ # Changes ## Unreleased - 2021-xx-xx - +* Minimum supported Rust version (MSRV) is now 1.46.0. ## 0.5.4 - 2020-12-31 diff --git a/actix-cors/Cargo.toml b/actix-cors/Cargo.toml index 6ac9a7560..6494ce84d 100644 --- a/actix-cors/Cargo.toml +++ b/actix-cors/Cargo.toml @@ -19,7 +19,7 @@ name = "actix_cors" path = "src/lib.rs" [dependencies] -actix-web = { version = "3.0.0", default-features = false } +actix-web = { version = "4.0.0-beta.4", default-features = false } derive_more = "0.99.5" futures-util = { version = "0.3.7", default-features = false } log = "0.4" @@ -27,7 +27,7 @@ once_cell = "1" tinyvec = { version = "1", features = ["alloc"] } [dev-dependencies] -actix-service = "1" -actix-rt = "1" +actix-service = "2.0.0-beta.5" +actix-rt = "2" pretty_env_logger = "0.4" regex = "1.4" diff --git a/actix-cors/README.md b/actix-cors/README.md index 68bda566c..72f243b2c 100644 --- a/actix-cors/README.md +++ b/actix-cors/README.md @@ -12,4 +12,4 @@ - [API Documentation](https://docs.rs/actix-cors) - [Example Project](https://github.com/actix/examples/tree/master/security/web-cors) - [Chat on Gitter](https://gitter.im/actix/actix-web) -- Minimum Supported Rust Version (MSRV): 1.42.0 +- Minimum Supported Rust Version (MSRV): 1.46.0 diff --git a/actix-cors/src/builder.rs b/actix-cors/src/builder.rs index f9bce3d21..c66b7307f 100644 --- a/actix-cors/src/builder.rs +++ b/actix-cors/src/builder.rs @@ -145,7 +145,7 @@ impl Cors { match TryInto::::try_into(origin) { Ok(_) if origin == "*" => { error!("Wildcard in `allowed_origin` is not allowed. Use `send_wildcard`."); - self.error = Some(Either::B(CorsError::WildcardOrigin)); + self.error = Some(Either::Right(CorsError::WildcardOrigin)); } Ok(_) => { @@ -162,7 +162,7 @@ impl Cors { } Err(err) => { - self.error = Some(Either::A(err.into())); + self.error = Some(Either::Left(err.into())); } } } @@ -224,7 +224,7 @@ impl Cors { } Err(err) => { - self.error = Some(Either::A(err.into())); + self.error = Some(Either::Left(err.into())); break; } } @@ -266,7 +266,7 @@ impl Cors { } } - Err(err) => self.error = Some(Either::A(err.into())), + Err(err) => self.error = Some(Either::Left(err.into())), } } @@ -303,7 +303,7 @@ impl Cors { } } Err(err) => { - self.error = Some(Either::A(err.into())); + self.error = Some(Either::Left(err.into())); break; } } @@ -351,7 +351,7 @@ impl Cors { } } Err(err) => { - self.error = Some(Either::A(err.into())); + self.error = Some(Either::Left(err.into())); break; } } @@ -483,13 +483,12 @@ impl Default for Cors { } } -impl Transform for Cors +impl Transform for Cors where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); @@ -499,8 +498,8 @@ where fn new_transform(&self, service: S) -> Self::Future { if let Some(ref err) = self.error { match err { - Either::A(err) => error!("{}", err), - Either::B(err) => error!("{}", err), + Either::Left(err) => error!("{}", err), + Either::Right(err) => error!("{}", err), } return future::err(()); @@ -592,15 +591,16 @@ mod test { #[actix_rt::test] async fn restrictive_defaults() { - let mut cors = Cors::default() + let cors = Cors::default() .new_transform(test::ok_service()) .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") + let req = TestRequest::default() + .insert_header(("Origin", "https://www.example.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!(resp.status(), StatusCode::BAD_REQUEST); } diff --git a/actix-cors/src/inner.rs b/actix-cors/src/inner.rs index ee81ff14b..d44461630 100644 --- a/actix-cors/src/inner.rs +++ b/actix-cors/src/inner.rs @@ -235,8 +235,8 @@ mod test { .unwrap(); let req = TestRequest::get() - .header(header::ORIGIN, "https://www.unknown.com") - .header(header::ACCESS_CONTROL_REQUEST_HEADERS, "DNT") + .insert_header((header::ORIGIN, "https://www.unknown.com")) + .insert_header((header::ACCESS_CONTROL_REQUEST_HEADERS, "DNT")) .to_srv_request(); assert!(cors.inner.validate_origin(req.head()).is_err()); @@ -257,34 +257,37 @@ mod test { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") + let req = TestRequest::default() .method(Method::OPTIONS) - .header(header::ACCESS_CONTROL_REQUEST_HEADERS, "X-Not-Allowed") + .insert_header(("Origin", "https://www.example.com")) + .insert_header((header::ACCESS_CONTROL_REQUEST_HEADERS, "X-Not-Allowed")) .to_srv_request(); assert!(cors.inner.validate_allowed_method(req.head()).is_err()); assert!(cors.inner.validate_allowed_headers(req.head()).is_err()); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "put") + let req = TestRequest::default() .method(Method::OPTIONS) + .insert_header(("Origin", "https://www.example.com")) + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "put")) .to_srv_request(); assert!(cors.inner.validate_allowed_method(req.head()).is_err()); assert!(cors.inner.validate_allowed_headers(req.head()).is_ok()); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") - .header( + let req = TestRequest::default() + .method(Method::OPTIONS) + .insert_header(("Origin", "https://www.example.com")) + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST")) + .insert_header(( header::ACCESS_CONTROL_REQUEST_HEADERS, "AUTHORIZATION,ACCEPT", - ) - .method(Method::OPTIONS) + )) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"*"[..]), resp.headers() @@ -319,16 +322,17 @@ mod test { Rc::get_mut(&mut cors.inner).unwrap().preflight = false; - let req = TestRequest::with_header("Origin", "https://www.example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") - .header( + let req = TestRequest::default() + .method(Method::OPTIONS) + .insert_header(("Origin", "https://www.example.com")) + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST")) + .insert_header(( header::ACCESS_CONTROL_REQUEST_HEADERS, "AUTHORIZATION,ACCEPT", - ) - .method(Method::OPTIONS) + )) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!(resp.status(), StatusCode::OK); } } diff --git a/actix-cors/src/middleware.rs b/actix-cors/src/middleware.rs index 8bd9f89b3..49b4df375 100644 --- a/actix-cors/src/middleware.rs +++ b/actix-cors/src/middleware.rs @@ -42,34 +42,34 @@ impl CorsMiddleware { let mut res = HttpResponse::Ok(); if let Some(origin) = inner.access_control_allow_origin(req.head()) { - res.header(header::ACCESS_CONTROL_ALLOW_ORIGIN, origin); + res.insert_header((header::ACCESS_CONTROL_ALLOW_ORIGIN, origin)); } if let Some(ref allowed_methods) = inner.allowed_methods_baked { - res.header( + res.insert_header(( header::ACCESS_CONTROL_ALLOW_METHODS, allowed_methods.clone(), - ); + )); } if let Some(ref headers) = inner.allowed_headers_baked { - res.header(header::ACCESS_CONTROL_ALLOW_HEADERS, headers.clone()); + res.insert_header((header::ACCESS_CONTROL_ALLOW_HEADERS, headers.clone())); } else if let Some(headers) = req.headers().get(header::ACCESS_CONTROL_REQUEST_HEADERS) { // all headers allowed, return - res.header(header::ACCESS_CONTROL_ALLOW_HEADERS, headers.clone()); + res.insert_header((header::ACCESS_CONTROL_ALLOW_HEADERS, headers.clone())); } if inner.supports_credentials { - res.header( + res.insert_header(( header::ACCESS_CONTROL_ALLOW_CREDENTIALS, HeaderValue::from_static("true"), - ); + )); } if let Some(max_age) = inner.max_age { - res.header(header::ACCESS_CONTROL_MAX_AGE, max_age.to_string()); + res.insert_header((header::ACCESS_CONTROL_MAX_AGE, max_age.to_string())); } let res = res.finish(); @@ -121,22 +121,21 @@ type CorsMiddlewareServiceFuture = Either< LocalBoxFuture<'static, Result, Error>>, >; -impl Service for CorsMiddleware +impl Service for CorsMiddleware where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = CorsMiddlewareServiceFuture; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { self.service.poll_ready(cx) } - fn call(&mut self, req: ServiceRequest) -> Self::Future { + fn call(&self, req: ServiceRequest) -> Self::Future { if self.inner.preflight && req.method() == Method::OPTIONS { let inner = Rc::clone(&self.inner); let res = Self::handle_preflight(&inner, req); @@ -187,7 +186,7 @@ mod tests { // Tests case where allowed_origins is All but there are validate functions to run incase. // In this case, origins are only allowed when the DNT header is sent. - let mut cors = Cors::default() + let cors = Cors::default() .allow_any_origin() .allowed_origin_fn(|origin, req_head| { assert_eq!(&origin, req_head.headers.get(header::ORIGIN).unwrap()); @@ -199,7 +198,7 @@ mod tests { .unwrap(); let req = TestRequest::get() - .header(header::ORIGIN, "http://example.com") + .insert_header((header::ORIGIN, "http://example.com")) .to_srv_request(); let res = cors.call(req).await.unwrap(); assert_eq!( @@ -210,8 +209,8 @@ mod tests { ); let req = TestRequest::get() - .header(header::ORIGIN, "http://example.com") - .header(header::DNT, "1") + .insert_header((header::ORIGIN, "http://example.com")) + .insert_header((header::DNT, "1")) .to_srv_request(); let res = cors.call(req).await.unwrap(); assert_eq!( diff --git a/actix-cors/tests/tests.rs b/actix-cors/tests/tests.rs index 594102a41..996f8ece9 100644 --- a/actix-cors/tests/tests.rs +++ b/actix-cors/tests/tests.rs @@ -26,7 +26,7 @@ async fn test_wildcard_origin() { #[actix_rt::test] async fn test_not_allowed_origin_fn() { - let mut cors = Cors::default() + let cors = Cors::default() .allowed_origin("https://www.example.com") .allowed_origin_fn(|origin, req| { assert_eq!(&origin, req.headers.get(header::ORIGIN).unwrap()); @@ -42,11 +42,11 @@ async fn test_not_allowed_origin_fn() { .unwrap(); { - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.example.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://www.example.com"[..]), @@ -57,11 +57,11 @@ async fn test_not_allowed_origin_fn() { } { - let req = TestRequest::with_header("Origin", "https://www.known.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.known.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( None, @@ -72,7 +72,7 @@ async fn test_not_allowed_origin_fn() { #[actix_rt::test] async fn test_allowed_origin_fn() { - let mut cors = Cors::default() + let cors = Cors::default() .allowed_origin("https://www.example.com") .allowed_origin_fn(|origin, req| { assert_eq!(&origin, req.headers.get(header::ORIGIN).unwrap()); @@ -87,11 +87,11 @@ async fn test_allowed_origin_fn() { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.example.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( "https://www.example.com", @@ -101,11 +101,11 @@ async fn test_allowed_origin_fn() { .unwrap() ); - let req = TestRequest::with_header("Origin", "https://www.unknown.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.unknown.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://www.unknown.com"[..]), @@ -119,7 +119,7 @@ async fn test_allowed_origin_fn() { async fn test_allowed_origin_fn_with_environment() { let regex = Regex::new("https:.+\\.unknown\\.com").unwrap(); - let mut cors = Cors::default() + let cors = Cors::default() .allowed_origin("https://www.example.com") .allowed_origin_fn(move |origin, req| { assert_eq!(&origin, req.headers.get(header::ORIGIN).unwrap()); @@ -134,11 +134,11 @@ async fn test_allowed_origin_fn_with_environment() { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.example.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( "https://www.example.com", @@ -148,11 +148,11 @@ async fn test_allowed_origin_fn_with_environment() { .unwrap() ); - let req = TestRequest::with_header("Origin", "https://www.unknown.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.unknown.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://www.unknown.com"[..]), @@ -164,7 +164,7 @@ async fn test_allowed_origin_fn_with_environment() { #[actix_rt::test] async fn test_multiple_origins_preflight() { - let mut cors = Cors::default() + let cors = Cors::default() .allowed_origin("https://example.com") .allowed_origin("https://example.org") .allowed_methods(vec![Method::GET]) @@ -172,12 +172,13 @@ async fn test_multiple_origins_preflight() { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET") + let req = TestRequest::default() + .insert_header(("Origin", "https://example.com")) + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "GET")) .method(Method::OPTIONS) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://example.com"[..]), resp.headers() @@ -185,12 +186,13 @@ async fn test_multiple_origins_preflight() { .map(HeaderValue::as_bytes) ); - let req = TestRequest::with_header("Origin", "https://example.org") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET") + let req = TestRequest::default() + .insert_header(("Origin", "https://example.org")) + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "GET")) .method(Method::OPTIONS) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://example.org"[..]), resp.headers() @@ -201,7 +203,7 @@ async fn test_multiple_origins_preflight() { #[actix_rt::test] async fn test_multiple_origins() { - let mut cors = Cors::default() + let cors = Cors::default() .allowed_origin("https://example.com") .allowed_origin("https://example.org") .allowed_methods(vec![Method::GET]) @@ -209,11 +211,11 @@ async fn test_multiple_origins() { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://example.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://example.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://example.com"[..]), resp.headers() @@ -221,11 +223,11 @@ async fn test_multiple_origins() { .map(HeaderValue::as_bytes) ); - let req = TestRequest::with_header("Origin", "https://example.org") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://example.org")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://example.org"[..]), resp.headers() @@ -237,7 +239,7 @@ async fn test_multiple_origins() { #[actix_rt::test] async fn test_response() { let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; - let mut cors = Cors::default() + let cors = Cors::default() .allow_any_origin() .send_wildcard() .disable_preflight() @@ -250,10 +252,11 @@ async fn test_response() { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") + let req = TestRequest::default() + .insert_header(("Origin", "https://www.example.com")) .method(Method::OPTIONS) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"*"[..]), resp.headers() @@ -283,7 +286,7 @@ async fn test_response() { } let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; - let mut cors = Cors::default() + let cors = Cors::default() .allow_any_origin() .send_wildcard() .disable_preflight() @@ -294,22 +297,25 @@ async fn test_response() { .allowed_header(header::CONTENT_TYPE) .new_transform(fn_service(|req: ServiceRequest| { ok(req.into_response({ - HttpResponse::Ok().header(header::VARY, "Accept").finish() + HttpResponse::Ok() + .insert_header((header::VARY, "Accept")) + .finish() })) })) .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") + let req = TestRequest::default() + .insert_header(("Origin", "https://www.example.com")) .method(Method::OPTIONS) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"Accept, Origin"[..]), resp.headers().get(header::VARY).map(HeaderValue::as_bytes) ); - let mut cors = Cors::default() + let cors = Cors::default() .disable_vary_header() .allowed_methods(vec!["POST"]) .allowed_origin("https://www.example.com") @@ -318,11 +324,12 @@ async fn test_response() { .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") + let req = TestRequest::default() + .insert_header(("Origin", "https://www.example.com")) .method(Method::OPTIONS) - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; let origins_str = resp .headers() .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) @@ -332,39 +339,40 @@ async fn test_response() { #[actix_rt::test] async fn test_validate_origin() { - let mut cors = Cors::default() + let cors = Cors::default() .allowed_origin("https://www.example.com") .new_transform(test::ok_service()) .await .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::GET) + let req = TestRequest::get() + .insert_header(("Origin", "https://www.example.com")) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!(resp.status(), StatusCode::OK); } #[actix_rt::test] async fn test_no_origin_response() { - let mut cors = Cors::permissive() + let cors = Cors::permissive() .disable_preflight() .new_transform(test::ok_service()) .await .unwrap(); let req = TestRequest::default().method(Method::GET).to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert!(resp .headers() .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) .is_none()); - let req = TestRequest::with_header("Origin", "https://www.example.com") + let req = TestRequest::default() + .insert_header(("Origin", "https://www.example.com")) .method(Method::OPTIONS) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!( Some(&b"https://www.example.com"[..]), resp.headers() @@ -375,21 +383,22 @@ async fn test_no_origin_response() { #[actix_rt::test] async fn validate_origin_allows_all_origins() { - let mut cors = Cors::permissive() + let cors = Cors::permissive() .new_transform(test::ok_service()) .await .unwrap(); - let req = - TestRequest::with_header("Origin", "https://www.example.com").to_srv_request(); + let req = TestRequest::default() + .insert_header(("Origin", "https://www.example.com")) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!(resp.status(), StatusCode::OK); } #[actix_rt::test] async fn test_allow_any_origin_any_method_any_header() { - let mut cors = Cors::default() + let cors = Cors::default() .allow_any_origin() .allow_any_method() .allow_any_header() @@ -397,12 +406,13 @@ async fn test_allow_any_origin_any_method_any_header() { .await .unwrap(); - let req = TestRequest::with_header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") - .header(header::ACCESS_CONTROL_REQUEST_HEADERS, "content-type") - .header(header::ORIGIN, "https://www.example.com") + let req = TestRequest::default() + .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST")) + .insert_header((header::ACCESS_CONTROL_REQUEST_HEADERS, "content-type")) + .insert_header((header::ORIGIN, "https://www.example.com")) .method(Method::OPTIONS) .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; + let resp = test::call_service(&cors, req).await; assert_eq!(resp.status(), StatusCode::OK); } diff --git a/actix-identity/CHANGES.md b/actix-identity/CHANGES.md index 36e8b14e7..6a1afdf96 100644 --- a/actix-identity/CHANGES.md +++ b/actix-identity/CHANGES.md @@ -1,6 +1,7 @@ # Changes ## Unreleased - 2020-xx-xx +* Minimum supported Rust version (MSRV) is now 1.46.0. ## 0.3.1 - 2020-09-20 diff --git a/actix-identity/Cargo.toml b/actix-identity/Cargo.toml index 3b51979e2..5542b2cb8 100644 --- a/actix-identity/Cargo.toml +++ b/actix-identity/Cargo.toml @@ -16,13 +16,13 @@ name = "actix_identity" path = "src/lib.rs" [dependencies] -actix-web = { version = "3.0.0", default-features = false, features = ["secure-cookies"] } -actix-service = "1.0.6" -futures-util = { version = "0.3.4", default-features = false } +actix-web = { version = "4.0.0-beta.4", default-features = false, features = ["secure-cookies"] } +actix-service = "2.0.0-beta.5" +futures-util = { version = "0.3", default-features = false } serde = "1.0" serde_json = "1.0" time = { version = "0.2.7", default-features = false, features = ["std"] } [dev-dependencies] -actix-rt = "1.1.1" -actix-http = "2.0.0" +actix-rt = "2" +actix-http = "3.0.0-beta.4" diff --git a/actix-identity/src/lib.rs b/actix-identity/src/lib.rs index 42060554e..0350a7342 100644 --- a/actix-identity/src/lib.rs +++ b/actix-identity/src/lib.rs @@ -223,15 +223,13 @@ impl IdentityService { } } -impl Transform for IdentityService +impl Transform for IdentityService where - S: Service, Error = Error> - + 'static, + S: Service, Error = Error> + 'static, S::Future: 'static, T: IdentityPolicy, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); @@ -261,24 +259,22 @@ impl Clone for IdentityServiceMiddleware { } } -impl Service for IdentityServiceMiddleware +impl Service for IdentityServiceMiddleware where B: 'static, - S: Service, Error = Error> - + 'static, + S: Service, Error = Error> + 'static, S::Future: 'static, T: IdentityPolicy, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { self.service.borrow_mut().poll_ready(cx) } - fn call(&mut self, mut req: ServiceRequest) -> Self::Future { + fn call(&self, mut req: ServiceRequest) -> Self::Future { let srv = self.service.clone(); let backend = self.backend.clone(); let fut = self.backend.from_request(&mut req); @@ -637,7 +633,7 @@ mod tests { #[actix_rt::test] async fn test_identity() { - let mut srv = test::init_service( + let srv = test::init_service( App::new() .wrap(IdentityService::new( CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) @@ -668,18 +664,16 @@ mod tests { ) .await; let resp = - test::call_service(&mut srv, TestRequest::with_uri("/index").to_request()) - .await; + test::call_service(&srv, TestRequest::with_uri("/index").to_request()).await; assert_eq!(resp.status(), StatusCode::OK); let resp = - test::call_service(&mut srv, TestRequest::with_uri("/login").to_request()) - .await; + test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await; assert_eq!(resp.status(), StatusCode::OK); let c = resp.response().cookies().next().unwrap().to_owned(); let resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/index") .cookie(c.clone()) .to_request(), @@ -688,7 +682,7 @@ mod tests { assert_eq!(resp.status(), StatusCode::CREATED); let resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/logout") .cookie(c.clone()) .to_request(), @@ -701,7 +695,7 @@ mod tests { #[actix_rt::test] async fn test_identity_max_age_time() { let duration = Duration::days(1); - let mut srv = test::init_service( + let srv = test::init_service( App::new() .wrap(IdentityService::new( CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) @@ -718,8 +712,7 @@ mod tests { ) .await; let resp = - test::call_service(&mut srv, TestRequest::with_uri("/login").to_request()) - .await; + test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await; assert_eq!(resp.status(), StatusCode::OK); assert!(resp.headers().contains_key(header::SET_COOKIE)); let c = resp.response().cookies().next().unwrap().to_owned(); @@ -728,7 +721,7 @@ mod tests { #[actix_rt::test] async fn test_http_only_same_site() { - let mut srv = test::init_service( + let srv = test::init_service( App::new() .wrap(IdentityService::new( CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) @@ -746,8 +739,7 @@ mod tests { .await; let resp = - test::call_service(&mut srv, TestRequest::with_uri("/login").to_request()) - .await; + test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await; assert_eq!(resp.status(), StatusCode::OK); assert!(resp.headers().contains_key(header::SET_COOKIE)); @@ -760,7 +752,7 @@ mod tests { #[actix_rt::test] async fn test_identity_max_age() { let seconds = 60; - let mut srv = test::init_service( + let srv = test::init_service( App::new() .wrap(IdentityService::new( CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) @@ -777,8 +769,7 @@ mod tests { ) .await; let resp = - test::call_service(&mut srv, TestRequest::with_uri("/login").to_request()) - .await; + test::call_service(&srv, TestRequest::with_uri("/login").to_request()).await; assert_eq!(resp.status(), StatusCode::OK); assert!(resp.headers().contains_key(header::SET_COOKIE)); let c = resp.response().cookies().next().unwrap().to_owned(); @@ -790,7 +781,7 @@ mod tests { >( f: F, ) -> impl actix_service::Service< - Request = actix_http::Request, + actix_http::Request, Response = ServiceResponse, Error = Error, > { @@ -925,19 +916,19 @@ mod tests { #[actix_rt::test] async fn test_identity_legacy_cookie_is_set() { - let mut srv = create_identity_server(|c| c).await; + let srv = create_identity_server(|c| c).await; let mut resp = - test::call_service(&mut srv, TestRequest::with_uri("/").to_request()).await; + test::call_service(&srv, TestRequest::with_uri("/").to_request()).await; assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN); assert_logged_in(resp, None).await; } #[actix_rt::test] async fn test_identity_legacy_cookie_works() { - let mut srv = create_identity_server(|c| c).await; + let srv = create_identity_server(|c| c).await; let cookie = legacy_login_cookie(COOKIE_LOGIN); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -949,11 +940,10 @@ mod tests { #[actix_rt::test] async fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() { - let mut srv = - create_identity_server(|c| c.visit_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.visit_deadline(Duration::days(90))).await; let cookie = legacy_login_cookie(COOKIE_LOGIN); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -970,11 +960,10 @@ mod tests { #[actix_rt::test] async fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() { - let mut srv = - create_identity_server(|c| c.login_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await; let cookie = legacy_login_cookie(COOKIE_LOGIN); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -991,11 +980,10 @@ mod tests { #[actix_rt::test] async fn test_identity_cookie_rejected_if_login_timestamp_needed() { - let mut srv = - create_identity_server(|c| c.login_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await; let cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now())); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -1012,11 +1000,10 @@ mod tests { #[actix_rt::test] async fn test_identity_cookie_rejected_if_visit_timestamp_needed() { - let mut srv = - create_identity_server(|c| c.visit_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.visit_deadline(Duration::days(90))).await; let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -1033,15 +1020,14 @@ mod tests { #[actix_rt::test] async fn test_identity_cookie_rejected_if_login_timestamp_too_old() { - let mut srv = - create_identity_server(|c| c.login_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await; let cookie = login_cookie( COOKIE_LOGIN, Some(SystemTime::now() - Duration::days(180)), None, ); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -1058,15 +1044,14 @@ mod tests { #[actix_rt::test] async fn test_identity_cookie_rejected_if_visit_timestamp_too_old() { - let mut srv = - create_identity_server(|c| c.visit_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.visit_deadline(Duration::days(90))).await; let cookie = login_cookie( COOKIE_LOGIN, None, Some(SystemTime::now() - Duration::days(180)), ); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -1083,11 +1068,10 @@ mod tests { #[actix_rt::test] async fn test_identity_cookie_not_updated_on_login_deadline() { - let mut srv = - create_identity_server(|c| c.login_deadline(Duration::days(90))).await; + let srv = create_identity_server(|c| c.login_deadline(Duration::days(90))).await; let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -1100,7 +1084,7 @@ mod tests { // https://github.com/actix/actix-web/issues/1263 #[actix_rt::test] async fn test_identity_cookie_updated_on_visit_deadline() { - let mut srv = create_identity_server(|c| { + let srv = create_identity_server(|c| { c.visit_deadline(Duration::days(90)) .login_deadline(Duration::days(90)) }) @@ -1108,7 +1092,7 @@ mod tests { let timestamp = SystemTime::now() - Duration::days(1); let cookie = login_cookie(COOKIE_LOGIN, Some(timestamp), Some(timestamp)); let mut resp = test::call_service( - &mut srv, + &srv, TestRequest::with_uri("/") .cookie(cookie.clone()) .to_request(), @@ -1146,22 +1130,22 @@ mod tests { } } - let mut srv = IdentityServiceMiddleware { + let srv = IdentityServiceMiddleware { backend: Rc::new(Ident), service: Rc::new(RefCell::new(into_service( |_: ServiceRequest| async move { - actix_rt::time::delay_for(std::time::Duration::from_secs(100)).await; + actix_rt::time::sleep(std::time::Duration::from_secs(100)).await; Err::(error::ErrorBadRequest("error")) }, ))), }; - let mut srv2 = srv.clone(); + let srv2 = srv.clone(); let req = TestRequest::default().to_srv_request(); actix_rt::spawn(async move { let _ = srv2.call(req).await; }); - actix_rt::time::delay_for(std::time::Duration::from_millis(50)).await; + actix_rt::time::sleep(std::time::Duration::from_millis(50)).await; let _ = lazy(|cx| srv.poll_ready(cx)).await; } diff --git a/actix-protobuf/CHANGES.md b/actix-protobuf/CHANGES.md index 2b894c4d9..2d305f03f 100644 --- a/actix-protobuf/CHANGES.md +++ b/actix-protobuf/CHANGES.md @@ -1,6 +1,7 @@ # Changes ## Unreleased - 2020-xx-xx +* Minimum supported Rust version (MSRV) is now 1.46.0. ## 0.6.0 - 2020-09-11 diff --git a/actix-protobuf/Cargo.toml b/actix-protobuf/Cargo.toml index 26686524c..f439b6bf5 100644 --- a/actix-protobuf/Cargo.toml +++ b/actix-protobuf/Cargo.toml @@ -19,11 +19,11 @@ name = "actix_protobuf" path = "src/lib.rs" [dependencies] -actix-web = { version = "3.0.0", default_features = false } -actix-rt = "1.1.1" +actix-web = { version = "4.0.0-beta.4", default_features = false } +actix-rt = "2" futures-util = { version = "0.3.5", default-features = false } derive_more = "0.99" -prost = "0.6.0" +prost = "0.7" [dev-dependencies] -prost-derive = "0.6.0" +prost-derive = "0.7" diff --git a/actix-protobuf/examples/prost-example/Cargo.toml b/actix-protobuf/examples/prost-example/Cargo.toml index 482189049..fc21c4e93 100644 --- a/actix-protobuf/examples/prost-example/Cargo.toml +++ b/actix-protobuf/examples/prost-example/Cargo.toml @@ -8,9 +8,9 @@ authors = [ ] [dependencies] -actix-web = "3.0.0" +actix-web = "4.0.0-beta.4" actix-protobuf = { path = "../../" } -env_logger = "0.7" -prost = "0.6.0" -prost-derive = "0.6.0" +env_logger = "0.8" +prost = "0.7" +prost-derive = "0.7" diff --git a/actix-protobuf/src/lib.rs b/actix-protobuf/src/lib.rs index 8c345db9f..0649d9e6c 100644 --- a/actix-protobuf/src/lib.rs +++ b/actix-protobuf/src/lib.rs @@ -17,7 +17,7 @@ use actix_web::error::{Error, PayloadError, ResponseError}; use actix_web::http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use actix_web::web::BytesMut; use actix_web::{FromRequest, HttpMessage, HttpRequest, HttpResponse, Responder}; -use futures_util::future::{ready, FutureExt, LocalBoxFuture, Ready}; +use futures_util::future::{FutureExt, LocalBoxFuture}; use futures_util::StreamExt; #[derive(Debug, Display)] @@ -137,21 +137,16 @@ where } impl Responder for ProtoBuf { - type Error = Error; - type Future = Ready>; - - fn respond_to(self, _: &HttpRequest) -> Self::Future { + fn respond_to(self, _: &HttpRequest) -> HttpResponse { let mut buf = Vec::new(); - ready( - self.0 - .encode(&mut buf) - .map_err(|e| Error::from(ProtoBufPayloadError::Serialize(e))) - .map(|()| { - HttpResponse::Ok() - .content_type("application/protobuf") - .body(buf) - }), - ) + match self.0.encode(&mut buf) { + Ok(()) => HttpResponse::Ok() + .content_type("application/protobuf") + .body(buf), + Err(err) => HttpResponse::from_error(Error::from( + ProtoBufPayloadError::Serialize(err), + )), + } } } @@ -255,7 +250,7 @@ pub trait ProtoBufResponseBuilder { impl ProtoBufResponseBuilder for HttpResponseBuilder { fn protobuf(&mut self, value: T) -> Result { - self.header(CONTENT_TYPE, "application/protobuf"); + self.append_header((CONTENT_TYPE, "application/protobuf")); let mut body = Vec::new(); value @@ -313,16 +308,16 @@ mod tests { let protobuf = ProtoBufMessage::::new(&req, &mut pl).await; assert_eq!(protobuf.err().unwrap(), ProtoBufPayloadError::ContentType); - let (req, mut pl) = - TestRequest::with_header(header::CONTENT_TYPE, "application/text") - .to_http_parts(); + let (req, mut pl) = TestRequest::get() + .append_header((header::CONTENT_TYPE, "application/text")) + .to_http_parts(); let protobuf = ProtoBufMessage::::new(&req, &mut pl).await; assert_eq!(protobuf.err().unwrap(), ProtoBufPayloadError::ContentType); - let (req, mut pl) = - TestRequest::with_header(header::CONTENT_TYPE, "application/protobuf") - .header(header::CONTENT_LENGTH, "10000") - .to_http_parts(); + let (req, mut pl) = TestRequest::get() + .append_header((header::CONTENT_TYPE, "application/protobuf")) + .append_header((header::CONTENT_LENGTH, "10000")) + .to_http_parts(); let protobuf = ProtoBufMessage::::new(&req, &mut pl) .limit(100) .await; diff --git a/actix-redis/Cargo.toml b/actix-redis/Cargo.toml index d60103e0b..ac6e12f7d 100644 --- a/actix-redis/Cargo.toml +++ b/actix-redis/Cargo.toml @@ -22,7 +22,6 @@ default = ["web"] # actix-web integration web = [ - "actix-http/actors", "actix-service", "actix-web", "actix-session/cookie-session", @@ -32,28 +31,27 @@ web = [ ] [dependencies] -actix = "0.10.0" -actix-utils = "2.0.0" - log = "0.4.6" -backoff = "0.2.1" derive_more = "0.99.2" futures-util = { version = "0.3.7", default-features = false } -redis-async = "0.6.3" -actix-rt = "1.1.1" +futures-channel = { version = "0.3.5", default-features = false } +redis-async = "0.9" time = "0.2.23" -tokio = "0.2.6" -tokio-util = "0.3.0" +actix-rt = "2" +tokio = "1" +tokio-util = "0.6" + +trust-dns-resolver = { version = "0.20.0", default-features = false, features = ["tokio-runtime", "system-config"] } # actix-session -actix-web = { version = "3.0.0", default_features = false, optional = true } -actix-http = { version = "2.0.0", optional = true } -actix-service = { version = "1.0.6", optional = true } +actix-web = { version = "4.0.0-beta.4", default_features = false, optional = true } +actix-http = { version = "3.0.0-beta.4", optional = true } +actix-service = { version = "2.0.0-beta.5", optional = true } actix-session = { version = "0.4.0", optional = true } -rand = { version = "0.7.0", optional = true } +rand = { version = "0.8", optional = true } serde = { version = "1.0.101", optional = true } serde_json = { version = "1.0.40", optional = true } [dev-dependencies] -env_logger = "0.7" +env_logger = "0.8" serde_derive = "1.0" diff --git a/actix-redis/examples/authentication.rs b/actix-redis/examples/authentication.rs index 191288bab..d2a301f8f 100644 --- a/actix-redis/examples/authentication.rs +++ b/actix-redis/examples/authentication.rs @@ -19,7 +19,7 @@ struct User { } impl User { - fn authenticate(credentials: Credentials) -> Result { + fn authenticate(credentials: Credentials) -> Result { // TODO: figure out why I keep getting hacked if &credentials.password != "hunter2" { return Err(HttpResponse::Unauthorized().json("Unauthorized")); @@ -33,7 +33,7 @@ impl User { } } -pub fn validate_session(session: &Session) -> Result { +pub fn validate_session(session: &Session) -> Result { let user_id: Option = session.get("user_id").unwrap_or(None); match user_id { @@ -49,7 +49,7 @@ pub fn validate_session(session: &Session) -> Result async fn login( credentials: web::Json, session: Session, -) -> Result { +) -> Result { let credentials = credentials.into_inner(); match User::authenticate(credentials) { diff --git a/actix-redis/src/lib.rs b/actix-redis/src/lib.rs index a582583f5..107beb762 100644 --- a/actix-redis/src/lib.rs +++ b/actix-redis/src/lib.rs @@ -3,7 +3,7 @@ #![deny(rust_2018_idioms)] mod redis; -pub use redis::{Command, RedisActor}; +pub use redis::RedisClient; use derive_more::{Display, Error, From}; @@ -25,6 +25,12 @@ pub enum Error { /// Cancel all waters when connection get dropped #[display(fmt = "Redis: Disconnected")] Disconnected, + /// Invalid address + #[display(fmt = "Redis: Invalid address")] + InvalidAddress, + /// DNS resolve error + #[display(fmt = "Redis: DNS resolve error")] + ResolveError, } #[cfg(feature = "web")] diff --git a/actix-redis/src/redis.rs b/actix-redis/src/redis.rs index 802b27836..b1b92b83f 100644 --- a/actix-redis/src/redis.rs +++ b/actix-redis/src/redis.rs @@ -1,150 +1,98 @@ use std::collections::VecDeque; -use std::io; +use std::net::SocketAddr; -use actix::actors::resolver::{Connect, Resolver}; -use actix::prelude::*; -use actix_utils::oneshot; -use backoff::backoff::Backoff; -use backoff::ExponentialBackoff; -use futures_util::FutureExt; -use log::{error, info, warn}; -use redis_async::error::Error as RespError; -use redis_async::resp::{RespCodec, RespValue}; -use tokio::io::{split, WriteHalf}; -use tokio::net::TcpStream; -use tokio_util::codec::FramedRead; +use redis_async::client::{paired_connect, PairedConnection}; +use redis_async::resp::RespValue; +use tokio::sync::Mutex; +use trust_dns_resolver::config::{ResolverConfig, ResolverOpts}; +use trust_dns_resolver::TokioAsyncResolver as AsyncResolver; use crate::Error; -/// Command for send data to Redis -#[derive(Debug)] -pub struct Command(pub RespValue); - -impl Message for Command { - type Result = Result; -} - -/// Redis comminucation actor -pub struct RedisActor { +pub struct RedisClient { addr: String, - backoff: ExponentialBackoff, - cell: Option, RespCodec>>, - queue: VecDeque>>, + connection: Mutex>, } -impl RedisActor { - /// Start new `Supervisor` with `RedisActor`. - pub fn start>(addr: S) -> Addr { - let addr = addr.into(); +impl RedisClient { + pub fn new(addr: impl Into) -> Self { + Self { + addr: addr.into(), + connection: Mutex::new(None), + } + } - let backoff = ExponentialBackoff { - max_elapsed_time: None, - ..Default::default() - }; + async fn get_connection(&self) -> Result { + let mut connection = self.connection.lock().await; + if let Some(ref connection) = *connection { + return Ok(connection.clone()); + } - Supervisor::start(|_| RedisActor { - addr, - cell: None, - backoff, - queue: VecDeque::new(), + let mut addrs = resolve(&self.addr).await?; + loop { + // try to connect + let socket_addr = addrs.pop_front().ok_or_else(|| { + log::warn!("Cannot connect to {}.", self.addr); + Error::NotConnected + })?; + match paired_connect(socket_addr).await { + Ok(conn) => { + *connection = Some(conn.clone()); + return Ok(conn); + } + Err(err) => log::warn!( + "Attempt to connect to {} as {} failed: {}.", + self.addr, + socket_addr, + err + ), + } + } + } + + pub async fn send(&self, req: RespValue) -> Result { + let res = self.get_connection().await?.send(req).await?; + Ok(res) + } +} + +fn parse_addr(addr: &str, default_port: u16) -> Option<(&str, u16)> { + // split the string by ':' and convert the second part to u16 + let mut parts_iter = addr.splitn(2, ':'); + let host = parts_iter.next()?; + let port_str = parts_iter.next().unwrap_or(""); + let port: u16 = port_str.parse().unwrap_or(default_port); + Some((host, port)) +} + +async fn resolve(addr: &str) -> Result, Error> { + // try to parse as a regular SocketAddr first + if let Ok(addr) = addr.parse::() { + let mut addrs = VecDeque::new(); + addrs.push_back(addr); + return Ok(addrs); + } + + let (host, port) = parse_addr(addr, 6379).ok_or(Error::InvalidAddress)?; + + // we need to do dns resolution + let resolver = AsyncResolver::tokio_from_system_conf() + .or_else(|err| { + log::warn!("Cannot create system DNS resolver: {}", err); + AsyncResolver::tokio(ResolverConfig::default(), ResolverOpts::default()) }) - } -} - -impl Actor for RedisActor { - type Context = Context; - - fn started(&mut self, ctx: &mut Context) { - Resolver::from_registry() - .send(Connect::host(self.addr.as_str())) - .into_actor(self) - .map(|res, act, ctx| match res { - Ok(res) => match res { - Ok(stream) => { - info!("Connected to redis server: {}", act.addr); - - let (r, w) = split(stream); - - // configure write side of the connection - let framed = actix::io::FramedWrite::new(w, RespCodec, ctx); - act.cell = Some(framed); - - // read side of the connection - ctx.add_stream(FramedRead::new(r, RespCodec)); - - act.backoff.reset(); - } - Err(err) => { - error!("Can not connect to redis server: {}", err); - // re-connect with backoff time. - // we stop current context, supervisor will restart it. - if let Some(timeout) = act.backoff.next_backoff() { - ctx.run_later(timeout, |_, ctx| ctx.stop()); - } - } - }, - Err(err) => { - error!("Can not connect to redis server: {}", err); - // re-connect with backoff time. - // we stop current context, supervisor will restart it. - if let Some(timeout) = act.backoff.next_backoff() { - ctx.run_later(timeout, |_, ctx| ctx.stop()); - } - } - }) - .wait(ctx); - } -} - -impl Supervised for RedisActor { - fn restarting(&mut self, _: &mut Self::Context) { - self.cell.take(); - for tx in self.queue.drain(..) { - let _ = tx.send(Err(Error::Disconnected)); - } - } -} - -impl actix::io::WriteHandler for RedisActor { - fn error(&mut self, err: io::Error, _: &mut Self::Context) -> Running { - warn!("Redis connection dropped: {} error: {}", self.addr, err); - Running::Stop - } -} - -impl StreamHandler> for RedisActor { - fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { - match msg { - Err(e) => { - if let Some(tx) = self.queue.pop_front() { - let _ = tx.send(Err(e.into())); - } - ctx.stop(); - } - Ok(val) => { - if let Some(tx) = self.queue.pop_front() { - let _ = tx.send(Ok(val)); - } - } - } - } -} - -impl Handler for RedisActor { - type Result = ResponseFuture>; - - fn handle(&mut self, msg: Command, _: &mut Self::Context) -> Self::Result { - let (tx, rx) = oneshot::channel(); - if let Some(ref mut cell) = self.cell { - self.queue.push_back(tx); - cell.write(msg.0); - } else { - let _ = tx.send(Err(Error::NotConnected)); - } - - Box::pin(rx.map(|res| match res { - Ok(res) => res, - Err(_) => Err(Error::Disconnected), - })) - } + .map_err(|err| { + log::error!("Cannot create DNS resolver: {}", err); + Error::ResolveError + })?; + + let addrs = resolver + .lookup_ip(host) + .await + .map_err(|_| Error::ResolveError)? + .into_iter() + .map(|ip| SocketAddr::new(ip, port)) + .collect(); + + Ok(addrs) } diff --git a/actix-redis/src/session.rs b/actix-redis/src/session.rs index be9f11a24..d185aefa4 100644 --- a/actix-redis/src/session.rs +++ b/actix-redis/src/session.rs @@ -3,7 +3,6 @@ use std::pin::Pin; use std::task::{Context, Poll}; use std::{collections::HashMap, iter, rc::Rc}; -use actix::prelude::*; use actix_service::{Service, Transform}; use actix_session::{Session, SessionStatus}; use actix_web::cookie::{Cookie, CookieJar, Key, SameSite}; @@ -16,7 +15,7 @@ use redis_async::resp::RespValue; use redis_async::resp_array; use time::{self, Duration, OffsetDateTime}; -use crate::redis::{Command, RedisActor}; +use crate::redis::RedisClient; /// Use redis as session storage. /// @@ -36,7 +35,7 @@ impl RedisSession { key: Key::derive_from(key), cache_keygen: Box::new(|key: &str| format!("session:{}", &key)), ttl: "7200".to_owned(), - addr: RedisActor::start(addr), + redis_client: RedisClient::new(addr), name: "actix-session".to_owned(), path: "/".to_owned(), domain: None, @@ -113,14 +112,12 @@ impl RedisSession { } } -impl Transform for RedisSession +impl Transform for RedisSession where - S: Service, Error = Error> - + 'static, + S: Service, Error = Error> + 'static, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = S::Error; type InitError = (); @@ -141,25 +138,23 @@ pub struct RedisSessionMiddleware { inner: Rc, } -impl Service for RedisSessionMiddleware +impl Service for RedisSessionMiddleware where - S: Service, Error = Error> - + 'static, + S: Service, Error = Error> + 'static, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; #[allow(clippy::type_complexity)] type Future = Pin>>>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { self.service.borrow_mut().poll_ready(cx) } - fn call(&mut self, mut req: ServiceRequest) -> Self::Future { - let mut srv = self.service.clone(); + fn call(&self, mut req: ServiceRequest) -> Self::Future { + let srv = self.service.clone(); let inner = self.inner.clone(); Box::pin(async move { @@ -215,7 +210,7 @@ struct Inner { key: Key, cache_keygen: Box String>, ttl: String, - addr: Addr, + redis_client: RedisClient, name: String, path: String, domain: Option, @@ -256,13 +251,11 @@ impl Inner { } }; - let res = self - .addr - .send(Command(resp_array!["GET", cache_key])) + let val = self + .redis_client + .send(resp_array!["GET", cache_key]) .await?; - let val = res.map_err(error::ErrorInternalServerError)?; - match val { RespValue::Error(err) => { return Err(error::ErrorInternalServerError(err)); @@ -294,6 +287,7 @@ impl Inner { } else { let value: String = iter::repeat(()) .map(|()| OsRng.sample(Alphanumeric)) + .map(char::from) .take(32) .collect(); @@ -331,12 +325,9 @@ impl Inner { Ok(body) => body, }; - let cmd = Command(resp_array!["SET", cache_key, body, "EX", &self.ttl]); - - self.addr - .send(cmd) - .await? - .map_err(error::ErrorInternalServerError)?; + self.redis_client + .send(resp_array!["SET", cache_key, body, "EX", &self.ttl]) + .await?; if let Some(jar) = jar { for cookie in jar.delta() { @@ -352,17 +343,16 @@ impl Inner { async fn clear_cache(&self, key: String) -> Result<(), Error> { let cache_key = (self.cache_keygen)(&key); - match self.addr.send(Command(resp_array!["DEL", cache_key])).await { - Err(e) => Err(Error::from(e)), - Ok(res) => { - match res { - // redis responds with number of deleted records - Ok(RespValue::Integer(x)) if x > 0 => Ok(()), - _ => Err(error::ErrorInternalServerError( - "failed to remove session from cache", - )), - } - } + match self + .redis_client + .send(resp_array!["DEL", cache_key]) + .await? + { + // redis responds with number of deleted records + RespValue::Integer(x) if x > 0 => Ok(()), + _ => Err(error::ErrorInternalServerError( + "failed to remove session from cache", + )), } } @@ -406,7 +396,7 @@ mod test { .unwrap_or(Some(0)) .unwrap_or(0); - Ok(HttpResponse::Ok().json(IndexResponse { user_id, counter })) + Ok(HttpResponse::Ok().json(&IndexResponse { user_id, counter })) } async fn do_something(session: Session) -> Result { @@ -417,7 +407,7 @@ mod test { .map_or(1, |inner| inner + 1); session.set("counter", counter)?; - Ok(HttpResponse::Ok().json(IndexResponse { user_id, counter })) + Ok(HttpResponse::Ok().json(&IndexResponse { user_id, counter })) } #[derive(Deserialize)] @@ -438,7 +428,7 @@ mod test { .unwrap_or(Some(0)) .unwrap_or(0); - Ok(HttpResponse::Ok().json(IndexResponse { + Ok(HttpResponse::Ok().json(&IndexResponse { user_id: Some(id), counter, })) diff --git a/actix-redis/tests/test_redis.rs b/actix-redis/tests/test_redis.rs index b9bb9c390..6d53aec79 100644 --- a/actix-redis/tests/test_redis.rs +++ b/actix-redis/tests/test_redis.rs @@ -1,42 +1,31 @@ #[macro_use] extern crate redis_async; -use actix_redis::{Command, Error, RedisActor, RespValue}; +use actix_redis::{Error, RedisClient, RespValue}; #[actix_rt::test] async fn test_error_connect() { - let addr = RedisActor::start("localhost:54000"); - let _addr2 = addr.clone(); + let addr = RedisClient::new("localhost:54000"); - let res = addr.send(Command(resp_array!["GET", "test"])).await; + let res = addr.send(resp_array!["GET", "test"]).await; match res { - Ok(Err(Error::NotConnected)) => (), + Err(Error::NotConnected) => (), _ => panic!("Should not happen {:?}", res), } } #[actix_rt::test] -async fn test_redis() { +async fn test_redis() -> Result<(), Error> { env_logger::init(); - let addr = RedisActor::start("127.0.0.1:6379"); - let res = addr - .send(Command(resp_array!["SET", "test", "value"])) - .await; + let addr = RedisClient::new("127.0.0.1:6379"); - match res { - Ok(Ok(resp)) => { - assert_eq!(resp, RespValue::SimpleString("OK".to_owned())); + let resp = addr.send(resp_array!["SET", "test", "value"]).await?; - let res = addr.send(Command(resp_array!["GET", "test"])).await; - match res { - Ok(Ok(resp)) => { - println!("RESP: {:?}", resp); - assert_eq!(resp, RespValue::BulkString((&b"value"[..]).into())); - } - _ => panic!("Should not happen {:?}", res), - } - } - _ => panic!("Should not happen {:?}", res), - } + assert_eq!(resp, RespValue::SimpleString("OK".to_owned())); + + let resp = addr.send(resp_array!["GET", "test"]).await?; + println!("RESP: {:?}", resp); + assert_eq!(resp, RespValue::BulkString((&b"value"[..]).into())); + Ok(()) } diff --git a/actix-session/CHANGES.md b/actix-session/CHANGES.md index 8921d3e7e..8e81457ab 100644 --- a/actix-session/CHANGES.md +++ b/actix-session/CHANGES.md @@ -6,6 +6,7 @@ ## 0.4.1 - 2020-03-21 * `Session::set_session` takes a `IntoIterator` instead of `Iterator`. [#105] * Fix calls to `session.purge()` from paths other than the one specified in the cookie. [#129] +* Minimum supported Rust version (MSRV) is now 1.46.0. [#105]: https://github.com/actix/actix-extras/pull/105 [#129]: https://github.com/actix/actix-extras/pull/129 diff --git a/actix-session/Cargo.toml b/actix-session/Cargo.toml index 85cd84cc4..6441373a8 100644 --- a/actix-session/Cargo.toml +++ b/actix-session/Cargo.toml @@ -20,8 +20,8 @@ default = ["cookie-session"] cookie-session = ["actix-web/secure-cookies"] [dependencies] -actix-web = { version = "3.0.0", default_features = false } -actix-service = "1.0.6" +actix-web = { version = "4.0.0-beta.4", default_features = false, features = ["cookies"] } +actix-service = "2.0.0-beta.5" derive_more = "0.99.2" futures-util = { version = "0.3.7", default-features = false } serde = "1.0" @@ -29,4 +29,4 @@ serde_json = "1.0" time = { version = "0.2.23", default-features = false, features = ["std"] } [dev-dependencies] -actix-rt = "1" +actix-rt = "2" diff --git a/actix-session/src/cookie.rs b/actix-session/src/cookie.rs index f5daa7dd9..b8fba0ee1 100644 --- a/actix-session/src/cookie.rs +++ b/actix-session/src/cookie.rs @@ -9,7 +9,7 @@ use actix_web::cookie::{Cookie, CookieJar, Key, SameSite}; use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::http::{header::SET_COOKIE, HeaderValue}; use actix_web::{Error, HttpMessage, ResponseError}; -use derive_more::{Display, From}; +use derive_more::Display; use futures_util::future::{ok, FutureExt, LocalBoxFuture, Ready}; use serde_json::error::Error as JsonError; use time::{Duration, OffsetDateTime}; @@ -17,7 +17,7 @@ use time::{Duration, OffsetDateTime}; use crate::{Session, SessionStatus}; /// Errors that can occur during handling cookie session -#[derive(Debug, From, Display)] +#[derive(Debug, Display)] pub enum CookieSessionError { /// Size of the serialized session is greater than 4000 bytes. #[display(fmt = "Size of the serialized session is greater than 4000 bytes.")] @@ -290,13 +290,12 @@ impl CookieSession { } } -impl Transform for CookieSession +impl Transform for CookieSession where - S: Service>, + S: Service>, S::Future: 'static, S::Error: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = S::Error; type InitError = (); @@ -317,18 +316,17 @@ pub struct CookieSessionMiddleware { inner: Rc, } -impl Service for CookieSessionMiddleware +impl Service for CookieSessionMiddleware where - S: Service>, + S: Service>, S::Future: 'static, S::Error: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = S::Error; type Future = LocalBoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { self.service.poll_ready(cx) } @@ -337,7 +335,7 @@ where /// session state changes, then set-cookie is returned in response. As /// a user logs out, call session.purge() to set SessionStatus accordingly /// and this will trigger removal of the session cookie in the response. - fn call(&mut self, mut req: ServiceRequest) -> Self::Future { + fn call(&self, mut req: ServiceRequest) -> Self::Future { let inner = self.inner.clone(); let (is_new, state) = self.inner.load(&req); let prolong_expiration = self.inner.expires_in.is_some(); @@ -387,7 +385,7 @@ mod tests { #[actix_rt::test] async fn cookie_session() { - let mut app = test::init_service( + let app = test::init_service( App::new() .wrap(CookieSession::signed(&[0; 32]).secure(false)) .service(web::resource("/").to(|ses: Session| async move { @@ -407,7 +405,7 @@ mod tests { #[actix_rt::test] async fn private_cookie() { - let mut app = test::init_service( + let app = test::init_service( App::new() .wrap(CookieSession::private(&[0; 32]).secure(false)) .service(web::resource("/").to(|ses: Session| async move { @@ -427,7 +425,7 @@ mod tests { #[actix_rt::test] async fn lazy_cookie() { - let mut app = test::init_service( + let app = test::init_service( App::new() .wrap(CookieSession::signed(&[0; 32]).secure(false).lazy(true)) .service(web::resource("/count").to(|ses: Session| async move { @@ -453,7 +451,7 @@ mod tests { #[actix_rt::test] async fn cookie_session_extractor() { - let mut app = test::init_service( + let app = test::init_service( App::new() .wrap(CookieSession::signed(&[0; 32]).secure(false)) .service(web::resource("/").to(|ses: Session| async move { @@ -473,7 +471,7 @@ mod tests { #[actix_rt::test] async fn basics() { - let mut app = test::init_service( + let app = test::init_service( App::new() .wrap( CookieSession::signed(&[0; 32]) @@ -508,13 +506,13 @@ mod tests { let request = test::TestRequest::with_uri("/test/") .cookie(cookie) .to_request(); - let body = test::read_response(&mut app, request).await; + let body = test::read_response(&app, request).await; assert_eq!(body, Bytes::from_static(b"counter: 100")); } #[actix_rt::test] async fn prolong_expiration() { - let mut app = test::init_service( + let app = test::init_service( App::new() .wrap(CookieSession::signed(&[0; 32]).secure(false).expires_in(60)) .service(web::resource("/").to(|ses: Session| async move { @@ -538,7 +536,7 @@ mod tests { .expires() .expect("Expiration is set"); - actix_rt::time::delay_for(std::time::Duration::from_secs(1)).await; + actix_rt::time::sleep(std::time::Duration::from_secs(1)).await; let request = test::TestRequest::with_uri("/test/").to_request(); let response = app.call(request).await.unwrap(); diff --git a/actix-web-httpauth/CHANGES.md b/actix-web-httpauth/CHANGES.md index 07a81adf3..b20cf8c5f 100644 --- a/actix-web-httpauth/CHANGES.md +++ b/actix-web-httpauth/CHANGES.md @@ -5,6 +5,7 @@ ## 0.5.1 - 2020-03-21 * Correct error handling when extracting auth details from request. [#128] +* Minimum supported Rust version (MSRV) is now 1.46.0. [#128]: https://github.com/actix/actix-extras/pull/128 diff --git a/actix-web-httpauth/Cargo.toml b/actix-web-httpauth/Cargo.toml index c8ab572fe..e3cb9a992 100644 --- a/actix-web-httpauth/Cargo.toml +++ b/actix-web-httpauth/Cargo.toml @@ -20,11 +20,11 @@ name = "actix_web_httpauth" path = "src/lib.rs" [dependencies] -actix-web = { version = "3.0.0", default_features = false } +actix-web = { version = "4.0.0-beta.4", default_features = false } base64 = "0.13" futures-util = { version = "0.3.7", default-features = false } [dev-dependencies] actix-cors = "0.5" -actix-rt = "1.1.1" -actix-service = "1.0.6" +actix-rt = "2" +actix-service = "2.0.0-beta.5" diff --git a/actix-web-httpauth/src/extractors/errors.rs b/actix-web-httpauth/src/extractors/errors.rs index 94233a1c5..872e14897 100644 --- a/actix-web-httpauth/src/extractors/errors.rs +++ b/actix-web-httpauth/src/extractors/errors.rs @@ -54,7 +54,7 @@ impl ResponseError for AuthenticationError { fn error_response(&self) -> HttpResponse { HttpResponse::build(self.status_code) // TODO: Get rid of the `.clone()` - .set(WwwAuthenticate(self.challenge.clone())) + .insert_header(WwwAuthenticate(self.challenge.clone())) .finish() } diff --git a/actix-web-httpauth/src/headers/authorization/header.rs b/actix-web-httpauth/src/headers/authorization/header.rs index 1c38c4c6f..17083ca5e 100644 --- a/actix-web-httpauth/src/headers/authorization/header.rs +++ b/actix-web-httpauth/src/headers/authorization/header.rs @@ -91,8 +91,8 @@ impl Header for Authorization { impl IntoHeaderValue for Authorization { type Error = ::Error; - fn try_into(self) -> Result::Error> { - self.0.try_into() + fn try_into_value(self) -> Result { + self.0.try_into_value() } } diff --git a/actix-web-httpauth/src/headers/authorization/scheme/basic.rs b/actix-web-httpauth/src/headers/authorization/scheme/basic.rs index 9c17d9acf..595658f86 100644 --- a/actix-web-httpauth/src/headers/authorization/scheme/basic.rs +++ b/actix-web-httpauth/src/headers/authorization/scheme/basic.rs @@ -97,7 +97,7 @@ impl fmt::Display for Basic { impl IntoHeaderValue for Basic { type Error = InvalidHeaderValue; - fn try_into(self) -> Result::Error> { + fn try_into_value(self) -> Result::Error> { let mut credentials = BytesMut::with_capacity( self.user_id.len() + 1 // ':' @@ -187,7 +187,7 @@ mod tests { password: Some("open sesame".into()), }; - let result = basic.try_into(); + let result = basic.try_into_value(); assert!(result.is_ok()); assert_eq!( result.unwrap(), diff --git a/actix-web-httpauth/src/headers/authorization/scheme/bearer.rs b/actix-web-httpauth/src/headers/authorization/scheme/bearer.rs index 5bdddd702..247d2c328 100644 --- a/actix-web-httpauth/src/headers/authorization/scheme/bearer.rs +++ b/actix-web-httpauth/src/headers/authorization/scheme/bearer.rs @@ -76,7 +76,7 @@ impl fmt::Display for Bearer { impl IntoHeaderValue for Bearer { type Error = InvalidHeaderValue; - fn try_into(self) -> Result::Error> { + fn try_into_value(self) -> Result::Error> { let mut buffer = BytesMut::with_capacity(7 + self.token.len()); buffer.put(&b"Bearer "[..]); buffer.extend_from_slice(self.token.as_bytes()); @@ -128,7 +128,7 @@ mod tests { fn test_into_header_value() { let bearer = Bearer::new("mF_9.B5f-4.1JqM"); - let result = bearer.try_into(); + let result = bearer.try_into_value(); assert!(result.is_ok()); assert_eq!( result.unwrap(), diff --git a/actix-web-httpauth/src/headers/www_authenticate/challenge/basic.rs b/actix-web-httpauth/src/headers/www_authenticate/challenge/basic.rs index 1df097f72..0a74f3251 100644 --- a/actix-web-httpauth/src/headers/www_authenticate/challenge/basic.rs +++ b/actix-web-httpauth/src/headers/www_authenticate/challenge/basic.rs @@ -25,7 +25,7 @@ use crate::utils; /// let challenge = Basic::with_realm("Restricted area"); /// /// HttpResponse::Unauthorized() -/// .set(WwwAuthenticate(challenge)) +/// .insert_header(WwwAuthenticate(challenge)) /// .finish() /// } /// ``` @@ -106,7 +106,7 @@ impl fmt::Display for Basic { impl IntoHeaderValue for Basic { type Error = InvalidHeaderValue; - fn try_into(self) -> Result::Error> { + fn try_into_value(self) -> Result::Error> { HeaderValue::from_maybe_shared(self.to_bytes()) } } @@ -120,7 +120,7 @@ mod tests { fn test_plain_into_header_value() { let challenge = Basic { realm: None }; - let value = challenge.try_into(); + let value = challenge.try_into_value(); assert!(value.is_ok()); let value = value.unwrap(); assert_eq!(value, "Basic"); @@ -132,7 +132,7 @@ mod tests { realm: Some("Restricted area".into()), }; - let value = challenge.try_into(); + let value = challenge.try_into_value(); assert!(value.is_ok()); let value = value.unwrap(); assert_eq!(value, "Basic realm=\"Restricted area\""); diff --git a/actix-web-httpauth/src/headers/www_authenticate/challenge/bearer/challenge.rs b/actix-web-httpauth/src/headers/www_authenticate/challenge/bearer/challenge.rs index 01f1b05ba..b2b5e86df 100644 --- a/actix-web-httpauth/src/headers/www_authenticate/challenge/bearer/challenge.rs +++ b/actix-web-httpauth/src/headers/www_authenticate/challenge/bearer/challenge.rs @@ -31,7 +31,7 @@ use crate::utils; /// .finish(); /// /// HttpResponse::Unauthorized() -/// .set(WwwAuthenticate(challenge)) +/// .insert_header(WwwAuthenticate(challenge)) /// .finish() /// } /// ``` @@ -133,7 +133,7 @@ impl fmt::Display for Bearer { impl IntoHeaderValue for Bearer { type Error = InvalidHeaderValue; - fn try_into(self) -> Result::Error> { + fn try_into_value(self) -> Result::Error> { HeaderValue::from_maybe_shared(self.to_bytes()) } } diff --git a/actix-web-httpauth/src/headers/www_authenticate/header.rs b/actix-web-httpauth/src/headers/www_authenticate/header.rs index 092b7593b..5094e098b 100644 --- a/actix-web-httpauth/src/headers/www_authenticate/header.rs +++ b/actix-web-httpauth/src/headers/www_authenticate/header.rs @@ -27,7 +27,7 @@ impl Header for WwwAuthenticate { impl IntoHeaderValue for WwwAuthenticate { type Error = ::Error; - fn try_into(self) -> Result::Error> { - self.0.try_into() + fn try_into_value(self) -> Result::Error> { + self.0.try_into_value() } } diff --git a/actix-web-httpauth/src/middleware.rs b/actix-web-httpauth/src/middleware.rs index 8aac191ab..24d35c6ea 100644 --- a/actix-web-httpauth/src/middleware.rs +++ b/actix-web-httpauth/src/middleware.rs @@ -118,16 +118,14 @@ where } } -impl Transform for HttpAuthentication +impl Transform for HttpAuthentication where - S: Service, Error = Error> - + 'static, + S: Service, Error = Error> + 'static, S::Future: 'static, F: Fn(ServiceRequest, T) -> O + 'static, O: Future> + 'static, T: AuthExtractor + 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Transform = AuthenticationMiddleware; @@ -153,25 +151,23 @@ where _extractor: PhantomData, } -impl Service for AuthenticationMiddleware +impl Service for AuthenticationMiddleware where - S: Service, Error = Error> - + 'static, + S: Service, Error = Error> + 'static, S::Future: 'static, F: Fn(ServiceRequest, T) -> O + 'static, O: Future> + 'static, T: AuthExtractor + 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = S::Error; type Future = LocalBoxFuture<'static, Result, Error>>; - fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll> { + fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { self.service.borrow_mut().poll_ready(ctx) } - fn call(&mut self, req: Self::Request) -> Self::Future { + fn call(&self, req: ServiceRequest) -> Self::Future { let process_fn = Arc::clone(&self.process_fn); let service = Rc::clone(&self.service); @@ -251,15 +247,14 @@ mod tests { use actix_service::{into_service, Service}; use actix_web::error; use actix_web::test::TestRequest; - use futures_util::join; /// This is a test for https://github.com/actix/actix-extras/issues/10 #[actix_rt::test] async fn test_middleware_panic() { - let mut middleware = AuthenticationMiddleware { + let middleware = AuthenticationMiddleware { service: Rc::new(RefCell::new(into_service( |_: ServiceRequest| async move { - actix_rt::time::delay_for(std::time::Duration::from_secs(1)).await; + actix_rt::time::sleep(std::time::Duration::from_secs(1)).await; Err::(error::ErrorBadRequest("error")) }, ))), @@ -267,22 +262,24 @@ mod tests { _extractor: PhantomData, }; - let req = TestRequest::with_header("Authorization", "Bearer 1").to_srv_request(); + let req = TestRequest::get() + .append_header(("Authorization", "Bearer 1")) + .to_srv_request(); - let f = middleware.call(req); + let f = middleware.call(req).await; - let res = futures_util::future::lazy(|cx| middleware.poll_ready(cx)); + let _res = futures_util::future::lazy(|cx| middleware.poll_ready(cx)).await; - assert!(join!(f, res).0.is_err()); + assert!(f.is_err()); } /// This is a test for https://github.com/actix/actix-extras/issues/10 #[actix_rt::test] async fn test_middleware_panic_several_orders() { - let mut middleware = AuthenticationMiddleware { + let middleware = AuthenticationMiddleware { service: Rc::new(RefCell::new(into_service( |_: ServiceRequest| async move { - actix_rt::time::delay_for(std::time::Duration::from_secs(1)).await; + actix_rt::time::sleep(std::time::Duration::from_secs(1)).await; Err::(error::ErrorBadRequest("error")) }, ))), @@ -290,24 +287,28 @@ mod tests { _extractor: PhantomData, }; - let req = TestRequest::with_header("Authorization", "Bearer 1").to_srv_request(); + let req = TestRequest::get() + .append_header(("Authorization", "Bearer 1")) + .to_srv_request(); - let f1 = middleware.call(req); + let f1 = middleware.call(req).await; - let req = TestRequest::with_header("Authorization", "Bearer 1").to_srv_request(); + let req = TestRequest::get() + .append_header(("Authorization", "Bearer 1")) + .to_srv_request(); - let f2 = middleware.call(req); + let f2 = middleware.call(req).await; - let req = TestRequest::with_header("Authorization", "Bearer 1").to_srv_request(); + let req = TestRequest::get() + .append_header(("Authorization", "Bearer 1")) + .to_srv_request(); - let f3 = middleware.call(req); + let f3 = middleware.call(req).await; - let res = futures_util::future::lazy(|cx| middleware.poll_ready(cx)); + let _res = futures_util::future::lazy(|cx| middleware.poll_ready(cx)).await; - let result = join!(f1, f2, f3, res); - - assert!(result.0.is_err()); - assert!(result.1.is_err()); - assert!(result.2.is_err()); + assert!(f1.is_err()); + assert!(f2.is_err()); + assert!(f3.is_err()); } }