From 4dc31aac93977572f062a43e5a38c23160ea2d5d Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Tue, 26 Nov 2019 11:25:50 +0600 Subject: [PATCH] use actix_rt::test for test setup --- .travis.yml | 11 +- Cargo.toml | 15 +- actix-cors/Cargo.toml | 3 + actix-cors/src/lib.rs | 652 ++++++------ actix-files/Cargo.toml | 1 + actix-files/src/lib.rs | 1180 +++++++++++----------- actix-framed/src/test.rs | 6 +- actix-framed/tests/test_server.rs | 227 +++-- actix-http/Cargo.toml | 10 +- actix-http/src/body.rs | 65 +- actix-http/src/client/connector.rs | 8 +- actix-http/src/client/h1proto.rs | 5 +- actix-http/src/client/h2proto.rs | 5 +- actix-http/src/client/pool.rs | 25 +- actix-http/src/config.rs | 37 +- actix-http/src/cookie/secure/key.rs | 1 - actix-http/src/error.rs | 4 - actix-http/src/h1/decoder.rs | 4 +- actix-http/src/h1/dispatcher.rs | 17 +- actix-http/src/h1/expect.rs | 2 - actix-http/src/h1/payload.rs | 28 +- actix-http/src/h1/service.rs | 2 +- actix-http/src/h1/upgrade.rs | 2 - actix-http/src/h1/utils.rs | 1 - actix-http/src/h2/dispatcher.rs | 4 +- actix-http/src/lib.rs | 3 +- actix-http/src/payload.rs | 1 - actix-http/src/response.rs | 1 - actix-http/src/service.rs | 4 +- actix-http/src/test.rs | 2 +- actix-http/tests/test_client.rs | 95 +- actix-http/tests/test_openssl.rs | 739 +++++++------- actix-http/tests/test_rustls.rs | 641 ++++++------ actix-http/tests/test_server.rs | 1043 +++++++++---------- actix-http/tests/test_ws.rs | 88 +- actix-identity/src/lib.rs | 611 ++++++------ actix-multipart/src/server.rs | 375 ++++--- actix-session/src/cookie.rs | 210 ++-- actix-web-codegen/Cargo.toml | 1 + actix-web-codegen/tests/test_macro.rs | 146 ++- awc/Cargo.toml | 6 +- awc/src/lib.rs | 21 +- awc/src/request.rs | 57 +- awc/src/response.rs | 146 ++- awc/src/sender.rs | 2 +- awc/src/ws.rs | 74 +- awc/tests/test_client.rs | 1057 ++++++++++---------- awc/tests/test_rustls_client.rs | 93 +- awc/tests/test_ssl_client.rs | 91 +- awc/tests/test_ws.rs | 92 +- src/app.rs | 386 ++++--- src/app_service.rs | 36 +- src/config.rs | 128 ++- src/data.rs | 153 ++- src/extract.rs | 30 +- src/lib.rs | 25 +- src/middleware/condition.rs | 66 +- src/middleware/defaultheaders.rs | 83 +- src/middleware/errhandlers.rs | 62 +- src/middleware/logger.rs | 22 +- src/middleware/normalize.rs | 84 +- src/request.rs | 122 ++- src/resource.rs | 357 +++---- src/responder.rs | 308 +++--- src/route.rs | 141 ++- src/scope.rs | 1103 ++++++++++---------- src/service.rs | 54 +- src/test.rs | 332 +++---- src/types/form.rs | 186 ++-- src/types/json.rs | 402 ++++---- src/types/mod.rs | 1 + src/types/path.rs | 177 ++-- src/types/payload.rs | 30 +- src/types/query.rs | 74 +- src/types/readlines.rs | 38 +- src/web.rs | 1 - test-server/Cargo.toml | 2 - test-server/src/lib.rs | 25 +- tests/test_httpserver.rs | 69 +- tests/test_server.rs | 1328 ++++++++++++------------- 80 files changed, 6502 insertions(+), 7237 deletions(-) diff --git a/.travis.yml b/.travis.yml index 683f77cc5..f10f82a48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,9 +36,12 @@ before_script: script: - cargo update - cargo check --all --no-default-features - - cargo test --all-features --all -- --nocapture - # - cd actix-http; cargo test --no-default-features --features="rustls" -- --nocapture; cd .. - # - cd awc; cargo test --no-default-features --features="rustls" -- --nocapture; cd .. + - | + if [[ "$TRAVIS_RUST_VERSION" == "stable" || "$TRAVIS_RUST_VERSION" == "beta" ]]; then + cargo test --all-features --all -- --nocapture + cd actix-http; cargo test --no-default-features --features="rustls" -- --nocapture; cd .. + cd awc; cargo test --no-default-features --features="rustls" -- --nocapture; cd .. + fi # Upload docs after_success: @@ -51,7 +54,7 @@ after_success: echo "Uploaded documentation" fi - | - if [[ "$TRAVIS_RUST_VERSION" == "nightly-2019-11-20" ]]; then + if [[ "$TRAVIS_RUST_VERSION" == "nightly-2019-11-20" ]]; then taskset -c 0 cargo tarpaulin --out Xml --all --all-features bash <(curl -s https://codecov.io/bash) echo "Uploaded code coverage" diff --git a/Cargo.toml b/Cargo.toml index dda01b481..a1875eb76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,7 +66,7 @@ fail = ["actix-http/fail"] openssl = ["open-ssl", "actix-server/openssl", "awc/openssl"] # rustls -# rustls = ["rust-tls", "actix-server/rustls", "awc/rustls"] +rustls = ["rust-tls", "actix-server/rustls", "awc/rustls"] [dependencies] actix-codec = "0.2.0-alpha.1" @@ -110,7 +110,6 @@ actix-http-test = "0.3.0-alpha.1" rand = "0.7" env_logger = "0.6" serde_derive = "1.0" -tokio-timer = "0.3.0-alpha.6" brotli2 = "0.3.2" flate2 = "1.0.2" @@ -135,19 +134,9 @@ awc = { path = "awc" } actix-codec = { git = "https://github.com/actix/actix-net.git" } actix-connect = { git = "https://github.com/actix/actix-net.git" } actix-rt = { git = "https://github.com/actix/actix-net.git" } +actix-macros = { git = "https://github.com/actix/actix-net.git" } actix-server = { git = "https://github.com/actix/actix-net.git" } actix-server-config = { git = "https://github.com/actix/actix-net.git" } actix-service = { git = "https://github.com/actix/actix-net.git" } actix-testing = { git = "https://github.com/actix/actix-net.git" } -actix-threadpool = { git = "https://github.com/actix/actix-net.git" } actix-utils = { git = "https://github.com/actix/actix-net.git" } - -# actix-codec = { path = "../actix-net/actix-codec" } -# actix-connect = { path = "../actix-net/actix-connect" } -# actix-rt = { path = "../actix-net/actix-rt" } -# actix-server = { path = "../actix-net/actix-server" } -# actix-server-config = { path = "../actix-net/actix-server-config" } -# actix-service = { path = "../actix-net/actix-service" } -# actix-testing = { path = "../actix-net/actix-testing" } -# actix-threadpool = { path = "../actix-net/actix-threadpool" } -# actix-utils = { path = "../actix-net/actix-utils" } diff --git a/actix-cors/Cargo.toml b/actix-cors/Cargo.toml index 11ad10334..ddb5f307e 100644 --- a/actix-cors/Cargo.toml +++ b/actix-cors/Cargo.toml @@ -21,3 +21,6 @@ actix-web = "2.0.0-alpha.1" actix-service = "1.0.0-alpha.1" derive_more = "0.99.2" futures = "0.3.1" + +[dev-dependencies] +actix-rt = "1.0.0-alpha.1" diff --git a/actix-cors/src/lib.rs b/actix-cors/src/lib.rs index db7e4cc4f..551e3bb4d 100644 --- a/actix-cors/src/lib.rs +++ b/actix-cors/src/lib.rs @@ -814,142 +814,136 @@ where #[cfg(test)] mod tests { use actix_service::{service_fn2, Transform}; - use actix_web::test::{self, block_on, TestRequest}; + use actix_web::test::{self, TestRequest}; use super::*; - #[test] + #[actix_rt::test] #[should_panic(expected = "Credentials are allowed, but the Origin is set to")] - fn cors_validates_illegal_allow_credentials() { + async fn cors_validates_illegal_allow_credentials() { let _cors = Cors::new().supports_credentials().send_wildcard().finish(); } - #[test] - fn validate_origin_allows_all_origins() { - block_on(async { - let mut cors = Cors::new() - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .to_srv_request(); + #[actix_rt::test] + async fn validate_origin_allows_all_origins() { + let mut cors = Cors::new() + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) + let resp = test::call_service(&mut cors, req).await; + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn default() { - block_on(async { - let mut cors = Cors::default() - .new_transform(test::ok_service()) - .await - .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .to_srv_request(); + #[actix_rt::test] + async fn default() { + let mut cors = Cors::default() + .new_transform(test::ok_service()) + .await + .unwrap(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) + let resp = test::call_service(&mut cors, req).await; + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn test_preflight() { - block_on(async { - let mut cors = Cors::new() - .send_wildcard() - .max_age(3600) - .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) - .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT]) - .allowed_header(header::CONTENT_TYPE) - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_preflight() { + let mut cors = Cors::new() + .send_wildcard() + .max_age(3600) + .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) + .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT]) + .allowed_header(header::CONTENT_TYPE) + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::OPTIONS) - .header(header::ACCESS_CONTROL_REQUEST_HEADERS, "X-Not-Allowed") - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .method(Method::OPTIONS) + .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; - assert_eq!(resp.status(), StatusCode::BAD_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; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "put") - .method(Method::OPTIONS) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .header(header::ACCESS_CONTROL_REQUEST_METHOD, "put") + .method(Method::OPTIONS) + .to_srv_request(); - assert!(cors.inner.validate_allowed_method(req.head()).is_err()); - assert!(cors.inner.validate_allowed_headers(req.head()).is_ok()); + 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( - header::ACCESS_CONTROL_REQUEST_HEADERS, - "AUTHORIZATION,ACCEPT", - ) - .method(Method::OPTIONS) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") + .header( + header::ACCESS_CONTROL_REQUEST_HEADERS, + "AUTHORIZATION,ACCEPT", + ) + .method(Method::OPTIONS) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"*"[..], - resp.headers() - .get(&header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); - assert_eq!( - &b"3600"[..], - resp.headers() - .get(&header::ACCESS_CONTROL_MAX_AGE) - .unwrap() - .as_bytes() - ); - let hdr = resp - .headers() - .get(&header::ACCESS_CONTROL_ALLOW_HEADERS) + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"*"[..], + resp.headers() + .get(&header::ACCESS_CONTROL_ALLOW_ORIGIN) .unwrap() - .to_str() - .unwrap(); - assert!(hdr.contains("authorization")); - assert!(hdr.contains("accept")); - assert!(hdr.contains("content-type")); - - let methods = resp - .headers() - .get(header::ACCESS_CONTROL_ALLOW_METHODS) + .as_bytes() + ); + assert_eq!( + &b"3600"[..], + resp.headers() + .get(&header::ACCESS_CONTROL_MAX_AGE) .unwrap() - .to_str() - .unwrap(); - assert!(methods.contains("POST")); - assert!(methods.contains("GET")); - assert!(methods.contains("OPTIONS")); + .as_bytes() + ); + let hdr = resp + .headers() + .get(&header::ACCESS_CONTROL_ALLOW_HEADERS) + .unwrap() + .to_str() + .unwrap(); + assert!(hdr.contains("authorization")); + assert!(hdr.contains("accept")); + assert!(hdr.contains("content-type")); - Rc::get_mut(&mut cors.inner).unwrap().preflight = false; + let methods = resp + .headers() + .get(header::ACCESS_CONTROL_ALLOW_METHODS) + .unwrap() + .to_str() + .unwrap(); + assert!(methods.contains("POST")); + assert!(methods.contains("GET")); + assert!(methods.contains("OPTIONS")); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") - .header( - header::ACCESS_CONTROL_REQUEST_HEADERS, - "AUTHORIZATION,ACCEPT", - ) - .method(Method::OPTIONS) - .to_srv_request(); + Rc::get_mut(&mut cors.inner).unwrap().preflight = false; - let resp = test::call_service(&mut cors, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) + let req = TestRequest::with_header("Origin", "https://www.example.com") + .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") + .header( + header::ACCESS_CONTROL_REQUEST_HEADERS, + "AUTHORIZATION,ACCEPT", + ) + .method(Method::OPTIONS) + .to_srv_request(); + + let resp = test::call_service(&mut cors, req).await; + assert_eq!(resp.status(), StatusCode::OK); } - // #[test] + // #[actix_rt::test] // #[should_panic(expected = "MissingOrigin")] - // fn test_validate_missing_origin() { + // async fn test_validate_missing_origin() { // let cors = Cors::build() // .allowed_origin("https://www.example.com") // .finish(); @@ -957,257 +951,245 @@ mod tests { // cors.start(&req).unwrap(); // } - #[test] + #[actix_rt::test] #[should_panic(expected = "OriginNotAllowed")] - fn test_validate_not_allowed_origin() { - block_on(async { - let cors = Cors::new() - .allowed_origin("https://www.example.com") - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); + async fn test_validate_not_allowed_origin() { + let cors = Cors::new() + .allowed_origin("https://www.example.com") + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.unknown.com") - .method(Method::GET) - .to_srv_request(); - cors.inner.validate_origin(req.head()).unwrap(); - cors.inner.validate_allowed_method(req.head()).unwrap(); - cors.inner.validate_allowed_headers(req.head()).unwrap(); - }) + let req = TestRequest::with_header("Origin", "https://www.unknown.com") + .method(Method::GET) + .to_srv_request(); + cors.inner.validate_origin(req.head()).unwrap(); + cors.inner.validate_allowed_method(req.head()).unwrap(); + cors.inner.validate_allowed_headers(req.head()).unwrap(); } - #[test] - fn test_validate_origin() { - block_on(async { - let mut cors = Cors::new() - .allowed_origin("https://www.example.com") - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_validate_origin() { + let mut cors = Cors::new() + .allowed_origin("https://www.example.com") + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::GET) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .method(Method::GET) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) + let resp = test::call_service(&mut cors, req).await; + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn test_no_origin_response() { - block_on(async { - let mut cors = Cors::new() - .disable_preflight() - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_no_origin_response() { + let mut cors = Cors::new() + .disable_preflight() + .finish() + .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; - assert!(resp - .headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .is_none()); + let req = TestRequest::default().method(Method::GET).to_srv_request(); + let resp = test::call_service(&mut cors, req).await; + assert!(resp + .headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .is_none()); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::OPTIONS) - .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"https://www.example.com"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); - }) - } - - #[test] - fn test_response() { - block_on(async { - let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; - let mut cors = Cors::new() - .send_wildcard() - .disable_preflight() - .max_age(3600) - .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) - .allowed_headers(exposed_headers.clone()) - .expose_headers(exposed_headers.clone()) - .allowed_header(header::CONTENT_TYPE) - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); - - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::OPTIONS) - .to_srv_request(); - - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"*"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); - assert_eq!( - &b"Origin"[..], - resp.headers().get(header::VARY).unwrap().as_bytes() - ); - - { - let headers = resp - .headers() - .get(header::ACCESS_CONTROL_EXPOSE_HEADERS) - .unwrap() - .to_str() - .unwrap() - .split(',') - .map(|s| s.trim()) - .collect::>(); - - for h in exposed_headers { - assert!(headers.contains(&h.as_str())); - } - } - - let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; - let mut cors = Cors::new() - .send_wildcard() - .disable_preflight() - .max_age(3600) - .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) - .allowed_headers(exposed_headers.clone()) - .expose_headers(exposed_headers.clone()) - .allowed_header(header::CONTENT_TYPE) - .finish() - .new_transform(service_fn2(|req: ServiceRequest| { - ok(req.into_response( - HttpResponse::Ok().header(header::VARY, "Accept").finish(), - )) - })) - .await - .unwrap(); - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::OPTIONS) - .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"Accept, Origin"[..], - resp.headers().get(header::VARY).unwrap().as_bytes() - ); - - let mut cors = Cors::new() - .disable_vary_header() - .allowed_origin("https://www.example.com") - .allowed_origin("https://www.google.com") - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); - - let req = TestRequest::with_header("Origin", "https://www.example.com") - .method(Method::OPTIONS) - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") - .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - - let origins_str = resp - .headers() + let req = TestRequest::with_header("Origin", "https://www.example.com") + .method(Method::OPTIONS) + .to_srv_request(); + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"https://www.example.com"[..], + resp.headers() .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) .unwrap() + .as_bytes() + ); + } + + #[actix_rt::test] + async fn test_response() { + let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; + let mut cors = Cors::new() + .send_wildcard() + .disable_preflight() + .max_age(3600) + .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) + .allowed_headers(exposed_headers.clone()) + .expose_headers(exposed_headers.clone()) + .allowed_header(header::CONTENT_TYPE) + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); + + let req = TestRequest::with_header("Origin", "https://www.example.com") + .method(Method::OPTIONS) + .to_srv_request(); + + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"*"[..], + resp.headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .unwrap() + .as_bytes() + ); + assert_eq!( + &b"Origin"[..], + resp.headers().get(header::VARY).unwrap().as_bytes() + ); + + { + let headers = resp + .headers() + .get(header::ACCESS_CONTROL_EXPOSE_HEADERS) + .unwrap() .to_str() - .unwrap(); + .unwrap() + .split(',') + .map(|s| s.trim()) + .collect::>(); - assert_eq!("https://www.example.com", origins_str); - }) + for h in exposed_headers { + assert!(headers.contains(&h.as_str())); + } + } + + let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; + let mut cors = Cors::new() + .send_wildcard() + .disable_preflight() + .max_age(3600) + .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) + .allowed_headers(exposed_headers.clone()) + .expose_headers(exposed_headers.clone()) + .allowed_header(header::CONTENT_TYPE) + .finish() + .new_transform(service_fn2(|req: ServiceRequest| { + ok(req.into_response( + HttpResponse::Ok().header(header::VARY, "Accept").finish(), + )) + })) + .await + .unwrap(); + let req = TestRequest::with_header("Origin", "https://www.example.com") + .method(Method::OPTIONS) + .to_srv_request(); + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"Accept, Origin"[..], + resp.headers().get(header::VARY).unwrap().as_bytes() + ); + + let mut cors = Cors::new() + .disable_vary_header() + .allowed_origin("https://www.example.com") + .allowed_origin("https://www.google.com") + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); + + let req = TestRequest::with_header("Origin", "https://www.example.com") + .method(Method::OPTIONS) + .header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST") + .to_srv_request(); + let resp = test::call_service(&mut cors, req).await; + + let origins_str = resp + .headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .unwrap() + .to_str() + .unwrap(); + + assert_eq!("https://www.example.com", origins_str); } - #[test] - fn test_multiple_origins() { - block_on(async { - let mut cors = Cors::new() - .allowed_origin("https://example.com") - .allowed_origin("https://example.org") - .allowed_methods(vec![Method::GET]) - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_multiple_origins() { + let mut cors = Cors::new() + .allowed_origin("https://example.com") + .allowed_origin("https://example.org") + .allowed_methods(vec![Method::GET]) + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); - let req = TestRequest::with_header("Origin", "https://example.com") - .method(Method::GET) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://example.com") + .method(Method::GET) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"https://example.com"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"https://example.com"[..], + resp.headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .unwrap() + .as_bytes() + ); - let req = TestRequest::with_header("Origin", "https://example.org") - .method(Method::GET) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://example.org") + .method(Method::GET) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"https://example.org"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); - }) + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"https://example.org"[..], + resp.headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .unwrap() + .as_bytes() + ); } - #[test] - fn test_multiple_origins_preflight() { - block_on(async { - let mut cors = Cors::new() - .allowed_origin("https://example.com") - .allowed_origin("https://example.org") - .allowed_methods(vec![Method::GET]) - .finish() - .new_transform(test::ok_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_multiple_origins_preflight() { + let mut cors = Cors::new() + .allowed_origin("https://example.com") + .allowed_origin("https://example.org") + .allowed_methods(vec![Method::GET]) + .finish() + .new_transform(test::ok_service()) + .await + .unwrap(); - let req = TestRequest::with_header("Origin", "https://example.com") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET") - .method(Method::OPTIONS) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://example.com") + .header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET") + .method(Method::OPTIONS) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"https://example.com"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"https://example.com"[..], + resp.headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .unwrap() + .as_bytes() + ); - let req = TestRequest::with_header("Origin", "https://example.org") - .header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET") - .method(Method::OPTIONS) - .to_srv_request(); + let req = TestRequest::with_header("Origin", "https://example.org") + .header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET") + .method(Method::OPTIONS) + .to_srv_request(); - let resp = test::call_service(&mut cors, req).await; - assert_eq!( - &b"https://example.org"[..], - resp.headers() - .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) - .unwrap() - .as_bytes() - ); - }) + let resp = test::call_service(&mut cors, req).await; + assert_eq!( + &b"https://example.org"[..], + resp.headers() + .get(header::ACCESS_CONTROL_ALLOW_ORIGIN) + .unwrap() + .as_bytes() + ); } } diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index f5318b72e..19366b902 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -32,4 +32,5 @@ percent-encoding = "2.1" v_htmlescape = "0.4" [dev-dependencies] +actix-rt = "1.0.0-alpha.1" actix-web = { version = "2.0.0-alpha.1", features=["openssl"] } diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 2f8a5c49c..ed8b6c3b9 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -12,7 +12,7 @@ use std::rc::Rc; use std::task::{Context, Poll}; use std::{cmp, io}; -use actix_service::boxed::{self, BoxedNewService, BoxedService}; +use actix_service::boxed::{self, BoxService, BoxServiceFactory}; use actix_service::{IntoServiceFactory, Service, ServiceFactory}; use actix_web::dev::{ AppService, HttpServiceFactory, Payload, ResourceDef, ServiceRequest, @@ -39,8 +39,8 @@ use self::error::{FilesError, UriSegmentError}; pub use crate::named::NamedFile; pub use crate::range::HttpRange; -type HttpService = BoxedService; -type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>; +type HttpService = BoxService; +type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; /// Return the MIME type associated with a filename extension (case-insensitive). /// If `ext` is empty or no associated type for the extension was found, returns @@ -644,11 +644,11 @@ mod tests { }; use actix_web::http::{Method, StatusCode}; use actix_web::middleware::Compress; - use actix_web::test::{self, block_on, TestRequest}; + use actix_web::test::{self, TestRequest}; use actix_web::{App, Responder}; - #[test] - fn test_file_extension_to_mime() { + #[actix_rt::test] + async fn test_file_extension_to_mime() { let m = file_extension_to_mime("jpg"); assert_eq!(m, mime::IMAGE_JPEG); @@ -659,678 +659,622 @@ mod tests { assert_eq!(m, mime::APPLICATION_OCTET_STREAM); } - #[test] - fn test_if_modified_since_without_if_none_match() { - block_on(async { - let file = NamedFile::open("Cargo.toml").unwrap(); - let since = - header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60))); + #[actix_rt::test] + async fn test_if_modified_since_without_if_none_match() { + let file = NamedFile::open("Cargo.toml").unwrap(); + let since = + header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60))); - let req = TestRequest::default() - .header(header::IF_MODIFIED_SINCE, since) - .to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_MODIFIED); - }) + let req = TestRequest::default() + .header(header::IF_MODIFIED_SINCE, since) + .to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_MODIFIED); } - #[test] - fn test_if_modified_since_with_if_none_match() { - block_on(async { - let file = NamedFile::open("Cargo.toml").unwrap(); - let since = - header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60))); + #[actix_rt::test] + async fn test_if_modified_since_with_if_none_match() { + let file = NamedFile::open("Cargo.toml").unwrap(); + let since = + header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60))); - let req = TestRequest::default() - .header(header::IF_NONE_MATCH, "miss_etag") - .header(header::IF_MODIFIED_SINCE, since) - .to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_ne!(resp.status(), StatusCode::NOT_MODIFIED); - }) + let req = TestRequest::default() + .header(header::IF_NONE_MATCH, "miss_etag") + .header(header::IF_MODIFIED_SINCE, since) + .to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_ne!(resp.status(), StatusCode::NOT_MODIFIED); } - #[test] - fn test_named_file_text() { - block_on(async { - assert!(NamedFile::open("test--").is_err()); - let mut file = NamedFile::open("Cargo.toml").unwrap(); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_text() { + assert!(NamedFile::open("test--").is_err()); + let mut file = NamedFile::open("Cargo.toml").unwrap(); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "text/x-toml" - ); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "inline; filename=\"Cargo.toml\"" - ); - }) + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "text/x-toml" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "inline; filename=\"Cargo.toml\"" + ); } - #[test] - fn test_named_file_content_disposition() { - block_on(async { - assert!(NamedFile::open("test--").is_err()); - let mut file = NamedFile::open("Cargo.toml").unwrap(); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_content_disposition() { + assert!(NamedFile::open("test--").is_err()); + let mut file = NamedFile::open("Cargo.toml").unwrap(); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "inline; filename=\"Cargo.toml\"" - ); + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "inline; filename=\"Cargo.toml\"" + ); - let file = NamedFile::open("Cargo.toml") - .unwrap() - .disable_content_disposition(); - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none()); - }) + let file = NamedFile::open("Cargo.toml") + .unwrap() + .disable_content_disposition(); + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none()); } - #[test] - fn test_named_file_non_ascii_file_name() { - block_on(async { - let mut file = - NamedFile::from_file(File::open("Cargo.toml").unwrap(), "貨物.toml") - .unwrap(); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_non_ascii_file_name() { + let mut file = + NamedFile::from_file(File::open("Cargo.toml").unwrap(), "貨物.toml") + .unwrap(); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "text/x-toml" - ); - assert_eq!( + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "text/x-toml" + ); + assert_eq!( resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), "inline; filename=\"貨物.toml\"; filename*=UTF-8''%E8%B2%A8%E7%89%A9.toml" ); - }) } - #[test] - fn test_named_file_set_content_type() { - block_on(async { - let mut file = NamedFile::open("Cargo.toml") - .unwrap() - .set_content_type(mime::TEXT_XML); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_set_content_type() { + let mut file = NamedFile::open("Cargo.toml") + .unwrap() + .set_content_type(mime::TEXT_XML); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "text/xml" - ); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "inline; filename=\"Cargo.toml\"" - ); - }) + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "text/xml" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "inline; filename=\"Cargo.toml\"" + ); } - #[test] - fn test_named_file_image() { - block_on(async { - let mut file = NamedFile::open("tests/test.png").unwrap(); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_image() { + let mut file = NamedFile::open("tests/test.png").unwrap(); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "image/png" - ); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "inline; filename=\"test.png\"" - ); - }) + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "image/png" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "inline; filename=\"test.png\"" + ); } - #[test] - fn test_named_file_image_attachment() { - block_on(async { - let cd = ContentDisposition { - disposition: DispositionType::Attachment, - parameters: vec![DispositionParam::Filename(String::from("test.png"))], - }; - let mut file = NamedFile::open("tests/test.png") - .unwrap() - .set_content_disposition(cd); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_image_attachment() { + let cd = ContentDisposition { + disposition: DispositionType::Attachment, + parameters: vec![DispositionParam::Filename(String::from("test.png"))], + }; + let mut file = NamedFile::open("tests/test.png") + .unwrap() + .set_content_disposition(cd); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "image/png" - ); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "attachment; filename=\"test.png\"" - ); - }) + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "image/png" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "attachment; filename=\"test.png\"" + ); } - #[test] - fn test_named_file_binary() { - block_on(async { - let mut file = NamedFile::open("tests/test.binary").unwrap(); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_binary() { + let mut file = NamedFile::open("tests/test.binary").unwrap(); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "application/octet-stream" - ); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "attachment; filename=\"test.binary\"" - ); - }) + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "application/octet-stream" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "attachment; filename=\"test.binary\"" + ); } - #[test] - fn test_named_file_status_code_text() { - block_on(async { - let mut file = NamedFile::open("Cargo.toml") - .unwrap() - .set_status_code(StatusCode::NOT_FOUND); - { - file.file(); - let _f: &File = &file; - } - { - let _f: &mut File = &mut file; - } + #[actix_rt::test] + async fn test_named_file_status_code_text() { + let mut file = NamedFile::open("Cargo.toml") + .unwrap() + .set_status_code(StatusCode::NOT_FOUND); + { + file.file(); + let _f: &File = &file; + } + { + let _f: &mut File = &mut file; + } - let req = TestRequest::default().to_http_request(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "text/x-toml" - ); - assert_eq!( - resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "inline; filename=\"Cargo.toml\"" - ); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) + let req = TestRequest::default().to_http_request(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "text/x-toml" + ); + assert_eq!( + resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), + "inline; filename=\"Cargo.toml\"" + ); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); } - #[test] - fn test_mime_override() { - block_on(async { - fn all_attachment(_: &mime::Name) -> DispositionType { - DispositionType::Attachment - } + #[actix_rt::test] + async fn test_mime_override() { + fn all_attachment(_: &mime::Name) -> DispositionType { + DispositionType::Attachment + } - let mut srv = test::init_service( - App::new().service( - Files::new("/", ".") - .mime_override(all_attachment) - .index_file("Cargo.toml"), - ), - ) - .await; + let mut srv = test::init_service( + App::new().service( + Files::new("/", ".") + .mime_override(all_attachment) + .index_file("Cargo.toml"), + ), + ) + .await; - let request = TestRequest::get().uri("/").to_request(); - let response = test::call_service(&mut srv, request).await; - assert_eq!(response.status(), StatusCode::OK); + let request = TestRequest::get().uri("/").to_request(); + let response = test::call_service(&mut srv, request).await; + assert_eq!(response.status(), StatusCode::OK); - let content_disposition = response - .headers() - .get(header::CONTENT_DISPOSITION) - .expect("To have CONTENT_DISPOSITION"); - let content_disposition = content_disposition - .to_str() - .expect("Convert CONTENT_DISPOSITION to str"); - assert_eq!(content_disposition, "attachment; filename=\"Cargo.toml\""); - }) + let content_disposition = response + .headers() + .get(header::CONTENT_DISPOSITION) + .expect("To have CONTENT_DISPOSITION"); + let content_disposition = content_disposition + .to_str() + .expect("Convert CONTENT_DISPOSITION to str"); + assert_eq!(content_disposition, "attachment; filename=\"Cargo.toml\""); } - #[test] - fn test_named_file_ranges_status_code() { - block_on(async { - let mut srv = test::init_service( - App::new().service(Files::new("/test", ".").index_file("Cargo.toml")), - ) - .await; + #[actix_rt::test] + async fn test_named_file_ranges_status_code() { + let mut srv = test::init_service( + App::new().service(Files::new("/test", ".").index_file("Cargo.toml")), + ) + .await; - // Valid range header - let request = TestRequest::get() - .uri("/t%65st/Cargo.toml") - .header(header::RANGE, "bytes=10-20") - .to_request(); - let response = test::call_service(&mut srv, request).await; - assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT); + // Valid range header + let request = TestRequest::get() + .uri("/t%65st/Cargo.toml") + .header(header::RANGE, "bytes=10-20") + .to_request(); + let response = test::call_service(&mut srv, request).await; + assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT); - // Invalid range header - let request = TestRequest::get() - .uri("/t%65st/Cargo.toml") - .header(header::RANGE, "bytes=1-0") - .to_request(); - let response = test::call_service(&mut srv, request).await; + // Invalid range header + let request = TestRequest::get() + .uri("/t%65st/Cargo.toml") + .header(header::RANGE, "bytes=1-0") + .to_request(); + let response = test::call_service(&mut srv, request).await; - assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE); - }) + assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE); } - #[test] - fn test_named_file_content_range_headers() { - block_on(async { - let mut srv = test::init_service( - App::new() - .service(Files::new("/test", ".").index_file("tests/test.binary")), - ) - .await; + #[actix_rt::test] + async fn test_named_file_content_range_headers() { + let mut srv = test::init_service( + App::new().service(Files::new("/test", ".").index_file("tests/test.binary")), + ) + .await; - // Valid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .header(header::RANGE, "bytes=10-20") - .to_request(); + // Valid range header + let request = TestRequest::get() + .uri("/t%65st/tests/test.binary") + .header(header::RANGE, "bytes=10-20") + .to_request(); - let response = test::call_service(&mut srv, request).await; - let contentrange = response - .headers() - .get(header::CONTENT_RANGE) + let response = test::call_service(&mut srv, request).await; + let contentrange = response + .headers() + .get(header::CONTENT_RANGE) + .unwrap() + .to_str() + .unwrap(); + + assert_eq!(contentrange, "bytes 10-20/100"); + + // Invalid range header + let request = TestRequest::get() + .uri("/t%65st/tests/test.binary") + .header(header::RANGE, "bytes=10-5") + .to_request(); + let response = test::call_service(&mut srv, request).await; + + let contentrange = response + .headers() + .get(header::CONTENT_RANGE) + .unwrap() + .to_str() + .unwrap(); + + assert_eq!(contentrange, "bytes */100"); + } + + #[actix_rt::test] + async fn test_named_file_content_length_headers() { + // use actix_web::body::{MessageBody, ResponseBody}; + + let mut srv = test::init_service( + App::new().service(Files::new("test", ".").index_file("tests/test.binary")), + ) + .await; + + // Valid range header + let request = TestRequest::get() + .uri("/t%65st/tests/test.binary") + .header(header::RANGE, "bytes=10-20") + .to_request(); + let _response = test::call_service(&mut srv, request).await; + + // let contentlength = response + // .headers() + // .get(header::CONTENT_LENGTH) + // .unwrap() + // .to_str() + // .unwrap(); + // assert_eq!(contentlength, "11"); + + // Invalid range header + let request = TestRequest::get() + .uri("/t%65st/tests/test.binary") + .header(header::RANGE, "bytes=10-8") + .to_request(); + let response = test::call_service(&mut srv, request).await; + assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE); + + // Without range header + let request = TestRequest::get() + .uri("/t%65st/tests/test.binary") + // .no_default_headers() + .to_request(); + let _response = test::call_service(&mut srv, request).await; + + // let contentlength = response + // .headers() + // .get(header::CONTENT_LENGTH) + // .unwrap() + // .to_str() + // .unwrap(); + // assert_eq!(contentlength, "100"); + + // chunked + let request = TestRequest::get() + .uri("/t%65st/tests/test.binary") + .to_request(); + let response = test::call_service(&mut srv, request).await; + + // with enabled compression + // { + // let te = response + // .headers() + // .get(header::TRANSFER_ENCODING) + // .unwrap() + // .to_str() + // .unwrap(); + // assert_eq!(te, "chunked"); + // } + + let bytes = test::read_body(response).await; + let data = Bytes::from(fs::read("tests/test.binary").unwrap()); + assert_eq!(bytes, data); + } + + #[actix_rt::test] + async fn test_head_content_length_headers() { + let mut srv = test::init_service( + App::new().service(Files::new("test", ".").index_file("tests/test.binary")), + ) + .await; + + // Valid range header + let request = TestRequest::default() + .method(Method::HEAD) + .uri("/t%65st/tests/test.binary") + .to_request(); + let _response = test::call_service(&mut srv, request).await; + + // TODO: fix check + // let contentlength = response + // .headers() + // .get(header::CONTENT_LENGTH) + // .unwrap() + // .to_str() + // .unwrap(); + // assert_eq!(contentlength, "100"); + } + + #[actix_rt::test] + async fn test_static_files_with_spaces() { + let mut srv = test::init_service( + App::new().service(Files::new("/", ".").index_file("Cargo.toml")), + ) + .await; + let request = TestRequest::get() + .uri("/tests/test%20space.binary") + .to_request(); + let response = test::call_service(&mut srv, request).await; + assert_eq!(response.status(), StatusCode::OK); + + let bytes = test::read_body(response).await; + let data = Bytes::from(fs::read("tests/test space.binary").unwrap()); + assert_eq!(bytes, data); + } + + #[actix_rt::test] + async fn test_files_not_allowed() { + let mut srv = test::init_service(App::new().service(Files::new("/", "."))).await; + + let req = TestRequest::default() + .uri("/Cargo.toml") + .method(Method::POST) + .to_request(); + + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + + let mut srv = test::init_service(App::new().service(Files::new("/", "."))).await; + let req = TestRequest::default() + .method(Method::PUT) + .uri("/Cargo.toml") + .to_request(); + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + } + + #[actix_rt::test] + async fn test_files_guards() { + let mut srv = test::init_service( + App::new().service(Files::new("/", ".").use_guards(guard::Post())), + ) + .await; + + let req = TestRequest::default() + .uri("/Cargo.toml") + .method(Method::POST) + .to_request(); + + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + } + + #[actix_rt::test] + async fn test_named_file_content_encoding() { + let mut srv = test::init_service(App::new().wrap(Compress::default()).service( + web::resource("/").to(|| { + async { + NamedFile::open("Cargo.toml") + .unwrap() + .set_content_encoding(header::ContentEncoding::Identity) + } + }), + )) + .await; + + let request = TestRequest::get() + .uri("/") + .header(header::ACCEPT_ENCODING, "gzip") + .to_request(); + let res = test::call_service(&mut srv, request).await; + assert_eq!(res.status(), StatusCode::OK); + assert!(!res.headers().contains_key(header::CONTENT_ENCODING)); + } + + #[actix_rt::test] + async fn test_named_file_content_encoding_gzip() { + let mut srv = test::init_service(App::new().wrap(Compress::default()).service( + web::resource("/").to(|| { + async { + NamedFile::open("Cargo.toml") + .unwrap() + .set_content_encoding(header::ContentEncoding::Gzip) + } + }), + )) + .await; + + let request = TestRequest::get() + .uri("/") + .header(header::ACCEPT_ENCODING, "gzip") + .to_request(); + let res = test::call_service(&mut srv, request).await; + assert_eq!(res.status(), StatusCode::OK); + assert_eq!( + res.headers() + .get(header::CONTENT_ENCODING) .unwrap() .to_str() - .unwrap(); - - assert_eq!(contentrange, "bytes 10-20/100"); - - // Invalid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .header(header::RANGE, "bytes=10-5") - .to_request(); - let response = test::call_service(&mut srv, request).await; - - let contentrange = response - .headers() - .get(header::CONTENT_RANGE) - .unwrap() - .to_str() - .unwrap(); - - assert_eq!(contentrange, "bytes */100"); - }) + .unwrap(), + "gzip" + ); } - #[test] - fn test_named_file_content_length_headers() { - block_on(async { - // use actix_web::body::{MessageBody, ResponseBody}; - - let mut srv = test::init_service( - App::new() - .service(Files::new("test", ".").index_file("tests/test.binary")), - ) - .await; - - // Valid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .header(header::RANGE, "bytes=10-20") - .to_request(); - let _response = test::call_service(&mut srv, request).await; - - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "11"); - - // Invalid range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .header(header::RANGE, "bytes=10-8") - .to_request(); - let response = test::call_service(&mut srv, request).await; - assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE); - - // Without range header - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - // .no_default_headers() - .to_request(); - let _response = test::call_service(&mut srv, request).await; - - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "100"); - - // chunked - let request = TestRequest::get() - .uri("/t%65st/tests/test.binary") - .to_request(); - let response = test::call_service(&mut srv, request).await; - - // with enabled compression - // { - // let te = response - // .headers() - // .get(header::TRANSFER_ENCODING) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(te, "chunked"); - // } - - let bytes = test::read_body(response).await; - let data = Bytes::from(fs::read("tests/test.binary").unwrap()); - assert_eq!(bytes, data); - }) + #[actix_rt::test] + async fn test_named_file_allowed_method() { + let req = TestRequest::default().method(Method::GET).to_http_request(); + let file = NamedFile::open("Cargo.toml").unwrap(); + let resp = file.respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn test_head_content_length_headers() { - block_on(async { - let mut srv = test::init_service( - App::new() - .service(Files::new("test", ".").index_file("tests/test.binary")), - ) - .await; + #[actix_rt::test] + async fn test_static_files() { + let mut srv = test::init_service( + App::new().service(Files::new("/", ".").show_files_listing()), + ) + .await; + let req = TestRequest::with_uri("/missing").to_request(); - // Valid range header - let request = TestRequest::default() - .method(Method::HEAD) - .uri("/t%65st/tests/test.binary") - .to_request(); - let _response = test::call_service(&mut srv, request).await; + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::NOT_FOUND); - // TODO: fix check - // let contentlength = response - // .headers() - // .get(header::CONTENT_LENGTH) - // .unwrap() - // .to_str() - // .unwrap(); - // assert_eq!(contentlength, "100"); - }) + let mut srv = test::init_service(App::new().service(Files::new("/", "."))).await; + + let req = TestRequest::default().to_request(); + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + + let mut srv = test::init_service( + App::new().service(Files::new("/", ".").show_files_listing()), + ) + .await; + let req = TestRequest::with_uri("/tests").to_request(); + let resp = test::call_service(&mut srv, req).await; + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + "text/html; charset=utf-8" + ); + + let bytes = test::read_body(resp).await; + assert!(format!("{:?}", bytes).contains("/tests/test.png")); } - #[test] - fn test_static_files_with_spaces() { - block_on(async { - let mut srv = test::init_service( - App::new().service(Files::new("/", ".").index_file("Cargo.toml")), - ) - .await; - let request = TestRequest::get() - .uri("/tests/test%20space.binary") - .to_request(); - let response = test::call_service(&mut srv, request).await; - assert_eq!(response.status(), StatusCode::OK); + #[actix_rt::test] + async fn test_redirect_to_slash_directory() { + // should not redirect if no index + let mut srv = test::init_service( + App::new().service(Files::new("/", ".").redirect_to_slash_directory()), + ) + .await; + let req = TestRequest::with_uri("/tests").to_request(); + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::NOT_FOUND); - let bytes = test::read_body(response).await; - let data = Bytes::from(fs::read("tests/test space.binary").unwrap()); - assert_eq!(bytes, data); - }) + // should redirect if index present + let mut srv = test::init_service( + App::new().service( + Files::new("/", ".") + .index_file("test.png") + .redirect_to_slash_directory(), + ), + ) + .await; + let req = TestRequest::with_uri("/tests").to_request(); + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::FOUND); + + // should not redirect if the path is wrong + let req = TestRequest::with_uri("/not_existing").to_request(); + let resp = test::call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::NOT_FOUND); } - #[test] - fn test_files_not_allowed() { - block_on(async { - let mut srv = - test::init_service(App::new().service(Files::new("/", "."))).await; - - let req = TestRequest::default() - .uri("/Cargo.toml") - .method(Method::POST) - .to_request(); - - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - - let mut srv = - test::init_service(App::new().service(Files::new("/", "."))).await; - let req = TestRequest::default() - .method(Method::PUT) - .uri("/Cargo.toml") - .to_request(); - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - }) - } - - #[test] - fn test_files_guards() { - block_on(async { - let mut srv = test::init_service( - App::new().service(Files::new("/", ".").use_guards(guard::Post())), - ) - .await; - - let req = TestRequest::default() - .uri("/Cargo.toml") - .method(Method::POST) - .to_request(); - - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) - } - - #[test] - fn test_named_file_content_encoding() { - block_on(async { - let mut srv = - test::init_service(App::new().wrap(Compress::default()).service( - web::resource("/").to(|| { - async { - NamedFile::open("Cargo.toml") - .unwrap() - .set_content_encoding(header::ContentEncoding::Identity) - } - }), - )) - .await; - - let request = TestRequest::get() - .uri("/") - .header(header::ACCEPT_ENCODING, "gzip") - .to_request(); - let res = test::call_service(&mut srv, request).await; - assert_eq!(res.status(), StatusCode::OK); - assert!(!res.headers().contains_key(header::CONTENT_ENCODING)); - }) - } - - #[test] - fn test_named_file_content_encoding_gzip() { - block_on(async { - let mut srv = - test::init_service(App::new().wrap(Compress::default()).service( - web::resource("/").to(|| { - async { - NamedFile::open("Cargo.toml") - .unwrap() - .set_content_encoding(header::ContentEncoding::Gzip) - } - }), - )) - .await; - - let request = TestRequest::get() - .uri("/") - .header(header::ACCEPT_ENCODING, "gzip") - .to_request(); - let res = test::call_service(&mut srv, request).await; - assert_eq!(res.status(), StatusCode::OK); - assert_eq!( - res.headers() - .get(header::CONTENT_ENCODING) - .unwrap() - .to_str() - .unwrap(), - "gzip" - ); - }) - } - - #[test] - fn test_named_file_allowed_method() { - block_on(async { - let req = TestRequest::default().method(Method::GET).to_http_request(); - let file = NamedFile::open("Cargo.toml").unwrap(); - let resp = file.respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) - } - - #[test] - fn test_static_files() { - block_on(async { - let mut srv = test::init_service( - App::new().service(Files::new("/", ".").show_files_listing()), - ) - .await; - let req = TestRequest::with_uri("/missing").to_request(); - - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - let mut srv = - test::init_service(App::new().service(Files::new("/", "."))).await; - - let req = TestRequest::default().to_request(); - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - let mut srv = test::init_service( - App::new().service(Files::new("/", ".").show_files_listing()), - ) - .await; - let req = TestRequest::with_uri("/tests").to_request(); - let resp = test::call_service(&mut srv, req).await; - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - "text/html; charset=utf-8" - ); - - let bytes = test::read_body(resp).await; - assert!(format!("{:?}", bytes).contains("/tests/test.png")); - }) - } - - #[test] - fn test_redirect_to_slash_directory() { - block_on(async { - // should not redirect if no index - let mut srv = test::init_service( - App::new().service(Files::new("/", ".").redirect_to_slash_directory()), - ) - .await; - let req = TestRequest::with_uri("/tests").to_request(); - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - // should redirect if index present - let mut srv = test::init_service( - App::new().service( - Files::new("/", ".") - .index_file("test.png") - .redirect_to_slash_directory(), - ), - ) - .await; - let req = TestRequest::with_uri("/tests").to_request(); - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::FOUND); - - // should not redirect if the path is wrong - let req = TestRequest::with_uri("/not_existing").to_request(); - let resp = test::call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) - } - - #[test] - fn test_static_files_bad_directory() { + #[actix_rt::test] + async fn test_static_files_bad_directory() { let _st: Files = Files::new("/", "missing"); let _st: Files = Files::new("/", "Cargo.toml"); } - #[test] - fn test_default_handler_file_missing() { - block_on(async { - let mut st = Files::new("/", ".") - .default_handler(|req: ServiceRequest| { - ok(req.into_response(HttpResponse::Ok().body("default content"))) - }) - .new_service(&()) - .await - .unwrap(); - let req = TestRequest::with_uri("/missing").to_srv_request(); + #[actix_rt::test] + async fn test_default_handler_file_missing() { + let mut st = Files::new("/", ".") + .default_handler(|req: ServiceRequest| { + ok(req.into_response(HttpResponse::Ok().body("default content"))) + }) + .new_service(&()) + .await + .unwrap(); + let req = TestRequest::with_uri("/missing").to_srv_request(); - let resp = test::call_service(&mut st, req).await; - assert_eq!(resp.status(), StatusCode::OK); - let bytes = test::read_body(resp).await; - assert_eq!(bytes, Bytes::from_static(b"default content")); - }) + let resp = test::call_service(&mut st, req).await; + assert_eq!(resp.status(), StatusCode::OK); + let bytes = test::read_body(resp).await; + assert_eq!(bytes, Bytes::from_static(b"default content")); } - // #[test] - // fn test_serve_index() { + // #[actix_rt::test] + // async fn test_serve_index() { // let st = Files::new(".").index_file("test.binary"); // let req = TestRequest::default().uri("/tests").finish(); @@ -1375,8 +1319,8 @@ mod tests { // assert_eq!(resp.status(), StatusCode::NOT_FOUND); // } - // #[test] - // fn test_serve_index_nested() { + // #[actix_rt::test] + // async fn test_serve_index_nested() { // let st = Files::new(".").index_file("mod.rs"); // let req = TestRequest::default().uri("/src/client").finish(); // let resp = st.handle(&req).respond_to(&req).unwrap(); @@ -1392,7 +1336,7 @@ mod tests { // ); // } - // #[test] + // #[actix_rt::test] // fn integration_serve_index() { // let mut srv = test::TestServer::with_factory(|| { // App::new().handler( @@ -1425,7 +1369,7 @@ mod tests { // assert_eq!(response.status(), StatusCode::NOT_FOUND); // } - // #[test] + // #[actix_rt::test] // fn integration_percent_encoded() { // let mut srv = test::TestServer::with_factory(|| { // App::new().handler( @@ -1443,8 +1387,8 @@ mod tests { // assert_eq!(response.status(), StatusCode::OK); // } - #[test] - fn test_path_buf() { + #[actix_rt::test] + async fn test_path_buf() { assert_eq!( PathBufWrp::get_pathbuf("/test/.tt").map(|t| t.0), Err(UriSegmentError::BadStart('.')) diff --git a/actix-framed/src/test.rs b/actix-framed/src/test.rs index b90a493dc..7969d51ff 100644 --- a/actix-framed/src/test.rs +++ b/actix-framed/src/test.rs @@ -7,7 +7,6 @@ use actix_http::http::header::{Header, HeaderName, IntoHeaderValue}; use actix_http::http::{HttpTryFrom, Method, Uri, Version}; use actix_http::test::{TestBuffer, TestRequest as HttpTestRequest}; use actix_router::{Path, Url}; -use actix_rt::Runtime; use crate::{FramedRequest, State}; @@ -119,13 +118,12 @@ impl TestRequest { } /// This method generates `FramedRequest` instance and executes async handler - pub fn run(self, f: F) -> Result + pub async fn run(self, f: F) -> Result where F: FnOnce(FramedRequest) -> R, R: Future>, { - let mut rt = Runtime::new().unwrap(); - rt.block_on(f(self.finish())) + f(self.finish()).await } } diff --git a/actix-framed/tests/test_server.rs b/actix-framed/tests/test_server.rs index 6e4bb6ada..4d1028d31 100644 --- a/actix-framed/tests/test_server.rs +++ b/actix-framed/tests/test_server.rs @@ -1,6 +1,6 @@ use actix_codec::{AsyncRead, AsyncWrite}; use actix_http::{body, http::StatusCode, ws, Error, HttpService, Response}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_service::{pipeline_factory, IntoServiceFactory, ServiceFactory}; use actix_utils::framed::FramedTransport; use bytes::{Bytes, BytesMut}; @@ -38,126 +38,121 @@ async fn service(msg: ws::Frame) -> Result { Ok(msg) } -#[test] -fn test_simple() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build() - .upgrade( - FramedApp::new() - .service(FramedRoute::get("/index.html").to(ws_service)), - ) - .finish(|_| future::ok::<_, Error>(Response::NotFound())) - }); - - assert!(srv.ws_at("/test").await.is_err()); - - // client service - let mut framed = srv.ws_at("/index.html").await.unwrap(); - framed - .send(ws::Message::Text("text".to_string())) - .await - .unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Text(Some(BytesMut::from("text"))) - ); - - framed - .send(ws::Message::Binary("text".into())) - .await - .unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) - ); - - framed.send(ws::Message::Ping("text".into())).await.unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Pong("text".to_string().into()) - ); - - framed - .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) - .await - .unwrap(); - - let (item, _) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Close(Some(ws::CloseCode::Normal.into())) - ); - }) -} - -#[test] -fn test_service() { - block_on(async { - let mut srv = TestServer::start(|| { - pipeline_factory(actix_http::h1::OneRequest::new().map_err(|_| ())).and_then( - pipeline_factory( - pipeline_factory(VerifyWebSockets::default()) - .then(SendError::default()) - .map_err(|_| ()), - ) - .and_then( - FramedApp::new() - .service(FramedRoute::get("/index.html").to(ws_service)) - .into_factory() - .map_err(|_| ()), - ), +#[actix_rt::test] +async fn test_simple() { + let mut srv = TestServer::start(|| { + HttpService::build() + .upgrade( + FramedApp::new().service(FramedRoute::get("/index.html").to(ws_service)), ) - }); + .finish(|_| future::ok::<_, Error>(Response::NotFound())) + }); - // non ws request - let res = srv.get("/index.html").send().await.unwrap(); - assert_eq!(res.status(), StatusCode::BAD_REQUEST); + assert!(srv.ws_at("/test").await.is_err()); - // not found - assert!(srv.ws_at("/test").await.is_err()); + // client service + let mut framed = srv.ws_at("/index.html").await.unwrap(); + framed + .send(ws::Message::Text("text".to_string())) + .await + .unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Text(Some(BytesMut::from("text"))) + ); - // client service - let mut framed = srv.ws_at("/index.html").await.unwrap(); - framed - .send(ws::Message::Text("text".to_string())) - .await - .unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Text(Some(BytesMut::from("text"))) - ); + framed + .send(ws::Message::Binary("text".into())) + .await + .unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) + ); - framed - .send(ws::Message::Binary("text".into())) - .await - .unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) - ); + framed.send(ws::Message::Ping("text".into())).await.unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Pong("text".to_string().into()) + ); - framed.send(ws::Message::Ping("text".into())).await.unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Pong("text".to_string().into()) - ); + framed + .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) + .await + .unwrap(); - framed - .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) - .await - .unwrap(); - - let (item, _) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Close(Some(ws::CloseCode::Normal.into())) - ); - }) + let (item, _) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Close(Some(ws::CloseCode::Normal.into())) + ); +} + +#[actix_rt::test] +async fn test_service() { + let mut srv = TestServer::start(|| { + pipeline_factory(actix_http::h1::OneRequest::new().map_err(|_| ())).and_then( + pipeline_factory( + pipeline_factory(VerifyWebSockets::default()) + .then(SendError::default()) + .map_err(|_| ()), + ) + .and_then( + FramedApp::new() + .service(FramedRoute::get("/index.html").to(ws_service)) + .into_factory() + .map_err(|_| ()), + ), + ) + }); + + // non ws request + let res = srv.get("/index.html").send().await.unwrap(); + assert_eq!(res.status(), StatusCode::BAD_REQUEST); + + // not found + assert!(srv.ws_at("/test").await.is_err()); + + // client service + let mut framed = srv.ws_at("/index.html").await.unwrap(); + framed + .send(ws::Message::Text("text".to_string())) + .await + .unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Text(Some(BytesMut::from("text"))) + ); + + framed + .send(ws::Message::Binary("text".into())) + .await + .unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) + ); + + framed.send(ws::Message::Ping("text".into())).await.unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Pong("text".to_string().into()) + ); + + framed + .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) + .await + .unwrap(); + + let (item, _) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Close(Some(ws::CloseCode::Normal.into())) + ); } diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index cf390e796..cfed0bf14 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -29,7 +29,7 @@ default = [] openssl = ["open-ssl", "actix-connect/openssl", "tokio-openssl"] # rustls support -# rustls = ["rust-tls", "webpki-roots", "actix-connect/rustls"] +rustls = ["rust-tls", "webpki-roots", "actix-connect/rustls"] # brotli encoding, requires c compiler brotli = ["brotli2"] @@ -52,6 +52,7 @@ actix-codec = "0.2.0-alpha.1" actix-connect = "1.0.0-alpha.1" actix-utils = "0.5.0-alpha.1" actix-server-config = "0.3.0-alpha.1" +actix-rt = "1.0.0-alpha.1" actix-threadpool = "0.2.0-alpha.1" base64 = "0.10" @@ -83,11 +84,7 @@ slab = "0.4" serde_urlencoded = "0.6.1" time = "0.1.42" -tokio = "=0.2.0-alpha.6" -tokio-io = "=0.2.0-alpha.6" tokio-net = "=0.2.0-alpha.6" -tokio-timer = "0.3.0-alpha.6" -tokio-executor = "=0.2.0-alpha.6" trust-dns-resolver = { version="0.18.0-alpha.1", default-features = false } # for secure cookie @@ -106,8 +103,7 @@ rust-tls = { version = "0.16.0", package="rustls", optional = true } webpki-roots = { version = "0.18", optional = true } [dev-dependencies] -actix-rt = "1.0.0-alpha.1" -actix-server = { version = "0.8.0-alpha.1", features=["openssl"] } +actix-server = { version = "0.8.0-alpha.1", features=["openssl", "rustls"] } actix-connect = { version = "1.0.0-alpha.1", features=["openssl"] } actix-http-test = { version = "0.3.0-alpha.1", features=["openssl"] } env_logger = "0.6" diff --git a/actix-http/src/body.rs b/actix-http/src/body.rs index 1d3a43fe5..b69c21eaa 100644 --- a/actix-http/src/body.rs +++ b/actix-http/src/body.rs @@ -432,8 +432,7 @@ where #[cfg(test)] mod tests { use super::*; - use actix_http_test::block_on; - use futures::future::{lazy, poll_fn}; + use futures::future::poll_fn; impl Body { pub(crate) fn get_ref(&self) -> &[u8] { @@ -453,21 +452,21 @@ mod tests { } } - #[test] - fn test_static_str() { + #[actix_rt::test] + async fn test_static_str() { assert_eq!(Body::from("").size(), BodySize::Sized(0)); assert_eq!(Body::from("test").size(), BodySize::Sized(4)); assert_eq!(Body::from("test").get_ref(), b"test"); assert_eq!("test".size(), BodySize::Sized(4)); assert_eq!( - block_on(poll_fn(|cx| "test".poll_next(cx))).unwrap().ok(), + poll_fn(|cx| "test".poll_next(cx)).await.unwrap().ok(), Some(Bytes::from("test")) ); } - #[test] - fn test_static_bytes() { + #[actix_rt::test] + async fn test_static_bytes() { assert_eq!(Body::from(b"test".as_ref()).size(), BodySize::Sized(4)); assert_eq!(Body::from(b"test".as_ref()).get_ref(), b"test"); assert_eq!( @@ -478,55 +477,57 @@ mod tests { assert_eq!((&b"test"[..]).size(), BodySize::Sized(4)); assert_eq!( - block_on(poll_fn(|cx| (&b"test"[..]).poll_next(cx))) + poll_fn(|cx| (&b"test"[..]).poll_next(cx)) + .await .unwrap() .ok(), Some(Bytes::from("test")) ); } - #[test] - fn test_vec() { + #[actix_rt::test] + async fn test_vec() { assert_eq!(Body::from(Vec::from("test")).size(), BodySize::Sized(4)); assert_eq!(Body::from(Vec::from("test")).get_ref(), b"test"); assert_eq!(Vec::from("test").size(), BodySize::Sized(4)); assert_eq!( - block_on(poll_fn(|cx| Vec::from("test").poll_next(cx))) + poll_fn(|cx| Vec::from("test").poll_next(cx)) + .await .unwrap() .ok(), Some(Bytes::from("test")) ); } - #[test] - fn test_bytes() { + #[actix_rt::test] + async fn test_bytes() { let mut b = Bytes::from("test"); assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4)); assert_eq!(Body::from(b.clone()).get_ref(), b"test"); assert_eq!(b.size(), BodySize::Sized(4)); assert_eq!( - block_on(poll_fn(|cx| b.poll_next(cx))).unwrap().ok(), + poll_fn(|cx| b.poll_next(cx)).await.unwrap().ok(), Some(Bytes::from("test")) ); } - #[test] - fn test_bytes_mut() { + #[actix_rt::test] + async fn test_bytes_mut() { let mut b = BytesMut::from("test"); assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4)); assert_eq!(Body::from(b.clone()).get_ref(), b"test"); assert_eq!(b.size(), BodySize::Sized(4)); assert_eq!( - block_on(poll_fn(|cx| b.poll_next(cx))).unwrap().ok(), + poll_fn(|cx| b.poll_next(cx)).await.unwrap().ok(), Some(Bytes::from("test")) ); } - #[test] - fn test_string() { + #[actix_rt::test] + async fn test_string() { let mut b = "test".to_owned(); assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4)); assert_eq!(Body::from(b.clone()).get_ref(), b"test"); @@ -535,26 +536,26 @@ mod tests { assert_eq!(b.size(), BodySize::Sized(4)); assert_eq!( - block_on(poll_fn(|cx| b.poll_next(cx))).unwrap().ok(), + poll_fn(|cx| b.poll_next(cx)).await.unwrap().ok(), Some(Bytes::from("test")) ); } - #[test] - fn test_unit() { + #[actix_rt::test] + async fn test_unit() { assert_eq!(().size(), BodySize::Empty); - assert!(block_on(poll_fn(|cx| ().poll_next(cx))).is_none()); + assert!(poll_fn(|cx| ().poll_next(cx)).await.is_none()); } - #[test] - fn test_box() { + #[actix_rt::test] + async fn test_box() { let mut val = Box::new(()); assert_eq!(val.size(), BodySize::Empty); - assert!(block_on(poll_fn(|cx| val.poll_next(cx))).is_none()); + assert!(poll_fn(|cx| val.poll_next(cx)).await.is_none()); } - #[test] - fn test_body_eq() { + #[actix_rt::test] + async fn test_body_eq() { assert!(Body::None == Body::None); assert!(Body::None != Body::Empty); assert!(Body::Empty == Body::Empty); @@ -566,15 +567,15 @@ mod tests { assert!(Body::Bytes(Bytes::from_static(b"1")) != Body::None); } - #[test] - fn test_body_debug() { + #[actix_rt::test] + async fn test_body_debug() { assert!(format!("{:?}", Body::None).contains("Body::None")); assert!(format!("{:?}", Body::Empty).contains("Body::Empty")); assert!(format!("{:?}", Body::Bytes(Bytes::from_static(b"1"))).contains("1")); } - #[test] - fn test_serde_json() { + #[actix_rt::test] + async fn test_serde_json() { use serde_json::json; assert_eq!( Body::from(serde_json::Value::String("test".into())).size(), diff --git a/actix-http/src/client/connector.rs b/actix-http/src/client/connector.rs index 1895f5306..eaa3d97e4 100644 --- a/actix-http/src/client/connector.rs +++ b/actix-http/src/client/connector.rs @@ -1,8 +1,5 @@ use std::fmt; -use std::future::Future; use std::marker::PhantomData; -use std::pin::Pin; -use std::task::{Context, Poll}; use std::time::Duration; use actix_codec::{AsyncRead, AsyncWrite}; @@ -11,7 +8,6 @@ use actix_connect::{ }; use actix_service::{apply_fn, Service}; use actix_utils::timeout::{TimeoutError, TimeoutService}; -use futures::future::Ready; use http::Uri; use tokio_net::tcp::TcpStream; @@ -344,7 +340,6 @@ mod connect_impl { use std::task::{Context, Poll}; use futures::future::{err, Either, Ready}; - use futures::ready; use super::*; use crate::client::connection::IoConnection; @@ -402,7 +397,10 @@ mod connect_impl { #[cfg(any(feature = "openssl", feature = "rustls"))] mod connect_impl { + use std::future::Future; use std::marker::PhantomData; + use std::pin::Pin; + use std::task::{Context, Poll}; use futures::future::Either; use futures::ready; diff --git a/actix-http/src/client/h1proto.rs b/actix-http/src/client/h1proto.rs index 041a36856..ddfc7a314 100644 --- a/actix-http/src/client/h1proto.rs +++ b/actix-http/src/client/h1proto.rs @@ -1,4 +1,3 @@ -use std::future::Future; use std::io::Write; use std::pin::Pin; use std::task::{Context, Poll}; @@ -6,8 +5,8 @@ use std::{io, time}; use actix_codec::{AsyncRead, AsyncWrite, Framed}; use bytes::{BufMut, Bytes, BytesMut}; -use futures::future::{ok, poll_fn, Either}; -use futures::{Sink, SinkExt, Stream, StreamExt}; +use futures::future::poll_fn; +use futures::{SinkExt, Stream, StreamExt}; use crate::error::PayloadError; use crate::h1; diff --git a/actix-http/src/client/h2proto.rs b/actix-http/src/client/h2proto.rs index 1647abf81..a94562f2d 100644 --- a/actix-http/src/client/h2proto.rs +++ b/actix-http/src/client/h2proto.rs @@ -1,11 +1,8 @@ -use std::future::Future; -use std::pin::Pin; -use std::task::{Context, Poll}; use std::time; use actix_codec::{AsyncRead, AsyncWrite}; use bytes::Bytes; -use futures::future::{err, poll_fn, Either}; +use futures::future::poll_fn; use h2::{client::SendRequest, SendStream}; use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING}; use http::{request::Request, HttpTryFrom, Method, Version}; diff --git a/actix-http/src/client/pool.rs b/actix-http/src/client/pool.rs index 1952dca59..c61039866 100644 --- a/actix-http/src/client/pool.rs +++ b/actix-http/src/client/pool.rs @@ -1,23 +1,22 @@ use std::cell::RefCell; use std::collections::VecDeque; use std::future::Future; -use std::io; use std::pin::Pin; use std::rc::Rc; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; use actix_codec::{AsyncRead, AsyncWrite}; +use actix_rt::time::{delay_for, Delay}; use actix_service::Service; use actix_utils::{oneshot, task::LocalWaker}; use bytes::Bytes; -use futures::future::{err, ok, poll_fn, Either, FutureExt, LocalBoxFuture, Ready}; +use futures::future::{poll_fn, FutureExt, LocalBoxFuture}; use h2::client::{handshake, Connection, SendRequest}; use hashbrown::HashMap; use http::uri::Authority; use indexmap::IndexSet; use slab::Slab; -use tokio_timer::{delay_for, Delay}; use super::connection::{ConnectionType, IoConnection}; use super::error::ConnectError; @@ -100,7 +99,7 @@ where fn call(&mut self, req: Connect) -> Self::Future { // start support future - tokio_executor::current_thread::spawn(ConnectorPoolSupport { + actix_rt::spawn(ConnectorPoolSupport { connector: self.0.clone(), inner: self.1.clone(), }); @@ -139,7 +138,7 @@ where )) } else { let (snd, connection) = handshake(io).await?; - tokio_executor::current_thread::spawn(connection.map(|_| ())); + actix_rt::spawn(connection.map(|_| ())); Ok(IoConnection::new( ConnectionType::H2(snd), Instant::now(), @@ -328,9 +327,7 @@ where { if let Some(timeout) = self.disconnect_timeout { if let ConnectionType::H1(io) = conn.io { - tokio_executor::current_thread::spawn(CloseConnection::new( - io, timeout, - )) + actix_rt::spawn(CloseConnection::new(io, timeout)) } } } else { @@ -342,9 +339,9 @@ where Poll::Ready(Ok(n)) if n > 0 => { if let Some(timeout) = self.disconnect_timeout { if let ConnectionType::H1(io) = io { - tokio_executor::current_thread::spawn( - CloseConnection::new(io, timeout), - ) + actix_rt::spawn(CloseConnection::new( + io, timeout, + )) } } continue; @@ -376,7 +373,7 @@ where self.acquired -= 1; if let Some(timeout) = self.disconnect_timeout { if let ConnectionType::H1(io) = io { - tokio_executor::current_thread::spawn(CloseConnection::new(io, timeout)) + actix_rt::spawn(CloseConnection::new(io, timeout)) } } self.check_availibility(); @@ -518,7 +515,7 @@ where inner: Rc>>, fut: F, ) { - tokio_executor::current_thread::spawn(OpenWaitingConnection { + actix_rt::spawn(OpenWaitingConnection { key, fut, h2: None, @@ -554,7 +551,7 @@ where if let Some(ref mut h2) = this.h2 { return match Pin::new(h2).poll(cx) { Poll::Ready(Ok((snd, connection))) => { - tokio_executor::current_thread::spawn(connection.map(|_| ())); + actix_rt::spawn(connection.map(|_| ())); let rx = this.rx.take().unwrap(); let _ = rx.send(Ok(IoConnection::new( ConnectionType::H2(snd), diff --git a/actix-http/src/config.rs b/actix-http/src/config.rs index 488e4d98a..bab3cdc6d 100644 --- a/actix-http/src/config.rs +++ b/actix-http/src/config.rs @@ -4,10 +4,10 @@ use std::fmt::Write; use std::rc::Rc; use std::time::{Duration, Instant}; +use actix_rt::time::{delay, delay_for, Delay}; use bytes::BytesMut; -use futures::{future, Future, FutureExt}; +use futures::{future, FutureExt}; use time; -use tokio_timer::{delay, delay_for, Delay}; // "Sun, 06 Nov 1994 08:49:37 GMT".len() const DATE_VALUE_LENGTH: usize = 29; @@ -242,12 +242,10 @@ impl DateService { // periodic date update let s = self.clone(); - tokio_executor::current_thread::spawn( - delay_for(Duration::from_millis(500)).then(move |_| { - s.0.reset(); - future::ready(()) - }), - ); + actix_rt::spawn(delay_for(Duration::from_millis(500)).then(move |_| { + s.0.reset(); + future::ready(()) + })); } } @@ -265,26 +263,19 @@ impl DateService { #[cfg(test)] mod tests { use super::*; - use actix_rt::System; - use futures::future; #[test] fn test_date_len() { assert_eq!(DATE_VALUE_LENGTH, "Sun, 06 Nov 1994 08:49:37 GMT".len()); } - #[test] - fn test_date() { - let mut rt = System::new("test"); - - let _ = rt.block_on(future::lazy(|_| { - let settings = ServiceConfig::new(KeepAlive::Os, 0, 0); - let mut buf1 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10); - settings.set_date(&mut buf1); - let mut buf2 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10); - settings.set_date(&mut buf2); - assert_eq!(buf1, buf2); - future::ok::<_, ()>(()) - })); + #[actix_rt::test] + async fn test_date() { + let settings = ServiceConfig::new(KeepAlive::Os, 0, 0); + let mut buf1 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10); + settings.set_date(&mut buf1); + let mut buf2 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10); + settings.set_date(&mut buf2); + assert_eq!(buf1, buf2); } } diff --git a/actix-http/src/cookie/secure/key.rs b/actix-http/src/cookie/secure/key.rs index 95058ed81..779c16b75 100644 --- a/actix-http/src/cookie/secure/key.rs +++ b/actix-http/src/cookie/secure/key.rs @@ -1,5 +1,4 @@ use ring::hkdf::{Algorithm, KeyType, Prk, HKDF_SHA256}; -use ring::hmac; use ring::rand::{SecureRandom, SystemRandom}; use super::private::KEY_LEN as PRIVATE_KEY_LEN; diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index a725789a2..f1767cf19 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -16,7 +16,6 @@ use httparse; use serde::de::value::Error as DeError; use serde_json::error::Error as JsonError; use serde_urlencoded::ser::Error as FormError; -use tokio_timer::Error as TimerError; // re-export for convinience use crate::body::Body; @@ -178,9 +177,6 @@ impl ResponseError for JsonError {} /// `InternalServerError` for `FormError` impl ResponseError for FormError {} -/// `InternalServerError` for `TimerError` -impl ResponseError for TimerError {} - #[cfg(feature = "openssl")] /// `InternalServerError` for `openssl::ssl::Error` impl ResponseError for open_ssl::ssl::Error {} diff --git a/actix-http/src/h1/decoder.rs b/actix-http/src/h1/decoder.rs index 272270ca1..ffa00288f 100644 --- a/actix-http/src/h1/decoder.rs +++ b/actix-http/src/h1/decoder.rs @@ -1,9 +1,7 @@ -use std::future::Future; use std::io; use std::marker::PhantomData; use std::mem::MaybeUninit; -use std::pin::Pin; -use std::task::{Context, Poll}; +use std::task::Poll; use actix_codec::Decoder; use bytes::{Bytes, BytesMut}; diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index 8c0896029..154b3ed40 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -3,15 +3,15 @@ use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Instant; -use std::{fmt, io, io::Write, net}; +use std::{fmt, io, net}; -use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed, FramedParts}; +use actix_codec::{AsyncRead, Decoder, Encoder, Framed, FramedParts}; +use actix_rt::time::{delay, Delay}; use actix_server_config::IoStream; use actix_service::Service; use bitflags::bitflags; use bytes::{BufMut, BytesMut}; use log::{error, trace}; -use tokio_timer::{delay, Delay}; use crate::body::{Body, BodySize, MessageBody, ResponseBody}; use crate::cloneable::CloneableService; @@ -893,10 +893,9 @@ mod tests { use crate::h1::{ExpectHandler, UpgradeHandler}; use crate::test::TestBuffer; - #[test] - fn test_req_parse_err() { - let mut sys = actix_rt::System::new("test"); - let _ = sys.block_on(lazy(|cx| { + #[actix_rt::test] + async fn test_req_parse_err() { + lazy(|cx| { let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n"); let mut h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( @@ -918,7 +917,7 @@ mod tests { assert!(inner.flags.contains(Flags::READ_DISCONNECT)); assert_eq!(&inner.io.write_buf[..26], b"HTTP/1.1 400 Bad Request\r\n"); } - ok::<_, ()>(()) - })); + }) + .await; } } diff --git a/actix-http/src/h1/expect.rs b/actix-http/src/h1/expect.rs index 79831eae1..d6b4a9f1e 100644 --- a/actix-http/src/h1/expect.rs +++ b/actix-http/src/h1/expect.rs @@ -1,5 +1,3 @@ -use std::future::Future; -use std::pin::Pin; use std::task::{Context, Poll}; use actix_server_config::ServerConfig; diff --git a/actix-http/src/h1/payload.rs b/actix-http/src/h1/payload.rs index 2b52cfd86..46f2f9728 100644 --- a/actix-http/src/h1/payload.rs +++ b/actix-http/src/h1/payload.rs @@ -1,7 +1,6 @@ //! Payload stream use std::cell::RefCell; use std::collections::VecDeque; -use std::future::Future; use std::pin::Pin; use std::rc::{Rc, Weak}; use std::task::{Context, Poll}; @@ -227,24 +226,19 @@ impl Inner { #[cfg(test)] mod tests { use super::*; - use actix_rt::Runtime; - use futures::future::{poll_fn, ready}; + use futures::future::poll_fn; - #[test] - fn test_unread_data() { - Runtime::new().unwrap().block_on(async { - let (_, mut payload) = Payload::create(false); + #[actix_rt::test] + async fn test_unread_data() { + let (_, mut payload) = Payload::create(false); - payload.unread_data(Bytes::from("data")); - assert!(!payload.is_empty()); - assert_eq!(payload.len(), 4); + payload.unread_data(Bytes::from("data")); + assert!(!payload.is_empty()); + assert_eq!(payload.len(), 4); - assert_eq!( - Bytes::from("data"), - poll_fn(|cx| payload.readany(cx)).await.unwrap().unwrap() - ); - - ready(()) - }); + assert_eq!( + Bytes::from("data"), + poll_fn(|cx| payload.readany(cx)).await.unwrap().unwrap() + ); } } diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index ce8ff6626..197c92887 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -9,7 +9,7 @@ use actix_codec::Framed; use actix_server_config::{Io, IoStream, ServerConfig as SrvConfig}; use actix_service::{IntoServiceFactory, Service, ServiceFactory}; use futures::future::{ok, Ready}; -use futures::{ready, Stream}; +use futures::ready; use crate::body::MessageBody; use crate::cloneable::CloneableService; diff --git a/actix-http/src/h1/upgrade.rs b/actix-http/src/h1/upgrade.rs index 43ab53d01..ce46fbe93 100644 --- a/actix-http/src/h1/upgrade.rs +++ b/actix-http/src/h1/upgrade.rs @@ -1,6 +1,4 @@ -use std::future::Future; use std::marker::PhantomData; -use std::pin::Pin; use std::task::{Context, Poll}; use actix_codec::Framed; diff --git a/actix-http/src/h1/utils.rs b/actix-http/src/h1/utils.rs index 7057bf1ca..7af0b124e 100644 --- a/actix-http/src/h1/utils.rs +++ b/actix-http/src/h1/utils.rs @@ -3,7 +3,6 @@ use std::pin::Pin; use std::task::{Context, Poll}; use actix_codec::{AsyncRead, AsyncWrite, Framed}; -use futures::Sink; use crate::body::{BodySize, MessageBody, ResponseBody}; use crate::error::Error; diff --git a/actix-http/src/h2/dispatcher.rs b/actix-http/src/h2/dispatcher.rs index 1a52a60f2..188553806 100644 --- a/actix-http/src/h2/dispatcher.rs +++ b/actix-http/src/h2/dispatcher.rs @@ -7,6 +7,7 @@ use std::time::Instant; use std::{fmt, mem, net}; use actix_codec::{AsyncRead, AsyncWrite}; +use actix_rt::time::Delay; use actix_server_config::IoStream; use actix_service::Service; use bitflags::bitflags; @@ -19,7 +20,6 @@ use http::header::{ }; use http::HttpTryFrom; use log::{debug, error, trace}; -use tokio_timer::Delay; use crate::body::{Body, BodySize, MessageBody, ResponseBody}; use crate::cloneable::CloneableService; @@ -139,7 +139,7 @@ where on_connect.set(&mut req.extensions_mut()); } - tokio_executor::current_thread::spawn(ServiceResponse::< + actix_rt::spawn(ServiceResponse::< S::Future, S::Response, S::Error, diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index 4d17347db..b57fdddce 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -4,8 +4,7 @@ clippy::too_many_arguments, clippy::new_without_default, clippy::borrow_interior_mutable_const, - clippy::write_with_newline, - unused_imports + clippy::write_with_newline )] #[macro_use] diff --git a/actix-http/src/payload.rs b/actix-http/src/payload.rs index f2cc6414f..b3ec04d11 100644 --- a/actix-http/src/payload.rs +++ b/actix-http/src/payload.rs @@ -1,4 +1,3 @@ -use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/actix-http/src/response.rs b/actix-http/src/response.rs index a5f18cc79..5eb0228dc 100644 --- a/actix-http/src/response.rs +++ b/actix-http/src/response.rs @@ -7,7 +7,6 @@ use std::task::{Context, Poll}; use std::{fmt, str}; use bytes::{BufMut, Bytes, BytesMut}; -use futures::future::{ok, Ready}; use futures::stream::Stream; use serde::Serialize; use serde_json; diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index e18b10130..7340c15fd 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -8,7 +8,7 @@ use actix_server_config::{ Io as ServerIo, IoStream, Protocol, ServerConfig as SrvConfig, }; use actix_service::{IntoServiceFactory, Service, ServiceFactory}; -use bytes::{Buf, BufMut, Bytes, BytesMut}; +use bytes::{BufMut, Bytes, BytesMut}; use futures::{ready, Future}; use h2::server::{self, Handshake}; use pin_project::{pin_project, project}; @@ -659,7 +659,7 @@ impl AsyncRead for Io { // } } -impl tokio_io::AsyncWrite for Io { +impl actix_codec::AsyncWrite for Io { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, diff --git a/actix-http/src/test.rs b/actix-http/src/test.rs index 26f2c223f..744f057dc 100644 --- a/actix-http/src/test.rs +++ b/actix-http/src/test.rs @@ -7,7 +7,7 @@ use std::task::{Context, Poll}; use actix_codec::{AsyncRead, AsyncWrite}; use actix_server_config::IoStream; -use bytes::{Buf, Bytes, BytesMut}; +use bytes::{Bytes, BytesMut}; use http::header::{self, HeaderName, HeaderValue}; use http::{HttpTryFrom, Method, Uri, Version}; use percent_encoding::percent_encode; diff --git a/actix-http/tests/test_client.rs b/actix-http/tests/test_client.rs index 05248966a..cdcaea028 100644 --- a/actix-http/tests/test_client.rs +++ b/actix-http/tests/test_client.rs @@ -3,7 +3,7 @@ use bytes::Bytes; use futures::future::{self, ok}; use actix_http::{http, HttpService, Request, Response}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ @@ -27,65 +27,58 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World"; -#[test] -fn test_h1_v2() { - block_on(async { - let srv = TestServer::start(move || { - HttpService::build() - .finish(|_| future::ok::<_, ()>(Response::Ok().body(STR))) - }); +#[actix_rt::test] +async fn test_h1_v2() { + let srv = TestServer::start(move || { + HttpService::build().finish(|_| future::ok::<_, ()>(Response::Ok().body(STR))) + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.get("/").header("x-test", "111").send(); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + let request = srv.get("/").header("x-test", "111").send(); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - let mut response = srv.post("/").send().await.unwrap(); - assert!(response.status().is_success()); + let mut response = srv.post("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] -fn test_connection_close() { - block_on(async { - let srv = TestServer::start(move || { - HttpService::build() - .finish(|_| ok::<_, ()>(Response::Ok().body(STR))) - .map(|_| ()) - }); +#[actix_rt::test] +async fn test_connection_close() { + let srv = TestServer::start(move || { + HttpService::build() + .finish(|_| ok::<_, ()>(Response::Ok().body(STR))) + .map(|_| ()) + }); - let response = srv.get("/").force_close().send().await.unwrap(); - assert!(response.status().is_success()); - }) + let response = srv.get("/").force_close().send().await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_with_query_parameter() { - block_on(async { - let srv = TestServer::start(move || { - HttpService::build() - .finish(|req: Request| { - if req.uri().query().unwrap().contains("qp=") { - ok::<_, ()>(Response::Ok().finish()) - } else { - ok::<_, ()>(Response::BadRequest().finish()) - } - }) - .map(|_| ()) - }); +#[actix_rt::test] +async fn test_with_query_parameter() { + let srv = TestServer::start(move || { + HttpService::build() + .finish(|req: Request| { + if req.uri().query().unwrap().contains("qp=") { + ok::<_, ()>(Response::Ok().finish()) + } else { + ok::<_, ()>(Response::BadRequest().finish()) + } + }) + .map(|_| ()) + }); - let request = srv.request(http::Method::GET, srv.url("/?qp=5")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - }) + let request = srv.request(http::Method::GET, srv.url("/?qp=5")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); } diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index 7eaa8e2a2..0fdddaa1c 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -2,7 +2,7 @@ use std::io; use actix_codec::{AsyncRead, AsyncWrite}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_server::ssl::OpensslAcceptor; use actix_server_config::ServerConfig; use actix_service::{factory_fn_cfg, pipeline_factory, service_fn2, ServiceFactory}; @@ -57,156 +57,147 @@ fn ssl_acceptor() -> io::Result io::Result<()> { - block_on(async { - let openssl = ssl_acceptor()?; - let srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| ok::<_, Error>(Response::Ok().finish())) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2() -> io::Result<()> { + let openssl = ssl_acceptor()?; + let srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| ok::<_, Error>(Response::Ok().finish())) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - Ok(()) - }) + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + Ok(()) } -#[test] -fn test_h2_1() -> io::Result<()> { - block_on(async { - let openssl = ssl_acceptor()?; - let srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .finish(|req: Request| { - assert!(req.peer_addr().is_some()); - assert_eq!(req.version(), Version::HTTP_2); - ok::<_, Error>(Response::Ok().finish()) - }) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_1() -> io::Result<()> { + let openssl = ssl_acceptor()?; + let srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .finish(|req: Request| { + assert!(req.peer_addr().is_some()); + assert_eq!(req.version(), Version::HTTP_2); + ok::<_, Error>(Response::Ok().finish()) + }) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - Ok(()) - }) + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + Ok(()) } -#[test] -fn test_h2_body() -> io::Result<()> { - block_on(async { - let data = "HELLOWORLD".to_owned().repeat(64 * 1024); - let openssl = ssl_acceptor()?; - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|mut req: Request<_>| { - async move { - let body = load_body(req.take_payload()).await?; - Ok::<_, Error>(Response::Ok().body(body)) - } - }) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_body() -> io::Result<()> { + let data = "HELLOWORLD".to_owned().repeat(64 * 1024); + let openssl = ssl_acceptor()?; + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|mut req: Request<_>| { + async move { + let body = load_body(req.take_payload()).await?; + Ok::<_, Error>(Response::Ok().body(body)) + } + }) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send_body(data.clone()).await.unwrap(); - assert!(response.status().is_success()); + let response = srv.sget("/").send_body(data.clone()).await.unwrap(); + assert!(response.status().is_success()); - let body = srv.load_body(response).await.unwrap(); - assert_eq!(&body, data.as_bytes()); - Ok(()) - }) + let body = srv.load_body(response).await.unwrap(); + assert_eq!(&body, data.as_bytes()); + Ok(()) } -#[test] -fn test_h2_content_length() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_content_length() { + let openssl = ssl_acceptor().unwrap(); - let srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|req: Request| { - let indx: usize = req.uri().path()[1..].parse().unwrap(); - let statuses = [ - StatusCode::NO_CONTENT, - StatusCode::CONTINUE, - StatusCode::SWITCHING_PROTOCOLS, - StatusCode::PROCESSING, - StatusCode::OK, - StatusCode::NOT_FOUND, - ]; - ok::<_, ()>(Response::new(statuses[indx])) - }) - .map_err(|_| ()), - ) - }); + let srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|req: Request| { + let indx: usize = req.uri().path()[1..].parse().unwrap(); + let statuses = [ + StatusCode::NO_CONTENT, + StatusCode::CONTINUE, + StatusCode::SWITCHING_PROTOCOLS, + StatusCode::PROCESSING, + StatusCode::OK, + StatusCode::NOT_FOUND, + ]; + ok::<_, ()>(Response::new(statuses[indx])) + }) + .map_err(|_| ()), + ) + }); - let header = HeaderName::from_static("content-length"); - let value = HeaderValue::from_static("0"); + let header = HeaderName::from_static("content-length"); + let value = HeaderValue::from_static("0"); - { - for i in 0..4 { - let req = srv - .request(Method::GET, srv.surl(&format!("/{}", i))) - .send(); - let response = req.await.unwrap(); - assert_eq!(response.headers().get(&header), None); + { + for i in 0..4 { + let req = srv + .request(Method::GET, srv.surl(&format!("/{}", i))) + .send(); + let response = req.await.unwrap(); + assert_eq!(response.headers().get(&header), None); - let req = srv - .request(Method::HEAD, srv.surl(&format!("/{}", i))) - .send(); - let response = req.await.unwrap(); - assert_eq!(response.headers().get(&header), None); - } - - for i in 4..6 { - let req = srv - .request(Method::GET, srv.surl(&format!("/{}", i))) - .send(); - let response = req.await.unwrap(); - assert_eq!(response.headers().get(&header), Some(&value)); - } + let req = srv + .request(Method::HEAD, srv.surl(&format!("/{}", i))) + .send(); + let response = req.await.unwrap(); + assert_eq!(response.headers().get(&header), None); } - }) + + for i in 4..6 { + let req = srv + .request(Method::GET, srv.surl(&format!("/{}", i))) + .send(); + let response = req.await.unwrap(); + assert_eq!(response.headers().get(&header), Some(&value)); + } + } } -#[test] -fn test_h2_headers() { - block_on(async { - let data = STR.repeat(10); - let data2 = data.clone(); - let openssl = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_headers() { + let data = STR.repeat(10); + let data2 = data.clone(); + let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - let data = data.clone(); - pipeline_factory(openssl + let mut srv = TestServer::start(move || { + let data = data.clone(); + pipeline_factory(openssl .clone() .map_err(|e| println!("Openssl error: {}", e))) .and_then( @@ -232,15 +223,14 @@ fn test_h2_headers() { } ok::<_, ()>(builder.body(data.clone())) }).map_err(|_| ())) - }); + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from(data2)); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from(data2)); } const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ @@ -265,281 +255,262 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World"; -#[test] -fn test_h2_body2() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| ok::<_, ()>(Response::Ok().body(STR))) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_body2() { + let openssl = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| ok::<_, ()>(Response::Ok().body(STR))) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] -fn test_h2_head_empty() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .finish(|_| ok::<_, ()>(Response::Ok().body(STR))) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_head_empty() { + let openssl = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .finish(|_| ok::<_, ()>(Response::Ok().body(STR))) + .map_err(|_| ()), + ) + }); - let response = srv.shead("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!(response.version(), Version::HTTP_2); + let response = srv.shead("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!(response.version(), Version::HTTP_2); - { - let len = response.headers().get(header::CONTENT_LENGTH).unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } + { + let len = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert!(bytes.is_empty()); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert!(bytes.is_empty()); } -#[test] -fn test_h2_head_binary() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| { - ok::<_, ()>( - Response::Ok().content_length(STR.len() as u64).body(STR), - ) - }) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_head_binary() { + let openssl = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| { + ok::<_, ()>( + Response::Ok().content_length(STR.len() as u64).body(STR), + ) + }) + .map_err(|_| ()), + ) + }); - let response = srv.shead("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.shead("/").send().await.unwrap(); + assert!(response.status().is_success()); - { - let len = response.headers().get(header::CONTENT_LENGTH).unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } + { + let len = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert!(bytes.is_empty()); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert!(bytes.is_empty()); } -#[test] -fn test_h2_head_binary2() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| ok::<_, ()>(Response::Ok().body(STR))) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_head_binary2() { + let openssl = ssl_acceptor().unwrap(); + let srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| ok::<_, ()>(Response::Ok().body(STR))) + .map_err(|_| ()), + ) + }); - let response = srv.shead("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.shead("/").send().await.unwrap(); + assert!(response.status().is_success()); - { - let len = response.headers().get(header::CONTENT_LENGTH).unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } - }) + { + let len = response.headers().get(header::CONTENT_LENGTH).unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } } -#[test] -fn test_h2_body_length() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| { - let body = once(ok(Bytes::from_static(STR.as_ref()))); +#[actix_rt::test] +async fn test_h2_body_length() { + let openssl = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| { + let body = once(ok(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>( + Response::Ok() + .body(body::SizedStream::new(STR.len() as u64, body)), + ) + }) + .map_err(|_| ()), + ) + }); + + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_h2_body_chunked_explicit() { + let openssl = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| { + let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>( + Response::Ok() + .header(header::TRANSFER_ENCODING, "chunked") + .streaming(body), + ) + }) + .map_err(|_| ()), + ) + }); + + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert!(!response.headers().contains_key(header::TRANSFER_ENCODING)); + + // read response + let bytes = srv.load_body(response).await.unwrap(); + + // decode + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_h2_response_http_error_handling() { + let openssl = ssl_acceptor().unwrap(); + + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(factory_fn_cfg(|_: &ServerConfig| { + ok::<_, ()>(service_fn2(|_| { + let broken_header = Bytes::from_static(b"\0\0\0"); ok::<_, ()>( Response::Ok() - .body(body::SizedStream::new(STR.len() as u64, body)), + .header(header::CONTENT_TYPE, broken_header) + .body(STR), ) - }) - .map_err(|_| ()), - ) - }); - - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_h2_body_chunked_explicit() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| { - let body = - once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); - ok::<_, ()>( - Response::Ok() - .header(header::TRANSFER_ENCODING, "chunked") - .streaming(body), - ) - }) - .map_err(|_| ()), - ) - }); - - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert!(!response.headers().contains_key(header::TRANSFER_ENCODING)); - - // read response - let bytes = srv.load_body(response).await.unwrap(); - - // decode - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_h2_response_http_error_handling() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(factory_fn_cfg(|_: &ServerConfig| { - ok::<_, ()>(service_fn2(|_| { - let broken_header = Bytes::from_static(b"\0\0\0"); - ok::<_, ()>( - Response::Ok() - .header(header::CONTENT_TYPE, broken_header) - .body(STR), - ) - })) })) - .map_err(|_| ()), - ) - }); + })) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + let response = srv.sget("/").send().await.unwrap(); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(b"failed to parse header value")); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(b"failed to parse header value")); } -#[test] -fn test_h2_service_error() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_service_error() { + let openssl = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(|_| err::(ErrorBadRequest("error"))) - .map_err(|_| ()), - ) - }); + let mut srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(|_| err::(ErrorBadRequest("error"))) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert_eq!(response.status(), StatusCode::BAD_REQUEST); + let response = srv.sget("/").send().await.unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(b"error")); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(b"error")); } -#[test] -fn test_h2_on_connect() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_on_connect() { + let openssl = ssl_acceptor().unwrap(); - let srv = TestServer::start(move || { - pipeline_factory( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .on_connect(|_| 10usize) - .h2(|req: Request| { - assert!(req.extensions().contains::()); - ok::<_, ()>(Response::Ok().finish()) - }) - .map_err(|_| ()), - ) - }); + let srv = TestServer::start(move || { + pipeline_factory( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .on_connect(|_| 10usize) + .h2(|req: Request| { + assert!(req.extensions().contains::()); + ok::<_, ()>(Response::Ok().finish()) + }) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - }) + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); } diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index c36d05794..4a649ca37 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -4,7 +4,7 @@ use actix_http::error::PayloadError; use actix_http::http::header::{self, HeaderName, HeaderValue}; use actix_http::http::{Method, StatusCode, Version}; use actix_http::{body, error, Error, HttpService, Request, Response}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_server::ssl::RustlsAcceptor; use actix_server_config::ServerConfig; use actix_service::{factory_fn_cfg, pipeline_factory, service_fn2, ServiceFactory}; @@ -45,140 +45,131 @@ fn ssl_acceptor() -> io::Result Ok(RustlsAcceptor::new(config)) } -#[test] -fn test_h2() -> io::Result<()> { - block_on(async { - let rustls = ssl_acceptor()?; - let srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| future::ok::<_, Error>(Response::Ok().finish())) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2() -> io::Result<()> { + let rustls = ssl_acceptor()?; + let srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| future::ok::<_, Error>(Response::Ok().finish())) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - Ok(()) - }) + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + Ok(()) } -#[test] -fn test_h2_1() -> io::Result<()> { - block_on(async { - let rustls = ssl_acceptor()?; - let srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .finish(|req: Request| { - assert!(req.peer_addr().is_some()); - assert_eq!(req.version(), Version::HTTP_2); - future::ok::<_, Error>(Response::Ok().finish()) - }) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_1() -> io::Result<()> { + let rustls = ssl_acceptor()?; + let srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .finish(|req: Request| { + assert!(req.peer_addr().is_some()); + assert_eq!(req.version(), Version::HTTP_2); + future::ok::<_, Error>(Response::Ok().finish()) + }) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - Ok(()) - }) + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + Ok(()) } -#[test] -fn test_h2_body1() -> io::Result<()> { - block_on(async { - let data = "HELLOWORLD".to_owned().repeat(64 * 1024); - let rustls = ssl_acceptor()?; - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|mut req: Request<_>| { - async move { - let body = load_body(req.take_payload()).await?; - Ok::<_, Error>(Response::Ok().body(body)) - } - }) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_body1() -> io::Result<()> { + let data = "HELLOWORLD".to_owned().repeat(64 * 1024); + let rustls = ssl_acceptor()?; + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|mut req: Request<_>| { + async move { + let body = load_body(req.take_payload()).await?; + Ok::<_, Error>(Response::Ok().body(body)) + } + }) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send_body(data.clone()).await.unwrap(); - assert!(response.status().is_success()); + let response = srv.sget("/").send_body(data.clone()).await.unwrap(); + assert!(response.status().is_success()); - let body = srv.load_body(response).await.unwrap(); - assert_eq!(&body, data.as_bytes()); - Ok(()) - }) + let body = srv.load_body(response).await.unwrap(); + assert_eq!(&body, data.as_bytes()); + Ok(()) } -#[test] -fn test_h2_content_length() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_content_length() { + let rustls = ssl_acceptor().unwrap(); - let srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|req: Request| { - let indx: usize = req.uri().path()[1..].parse().unwrap(); - let statuses = [ - StatusCode::NO_CONTENT, - StatusCode::CONTINUE, - StatusCode::SWITCHING_PROTOCOLS, - StatusCode::PROCESSING, - StatusCode::OK, - StatusCode::NOT_FOUND, - ]; - future::ok::<_, ()>(Response::new(statuses[indx])) - }) - .map_err(|_| ()), - ) - }); + let srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|req: Request| { + let indx: usize = req.uri().path()[1..].parse().unwrap(); + let statuses = [ + StatusCode::NO_CONTENT, + StatusCode::CONTINUE, + StatusCode::SWITCHING_PROTOCOLS, + StatusCode::PROCESSING, + StatusCode::OK, + StatusCode::NOT_FOUND, + ]; + future::ok::<_, ()>(Response::new(statuses[indx])) + }) + .map_err(|_| ()), + ) + }); - let header = HeaderName::from_static("content-length"); - let value = HeaderValue::from_static("0"); + let header = HeaderName::from_static("content-length"); + let value = HeaderValue::from_static("0"); - { - for i in 0..4 { - let req = srv - .request(Method::GET, srv.surl(&format!("/{}", i))) - .send(); - let response = req.await.unwrap(); - assert_eq!(response.headers().get(&header), None); + { + for i in 0..4 { + let req = srv + .request(Method::GET, srv.surl(&format!("/{}", i))) + .send(); + let response = req.await.unwrap(); + assert_eq!(response.headers().get(&header), None); - let req = srv - .request(Method::HEAD, srv.surl(&format!("/{}", i))) - .send(); - let response = req.await.unwrap(); - assert_eq!(response.headers().get(&header), None); - } - - for i in 4..6 { - let req = srv - .request(Method::GET, srv.surl(&format!("/{}", i))) - .send(); - let response = req.await.unwrap(); - assert_eq!(response.headers().get(&header), Some(&value)); - } + let req = srv + .request(Method::HEAD, srv.surl(&format!("/{}", i))) + .send(); + let response = req.await.unwrap(); + assert_eq!(response.headers().get(&header), None); } - }) + + for i in 4..6 { + let req = srv + .request(Method::GET, srv.surl(&format!("/{}", i))) + .send(); + let response = req.await.unwrap(); + assert_eq!(response.headers().get(&header), Some(&value)); + } + } } -#[test] -fn test_h2_headers() { - block_on(async { - let data = STR.repeat(10); - let data2 = data.clone(); - let rustls = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_headers() { + let data = STR.repeat(10); + let data2 = data.clone(); + let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - let data = data.clone(); - pipeline_factory(rustls + let mut srv = TestServer::start(move || { + let data = data.clone(); + pipeline_factory(rustls .clone() .map_err(|e| println!("Rustls error: {}", e))) .and_then( @@ -204,15 +195,14 @@ fn test_h2_headers() { } future::ok::<_, ()>(config.body(data.clone())) }).map_err(|_| ())) - }); + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from(data2)); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from(data2)); } const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ @@ -237,238 +227,215 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World"; -#[test] -fn test_h2_body2() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| future::ok::<_, ()>(Response::Ok().body(STR))) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_body2() { + let rustls = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| future::ok::<_, ()>(Response::Ok().body(STR))) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] -fn test_h2_head_empty() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .finish(|_| ok::<_, ()>(Response::Ok().body(STR))) - .map_err(|_| ()), - ) - }); +#[actix_rt::test] +async fn test_h2_head_empty() { + let rustls = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .finish(|_| ok::<_, ()>(Response::Ok().body(STR))) + .map_err(|_| ()), + ) + }); - let response = srv.shead("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!(response.version(), Version::HTTP_2); + let response = srv.shead("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!(response.version(), Version::HTTP_2); - { - let len = response - .headers() - .get(http::header::CONTENT_LENGTH) - .unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } + { + let len = response + .headers() + .get(http::header::CONTENT_LENGTH) + .unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert!(bytes.is_empty()); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert!(bytes.is_empty()); } -#[test] -fn test_h2_head_binary() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| { +#[actix_rt::test] +async fn test_h2_head_binary() { + let rustls = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| { + ok::<_, ()>( + Response::Ok().content_length(STR.len() as u64).body(STR), + ) + }) + .map_err(|_| ()), + ) + }); + + let response = srv.shead("/").send().await.unwrap(); + assert!(response.status().is_success()); + + { + let len = response + .headers() + .get(http::header::CONTENT_LENGTH) + .unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } + + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert!(bytes.is_empty()); +} + +#[actix_rt::test] +async fn test_h2_head_binary2() { + let rustls = ssl_acceptor().unwrap(); + let srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| ok::<_, ()>(Response::Ok().body(STR))) + .map_err(|_| ()), + ) + }); + + let response = srv.shead("/").send().await.unwrap(); + assert!(response.status().is_success()); + + { + let len = response + .headers() + .get(http::header::CONTENT_LENGTH) + .unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } +} + +#[actix_rt::test] +async fn test_h2_body_length() { + let rustls = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| { + let body = once(ok(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>( + Response::Ok() + .body(body::SizedStream::new(STR.len() as u64, body)), + ) + }) + .map_err(|_| ()), + ) + }); + + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_h2_body_chunked_explicit() { + let rustls = ssl_acceptor().unwrap(); + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| { + let body = + once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>( + Response::Ok() + .header(header::TRANSFER_ENCODING, "chunked") + .streaming(body), + ) + }) + .map_err(|_| ()), + ) + }); + + let response = srv.sget("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert!(!response.headers().contains_key(header::TRANSFER_ENCODING)); + + // read response + let bytes = srv.load_body(response).await.unwrap(); + + // decode + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_h2_response_http_error_handling() { + let rustls = ssl_acceptor().unwrap(); + + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(factory_fn_cfg(|_: &ServerConfig| { + ok::<_, ()>(service_fn2(|_| { + let broken_header = Bytes::from_static(b"\0\0\0"); ok::<_, ()>( Response::Ok() - .content_length(STR.len() as u64) + .header(http::header::CONTENT_TYPE, broken_header) .body(STR), ) - }) - .map_err(|_| ()), - ) - }); - - let response = srv.shead("/").send().await.unwrap(); - assert!(response.status().is_success()); - - { - let len = response - .headers() - .get(http::header::CONTENT_LENGTH) - .unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } - - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert!(bytes.is_empty()); - }) -} - -#[test] -fn test_h2_head_binary2() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - let srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| ok::<_, ()>(Response::Ok().body(STR))) - .map_err(|_| ()), - ) - }); - - let response = srv.shead("/").send().await.unwrap(); - assert!(response.status().is_success()); - - { - let len = response - .headers() - .get(http::header::CONTENT_LENGTH) - .unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } - }) -} - -#[test] -fn test_h2_body_length() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| { - let body = once(ok(Bytes::from_static(STR.as_ref()))); - ok::<_, ()>( - Response::Ok().body(body::SizedStream::new( - STR.len() as u64, - body, - )), - ) - }) - .map_err(|_| ()), - ) - }); - - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_h2_body_chunked_explicit() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| { - let body = - once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); - ok::<_, ()>( - Response::Ok() - .header(header::TRANSFER_ENCODING, "chunked") - .streaming(body), - ) - }) - .map_err(|_| ()), - ) - }); - - let response = srv.sget("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert!(!response.headers().contains_key(header::TRANSFER_ENCODING)); - - // read response - let bytes = srv.load_body(response).await.unwrap(); - - // decode - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_h2_response_http_error_handling() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); - - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(factory_fn_cfg(|_: &ServerConfig| { - ok::<_, ()>(service_fn2(|_| { - let broken_header = Bytes::from_static(b"\0\0\0"); - ok::<_, ()>( - Response::Ok() - .header( - http::header::CONTENT_TYPE, - broken_header, - ) - .body(STR), - ) - })) })) - .map_err(|_| ()), - ) - }); + })) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); + let response = srv.sget("/").send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(b"failed to parse header value")); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(b"failed to parse header value")); } -#[test] -fn test_h2_service_error() { - block_on(async { - let rustls = ssl_acceptor().unwrap(); +#[actix_rt::test] +async fn test_h2_service_error() { + let rustls = ssl_acceptor().unwrap(); - let mut srv = TestServer::start(move || { - pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) - .and_then( - HttpService::build() - .h2(|_| err::(error::ErrorBadRequest("error"))) - .map_err(|_| ()), - ) - }); + let mut srv = TestServer::start(move || { + pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e))) + .and_then( + HttpService::build() + .h2(|_| err::(error::ErrorBadRequest("error"))) + .map_err(|_| ()), + ) + }); - let response = srv.sget("/").send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::BAD_REQUEST); + let response = srv.sget("/").send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::BAD_REQUEST); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(b"error")); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(b"error")); } diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index c37e8fad1..a3ce3f9cb 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -2,395 +2,361 @@ use std::io::{Read, Write}; use std::time::Duration; use std::{net, thread}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; +use actix_rt::time::delay_for; use actix_server_config::ServerConfig; use actix_service::{factory_fn_cfg, pipeline, service_fn, ServiceFactory}; use bytes::Bytes; use futures::future::{self, err, ok, ready, FutureExt}; use futures::stream::{once, StreamExt}; use regex::Regex; -use tokio_timer::delay_for; use actix_http::httpmessage::HttpMessage; use actix_http::{ body, error, http, http::header, Error, HttpService, KeepAlive, Request, Response, }; -#[test] -fn test_h1() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .keep_alive(KeepAlive::Disabled) - .client_timeout(1000) - .client_disconnect(1000) - .h1(|req: Request| { - assert!(req.peer_addr().is_some()); - future::ok::<_, ()>(Response::Ok().finish()) - }) - }); +#[actix_rt::test] +async fn test_h1() { + let srv = TestServer::start(|| { + HttpService::build() + .keep_alive(KeepAlive::Disabled) + .client_timeout(1000) + .client_disconnect(1000) + .h1(|req: Request| { + assert!(req.peer_addr().is_some()); + future::ok::<_, ()>(Response::Ok().finish()) + }) + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); - }) + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_h1_2() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .keep_alive(KeepAlive::Disabled) - .client_timeout(1000) - .client_disconnect(1000) - .finish(|req: Request| { - assert!(req.peer_addr().is_some()); - assert_eq!(req.version(), http::Version::HTTP_11); - future::ok::<_, ()>(Response::Ok().finish()) - }) - .map(|_| ()) - }); +#[actix_rt::test] +async fn test_h1_2() { + let srv = TestServer::start(|| { + HttpService::build() + .keep_alive(KeepAlive::Disabled) + .client_timeout(1000) + .client_disconnect(1000) + .finish(|req: Request| { + assert!(req.peer_addr().is_some()); + assert_eq!(req.version(), http::Version::HTTP_11); + future::ok::<_, ()>(Response::Ok().finish()) + }) + .map(|_| ()) + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); - }) + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_expect_continue() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .expect(service_fn(|req: Request| { +#[actix_rt::test] +async fn test_expect_continue() { + let srv = TestServer::start(|| { + HttpService::build() + .expect(service_fn(|req: Request| { + if req.head().uri.query() == Some("yes=") { + ok(req) + } else { + err(error::ErrorPreconditionFailed("error")) + } + })) + .finish(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.starts_with("HTTP/1.1 412 Precondition Failed\r\ncontent-length")); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test?yes= HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n")); +} + +#[actix_rt::test] +async fn test_expect_continue_h1() { + let srv = TestServer::start(|| { + HttpService::build() + .expect(service_fn(|req: Request| { + delay_for(Duration::from_millis(20)).then(move |_| { if req.head().uri.query() == Some("yes=") { ok(req) } else { err(error::ErrorPreconditionFailed("error")) } - })) - .finish(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 412 Precondition Failed\r\ncontent-length")); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = - stream.write_all(b"GET /test?yes= HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n")); - }) -} - -#[test] -fn test_expect_continue_h1() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .expect(service_fn(|req: Request| { - delay_for(Duration::from_millis(20)).then(move |_| { - if req.head().uri.query() == Some("yes=") { - ok(req) - } else { - err(error::ErrorPreconditionFailed("error")) - } - }) - })) - .h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 412 Precondition Failed\r\ncontent-length")); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = - stream.write_all(b"GET /test?yes= HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n")); - }) -} - -#[test] -fn test_chunked_payload() { - block_on(async { - let chunk_sizes = vec![32768, 32, 32768]; - let total_size: usize = chunk_sizes.iter().sum(); - - let srv = TestServer::start(|| { - HttpService::build().h1(service_fn(|mut request: Request| { - request - .take_payload() - .map(|res| match res { - Ok(pl) => pl, - Err(e) => panic!(format!("Error reading payload: {}", e)), - }) - .fold(0usize, |acc, chunk| ready(acc + chunk.len())) - .map(|req_size| { - Ok::<_, Error>(Response::Ok().body(format!("size={}", req_size))) - }) + }) })) - }); + .h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); - let returned_size = { - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream - .write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"); + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.starts_with("HTTP/1.1 412 Precondition Failed\r\ncontent-length")); - for chunk_size in chunk_sizes.iter() { - let mut bytes = Vec::new(); - let random_bytes: Vec = - (0..*chunk_size).map(|_| rand::random::()).collect(); - - bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes()); - bytes.extend(&random_bytes[..]); - bytes.extend(b"\r\n"); - let _ = stream.write_all(&bytes); - } - - let _ = stream.write_all(b"0\r\n\r\n"); - stream.shutdown(net::Shutdown::Write).unwrap(); - - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - - let re = Regex::new(r"size=(\d+)").unwrap(); - let size: usize = match re.captures(&data) { - Some(caps) => caps.get(1).unwrap().as_str().parse().unwrap(), - None => { - panic!(format!("Failed to find size in HTTP Response: {}", data)) - } - }; - size - }; - - assert_eq!(returned_size, total_size); - }) + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test?yes= HTTP/1.1\r\nexpect: 100-continue\r\n\r\n"); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.starts_with("HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\n")); } -#[test] -fn test_slow_request() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .client_timeout(100) - .finish(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); +#[actix_rt::test] +async fn test_chunked_payload() { + let chunk_sizes = vec![32768, 32, 32768]; + let total_size: usize = chunk_sizes.iter().sum(); - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n"); - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 408 Request Timeout")); - }) -} - -#[test] -fn test_http1_malformed_request() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP1.1\r\n"); - let mut data = String::new(); - let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 400 Bad Request")); - }) -} - -#[test] -fn test_http1_keepalive() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); - - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); - }) -} - -#[test] -fn test_http1_keepalive_timeout() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .keep_alive(1) - .h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); - thread::sleep(Duration::from_millis(1100)); - - let mut data = vec![0; 1024]; - let res = stream.read(&mut data).unwrap(); - assert_eq!(res, 0); - }) -} - -#[test] -fn test_http1_keepalive_close() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); + let srv = TestServer::start(|| { + HttpService::build().h1(service_fn(|mut request: Request| { + request + .take_payload() + .map(|res| match res { + Ok(pl) => pl, + Err(e) => panic!(format!("Error reading payload: {}", e)), + }) + .fold(0usize, |acc, chunk| ready(acc + chunk.len())) + .map(|req_size| { + Ok::<_, Error>(Response::Ok().body(format!("size={}", req_size))) + }) + })) + }); + let returned_size = { let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); let _ = stream - .write_all(b"GET /test/tests/test HTTP/1.1\r\nconnection: close\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); + .write_all(b"POST /test HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n"); - let mut data = vec![0; 1024]; - let res = stream.read(&mut data).unwrap(); - assert_eq!(res, 0); - }) -} + for chunk_size in chunk_sizes.iter() { + let mut bytes = Vec::new(); + let random_bytes: Vec = + (0..*chunk_size).map(|_| rand::random::()).collect(); -#[test] -fn test_http10_keepalive_default_close() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.0\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); - - let mut data = vec![0; 1024]; - let res = stream.read(&mut data).unwrap(); - assert_eq!(res, 0); - }) -} - -#[test] -fn test_http10_keepalive() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all( - b"GET /test/tests/test HTTP/1.0\r\nconnection: keep-alive\r\n\r\n", - ); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.0\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); - - let mut data = vec![0; 1024]; - let res = stream.read(&mut data).unwrap(); - assert_eq!(res, 0); - }) -} - -#[test] -fn test_http1_keepalive_disabled() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .keep_alive(KeepAlive::Disabled) - .h1(|_| future::ok::<_, ()>(Response::Ok().finish())) - }); - - let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); - let mut data = vec![0; 1024]; - let _ = stream.read(&mut data); - assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); - - let mut data = vec![0; 1024]; - let res = stream.read(&mut data).unwrap(); - assert_eq!(res, 0); - }) -} - -#[test] -fn test_content_length() { - block_on(async { - use actix_http::http::{ - header::{HeaderName, HeaderValue}, - StatusCode, - }; - - let srv = TestServer::start(|| { - HttpService::build().h1(|req: Request| { - let indx: usize = req.uri().path()[1..].parse().unwrap(); - let statuses = [ - StatusCode::NO_CONTENT, - StatusCode::CONTINUE, - StatusCode::SWITCHING_PROTOCOLS, - StatusCode::PROCESSING, - StatusCode::OK, - StatusCode::NOT_FOUND, - ]; - future::ok::<_, ()>(Response::new(statuses[indx])) - }) - }); - - let header = HeaderName::from_static("content-length"); - let value = HeaderValue::from_static("0"); - - { - for i in 0..4 { - let req = srv.request(http::Method::GET, srv.url(&format!("/{}", i))); - let response = req.send().await.unwrap(); - assert_eq!(response.headers().get(&header), None); - - let req = srv.request(http::Method::HEAD, srv.url(&format!("/{}", i))); - let response = req.send().await.unwrap(); - assert_eq!(response.headers().get(&header), None); - } - - for i in 4..6 { - let req = srv.request(http::Method::GET, srv.url(&format!("/{}", i))); - let response = req.send().await.unwrap(); - assert_eq!(response.headers().get(&header), Some(&value)); - } + bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes()); + bytes.extend(&random_bytes[..]); + bytes.extend(b"\r\n"); + let _ = stream.write_all(&bytes); } - }) + + let _ = stream.write_all(b"0\r\n\r\n"); + stream.shutdown(net::Shutdown::Write).unwrap(); + + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + + let re = Regex::new(r"size=(\d+)").unwrap(); + let size: usize = match re.captures(&data) { + Some(caps) => caps.get(1).unwrap().as_str().parse().unwrap(), + None => panic!(format!("Failed to find size in HTTP Response: {}", data)), + }; + size + }; + + assert_eq!(returned_size, total_size); } -#[test] -fn test_h1_headers() { - block_on(async { - let data = STR.repeat(10); - let data2 = data.clone(); +#[actix_rt::test] +async fn test_slow_request() { + let srv = TestServer::start(|| { + HttpService::build() + .client_timeout(100) + .finish(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); - let mut srv = TestServer::start(move || { - let data = data.clone(); - HttpService::build().h1(move |_| { + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n"); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.starts_with("HTTP/1.1 408 Request Timeout")); +} + +#[actix_rt::test] +async fn test_http1_malformed_request() { + let srv = TestServer::start(|| { + HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP1.1\r\n"); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.starts_with("HTTP/1.1 400 Bad Request")); +} + +#[actix_rt::test] +async fn test_http1_keepalive() { + let srv = TestServer::start(|| { + HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); + + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); +} + +#[actix_rt::test] +async fn test_http1_keepalive_timeout() { + let srv = TestServer::start(|| { + HttpService::build() + .keep_alive(1) + .h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); + thread::sleep(Duration::from_millis(1100)); + + let mut data = vec![0; 1024]; + let res = stream.read(&mut data).unwrap(); + assert_eq!(res, 0); +} + +#[actix_rt::test] +async fn test_http1_keepalive_close() { + let srv = TestServer::start(|| { + HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = + stream.write_all(b"GET /test/tests/test HTTP/1.1\r\nconnection: close\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); + + let mut data = vec![0; 1024]; + let res = stream.read(&mut data).unwrap(); + assert_eq!(res, 0); +} + +#[actix_rt::test] +async fn test_http10_keepalive_default_close() { + let srv = TestServer::start(|| { + HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.0\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); + + let mut data = vec![0; 1024]; + let res = stream.read(&mut data).unwrap(); + assert_eq!(res, 0); +} + +#[actix_rt::test] +async fn test_http10_keepalive() { + let srv = TestServer::start(|| { + HttpService::build().h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream + .write_all(b"GET /test/tests/test HTTP/1.0\r\nconnection: keep-alive\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.0\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); + + let mut data = vec![0; 1024]; + let res = stream.read(&mut data).unwrap(); + assert_eq!(res, 0); +} + +#[actix_rt::test] +async fn test_http1_keepalive_disabled() { + let srv = TestServer::start(|| { + HttpService::build() + .keep_alive(KeepAlive::Disabled) + .h1(|_| future::ok::<_, ()>(Response::Ok().finish())) + }); + + let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n\r\n"); + let mut data = vec![0; 1024]; + let _ = stream.read(&mut data); + assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n"); + + let mut data = vec![0; 1024]; + let res = stream.read(&mut data).unwrap(); + assert_eq!(res, 0); +} + +#[actix_rt::test] +async fn test_content_length() { + use actix_http::http::{ + header::{HeaderName, HeaderValue}, + StatusCode, + }; + + let srv = TestServer::start(|| { + HttpService::build().h1(|req: Request| { + let indx: usize = req.uri().path()[1..].parse().unwrap(); + let statuses = [ + StatusCode::NO_CONTENT, + StatusCode::CONTINUE, + StatusCode::SWITCHING_PROTOCOLS, + StatusCode::PROCESSING, + StatusCode::OK, + StatusCode::NOT_FOUND, + ]; + future::ok::<_, ()>(Response::new(statuses[indx])) + }) + }); + + let header = HeaderName::from_static("content-length"); + let value = HeaderValue::from_static("0"); + + { + for i in 0..4 { + let req = srv.request(http::Method::GET, srv.url(&format!("/{}", i))); + let response = req.send().await.unwrap(); + assert_eq!(response.headers().get(&header), None); + + let req = srv.request(http::Method::HEAD, srv.url(&format!("/{}", i))); + let response = req.send().await.unwrap(); + assert_eq!(response.headers().get(&header), None); + } + + for i in 4..6 { + let req = srv.request(http::Method::GET, srv.url(&format!("/{}", i))); + let response = req.send().await.unwrap(); + assert_eq!(response.headers().get(&header), Some(&value)); + } + } +} + +#[actix_rt::test] +async fn test_h1_headers() { + let data = STR.repeat(10); + let data2 = data.clone(); + + let mut srv = TestServer::start(move || { + let data = data.clone(); + HttpService::build().h1(move |_| { let mut builder = Response::Ok(); for idx in 0..90 { builder.header( @@ -412,15 +378,14 @@ fn test_h1_headers() { } future::ok::<_, ()>(builder.body(data.clone())) }) - }); + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from(data2)); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from(data2)); } const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ @@ -445,230 +410,210 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World"; -#[test] -fn test_h1_body() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR))) - }); +#[actix_rt::test] +async fn test_h1_body() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR))) + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] -fn test_h1_head_empty() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR))) - }); +#[actix_rt::test] +async fn test_h1_head_empty() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR))) + }); - let response = srv.head("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.head("/").send().await.unwrap(); + assert!(response.status().is_success()); - { - let len = response - .headers() - .get(http::header::CONTENT_LENGTH) - .unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } + { + let len = response + .headers() + .get(http::header::CONTENT_LENGTH) + .unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert!(bytes.is_empty()); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert!(bytes.is_empty()); } -#[test] -fn test_h1_head_binary() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(|_| { - ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR)) - }) - }); +#[actix_rt::test] +async fn test_h1_head_binary() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(|_| { + ok::<_, ()>(Response::Ok().content_length(STR.len() as u64).body(STR)) + }) + }); - let response = srv.head("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.head("/").send().await.unwrap(); + assert!(response.status().is_success()); - { - let len = response - .headers() - .get(http::header::CONTENT_LENGTH) - .unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } + { + let len = response + .headers() + .get(http::header::CONTENT_LENGTH) + .unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert!(bytes.is_empty()); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert!(bytes.is_empty()); } -#[test] -fn test_h1_head_binary2() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR))) - }); +#[actix_rt::test] +async fn test_h1_head_binary2() { + let srv = TestServer::start(|| { + HttpService::build().h1(|_| ok::<_, ()>(Response::Ok().body(STR))) + }); - let response = srv.head("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.head("/").send().await.unwrap(); + assert!(response.status().is_success()); - { - let len = response - .headers() - .get(http::header::CONTENT_LENGTH) - .unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } - }) + { + let len = response + .headers() + .get(http::header::CONTENT_LENGTH) + .unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } } -#[test] -fn test_h1_body_length() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(|_| { - let body = once(ok(Bytes::from_static(STR.as_ref()))); - ok::<_, ()>( - Response::Ok().body(body::SizedStream::new(STR.len() as u64, body)), - ) - }) - }); +#[actix_rt::test] +async fn test_h1_body_length() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(|_| { + let body = once(ok(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>( + Response::Ok().body(body::SizedStream::new(STR.len() as u64, body)), + ) + }) + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] -fn test_h1_body_chunked_explicit() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(|_| { - let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); +#[actix_rt::test] +async fn test_h1_body_chunked_explicit() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(|_| { + let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>( + Response::Ok() + .header(header::TRANSFER_ENCODING, "chunked") + .streaming(body), + ) + }) + }); + + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!( + response + .headers() + .get(header::TRANSFER_ENCODING) + .unwrap() + .to_str() + .unwrap(), + "chunked" + ); + + // read response + let bytes = srv.load_body(response).await.unwrap(); + + // decode + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_h1_body_chunked_implicit() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(|_| { + let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); + ok::<_, ()>(Response::Ok().streaming(body)) + }) + }); + + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!( + response + .headers() + .get(header::TRANSFER_ENCODING) + .unwrap() + .to_str() + .unwrap(), + "chunked" + ); + + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_h1_response_http_error_handling() { + let mut srv = TestServer::start(|| { + HttpService::build().h1(factory_fn_cfg(|_: &ServerConfig| { + ok::<_, ()>(pipeline(|_| { + let broken_header = Bytes::from_static(b"\0\0\0"); ok::<_, ()>( Response::Ok() - .header(header::TRANSFER_ENCODING, "chunked") - .streaming(body), + .header(http::header::CONTENT_TYPE, broken_header) + .body(STR), ) - }) - }); - - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!( - response - .headers() - .get(header::TRANSFER_ENCODING) - .unwrap() - .to_str() - .unwrap(), - "chunked" - ); - - // read response - let bytes = srv.load_body(response).await.unwrap(); - - // decode - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_h1_body_chunked_implicit() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(|_| { - let body = once(ok::<_, Error>(Bytes::from_static(STR.as_ref()))); - ok::<_, ()>(Response::Ok().streaming(body)) - }) - }); - - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!( - response - .headers() - .get(header::TRANSFER_ENCODING) - .unwrap() - .to_str() - .unwrap(), - "chunked" - ); - - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_h1_response_http_error_handling() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build().h1(factory_fn_cfg(|_: &ServerConfig| { - ok::<_, ()>(pipeline(|_| { - let broken_header = Bytes::from_static(b"\0\0\0"); - ok::<_, ()>( - Response::Ok() - .header(http::header::CONTENT_TYPE, broken_header) - .body(STR), - ) - })) })) - }); + })) + }); - let response = srv.get("/").send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); + let response = srv.get("/").send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(b"failed to parse header value")); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(b"failed to parse header value")); } -#[test] -fn test_h1_service_error() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build() - .h1(|_| future::err::(error::ErrorBadRequest("error"))) - }); +#[actix_rt::test] +async fn test_h1_service_error() { + let mut srv = TestServer::start(|| { + HttpService::build() + .h1(|_| future::err::(error::ErrorBadRequest("error"))) + }); - let response = srv.get("/").send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::BAD_REQUEST); + let response = srv.get("/").send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::BAD_REQUEST); - // read response - let bytes = srv.load_body(response).await.unwrap(); - assert_eq!(bytes, Bytes::from_static(b"error")); - }) + // read response + let bytes = srv.load_body(response).await.unwrap(); + assert_eq!(bytes, Bytes::from_static(b"error")); } -#[test] -fn test_h1_on_connect() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::build() - .on_connect(|_| 10usize) - .h1(|req: Request| { - assert!(req.extensions().contains::()); - future::ok::<_, ()>(Response::Ok().finish()) - }) - }); +#[actix_rt::test] +async fn test_h1_on_connect() { + let srv = TestServer::start(|| { + HttpService::build() + .on_connect(|_| 10usize) + .h1(|req: Request| { + assert!(req.extensions().contains::()); + future::ok::<_, ()>(Response::Ok().finish()) + }) + }); - let response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); - }) + let response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); } diff --git a/actix-http/tests/test_ws.rs b/actix-http/tests/test_ws.rs index 74c1cb405..aa81bc41b 100644 --- a/actix-http/tests/test_ws.rs +++ b/actix-http/tests/test_ws.rs @@ -1,6 +1,6 @@ use actix_codec::{AsyncRead, AsyncWrite, Framed}; use actix_http::{body, h1, ws, Error, HttpService, Request, Response}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_utils::framed::FramedTransport; use bytes::{Bytes, BytesMut}; use futures::future; @@ -34,53 +34,51 @@ async fn service(msg: ws::Frame) -> Result { Ok(msg) } -#[test] -fn test_simple() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build() - .upgrade(actix_service::service_fn(ws_service)) - .finish(|_| future::ok::<_, ()>(Response::NotFound())) - }); +#[actix_rt::test] +async fn test_simple() { + let mut srv = TestServer::start(|| { + HttpService::build() + .upgrade(actix_service::service_fn(ws_service)) + .finish(|_| future::ok::<_, ()>(Response::NotFound())) + }); - // client service - let mut framed = srv.ws().await.unwrap(); - framed - .send(ws::Message::Text("text".to_string())) - .await - .unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Text(Some(BytesMut::from("text"))) - ); + // client service + let mut framed = srv.ws().await.unwrap(); + framed + .send(ws::Message::Text("text".to_string())) + .await + .unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Text(Some(BytesMut::from("text"))) + ); - framed - .send(ws::Message::Binary("text".into())) - .await - .unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) - ); + framed + .send(ws::Message::Binary("text".into())) + .await + .unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) + ); - framed.send(ws::Message::Ping("text".into())).await.unwrap(); - let (item, mut framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Pong("text".to_string().into()) - ); + framed.send(ws::Message::Ping("text".into())).await.unwrap(); + let (item, mut framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Pong("text".to_string().into()) + ); - framed - .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) - .await - .unwrap(); + framed + .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) + .await + .unwrap(); - let (item, _framed) = framed.into_future().await; - assert_eq!( - item.unwrap().unwrap(), - ws::Frame::Close(Some(ws::CloseCode::Normal.into())) - ); - }) + let (item, _framed) = framed.into_future().await; + assert_eq!( + item.unwrap().unwrap(), + ws::Frame::Close(Some(ws::CloseCode::Normal.into())) + ); } diff --git a/actix-identity/src/lib.rs b/actix-identity/src/lib.rs index 2980a7753..5dfd2ae65 100644 --- a/actix-identity/src/lib.rs +++ b/actix-identity/src/lib.rs @@ -607,144 +607,130 @@ mod tests { use super::*; use actix_web::http::StatusCode; - use actix_web::test::{self, block_on, TestRequest}; + use actix_web::test::{self, TestRequest}; use actix_web::{web, App, Error, HttpResponse}; const COOKIE_KEY_MASTER: [u8; 32] = [0; 32]; const COOKIE_NAME: &'static str = "actix_auth"; const COOKIE_LOGIN: &'static str = "test"; - #[test] - fn test_identity() { - block_on(async { - let mut srv = test::init_service( - App::new() - .wrap(IdentityService::new( - CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) - .domain("www.rust-lang.org") - .name(COOKIE_NAME) - .path("/") - .secure(true), - )) - .service(web::resource("/index").to(|id: Identity| { - if id.identity().is_some() { - HttpResponse::Created() - } else { - HttpResponse::Ok() - } - })) - .service(web::resource("/login").to(|id: Identity| { - id.remember(COOKIE_LOGIN.to_string()); + #[actix_rt::test] + async fn test_identity() { + let mut srv = test::init_service( + App::new() + .wrap(IdentityService::new( + CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) + .domain("www.rust-lang.org") + .name(COOKIE_NAME) + .path("/") + .secure(true), + )) + .service(web::resource("/index").to(|id: Identity| { + if id.identity().is_some() { + HttpResponse::Created() + } else { HttpResponse::Ok() - })) - .service(web::resource("/logout").to(|id: Identity| { - if id.identity().is_some() { - id.forget(); - HttpResponse::Ok() - } else { - HttpResponse::BadRequest() - } - })), - ) - .await; - let resp = test::call_service( - &mut srv, - TestRequest::with_uri("/index").to_request(), - ) - .await; - assert_eq!(resp.status(), StatusCode::OK); + } + })) + .service(web::resource("/login").to(|id: Identity| { + id.remember(COOKIE_LOGIN.to_string()); + HttpResponse::Ok() + })) + .service(web::resource("/logout").to(|id: Identity| { + if id.identity().is_some() { + id.forget(); + HttpResponse::Ok() + } else { + HttpResponse::BadRequest() + } + })), + ) + .await; + let resp = + test::call_service(&mut 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; - assert_eq!(resp.status(), StatusCode::OK); - let c = resp.response().cookies().next().unwrap().to_owned(); + let resp = + test::call_service(&mut 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, - TestRequest::with_uri("/index") - .cookie(c.clone()) - .to_request(), - ) - .await; - assert_eq!(resp.status(), StatusCode::CREATED); + let resp = test::call_service( + &mut srv, + TestRequest::with_uri("/index") + .cookie(c.clone()) + .to_request(), + ) + .await; + assert_eq!(resp.status(), StatusCode::CREATED); - let resp = test::call_service( - &mut srv, - TestRequest::with_uri("/logout") - .cookie(c.clone()) - .to_request(), - ) - .await; - assert_eq!(resp.status(), StatusCode::OK); - assert!(resp.headers().contains_key(header::SET_COOKIE)) - }) + let resp = test::call_service( + &mut srv, + TestRequest::with_uri("/logout") + .cookie(c.clone()) + .to_request(), + ) + .await; + assert_eq!(resp.status(), StatusCode::OK); + assert!(resp.headers().contains_key(header::SET_COOKIE)) } - #[test] - fn test_identity_max_age_time() { - block_on(async { - let duration = Duration::days(1); - let mut srv = test::init_service( - App::new() - .wrap(IdentityService::new( - CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) - .domain("www.rust-lang.org") - .name(COOKIE_NAME) - .path("/") - .max_age_time(duration) - .secure(true), - )) - .service(web::resource("/login").to(|id: Identity| { - id.remember("test".to_string()); - HttpResponse::Ok() - })), - ) - .await; - let resp = test::call_service( - &mut 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(); - assert_eq!(duration, c.max_age().unwrap()); - }) + #[actix_rt::test] + async fn test_identity_max_age_time() { + let duration = Duration::days(1); + let mut srv = test::init_service( + App::new() + .wrap(IdentityService::new( + CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) + .domain("www.rust-lang.org") + .name(COOKIE_NAME) + .path("/") + .max_age_time(duration) + .secure(true), + )) + .service(web::resource("/login").to(|id: Identity| { + id.remember("test".to_string()); + HttpResponse::Ok() + })), + ) + .await; + let resp = + test::call_service(&mut 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(); + assert_eq!(duration, c.max_age().unwrap()); } - #[test] - fn test_identity_max_age() { - block_on(async { - let seconds = 60; - let mut srv = test::init_service( - App::new() - .wrap(IdentityService::new( - CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) - .domain("www.rust-lang.org") - .name(COOKIE_NAME) - .path("/") - .max_age(seconds) - .secure(true), - )) - .service(web::resource("/login").to(|id: Identity| { - id.remember("test".to_string()); - HttpResponse::Ok() - })), - ) - .await; - let resp = test::call_service( - &mut 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(); - assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap()); - }) + #[actix_rt::test] + async fn test_identity_max_age() { + let seconds = 60; + let mut srv = test::init_service( + App::new() + .wrap(IdentityService::new( + CookieIdentityPolicy::new(&COOKIE_KEY_MASTER) + .domain("www.rust-lang.org") + .name(COOKIE_NAME) + .path("/") + .max_age(seconds) + .secure(true), + )) + .service(web::resource("/login").to(|id: Identity| { + id.remember("test".to_string()); + HttpResponse::Ok() + })), + ) + .await; + let resp = + test::call_service(&mut 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(); + assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap()); } async fn create_identity_server< @@ -885,223 +871,202 @@ mod tests { assert!(cookies.get(COOKIE_NAME).is_none()); } - #[test] - fn test_identity_legacy_cookie_is_set() { - block_on(async { - let mut srv = create_identity_server(|c| c).await; - let mut resp = - test::call_service(&mut 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_is_set() { + let mut srv = create_identity_server(|c| c).await; + let mut resp = + test::call_service(&mut srv, TestRequest::with_uri("/").to_request()).await; + assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_legacy_cookie_works() { - block_on(async { - let mut srv = create_identity_server(|c| c).await; - let cookie = legacy_login_cookie(COOKIE_LOGIN); - let mut resp = test::call_service( - &mut srv, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_no_login_cookie(&mut resp); - assert_logged_in(resp, Some(COOKIE_LOGIN)).await; - }) + #[actix_rt::test] + async fn test_identity_legacy_cookie_works() { + let mut srv = create_identity_server(|c| c).await; + let cookie = legacy_login_cookie(COOKIE_LOGIN); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_no_login_cookie(&mut resp); + assert_logged_in(resp, Some(COOKIE_LOGIN)).await; } - #[test] - fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() { - block_on(async { - let mut 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, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::NoTimestamp, - VisitTimeStampCheck::NewTimestamp, - ); - assert_logged_in(resp, None).await; - }) + #[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 cookie = legacy_login_cookie(COOKIE_LOGIN); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::NoTimestamp, + VisitTimeStampCheck::NewTimestamp, + ); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() { - block_on(async { - let mut 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, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::NewTimestamp, - VisitTimeStampCheck::NoTimestamp, - ); - assert_logged_in(resp, None).await; - }) + #[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 cookie = legacy_login_cookie(COOKIE_LOGIN); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::NewTimestamp, + VisitTimeStampCheck::NoTimestamp, + ); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_cookie_rejected_if_login_timestamp_needed() { - block_on(async { - let mut 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, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::NewTimestamp, - VisitTimeStampCheck::NoTimestamp, - ); - assert_logged_in(resp, None).await; - }) + #[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 cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now())); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::NewTimestamp, + VisitTimeStampCheck::NoTimestamp, + ); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_cookie_rejected_if_visit_timestamp_needed() { - block_on(async { - let mut 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, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::NoTimestamp, - VisitTimeStampCheck::NewTimestamp, - ); - assert_logged_in(resp, None).await; - }) + #[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 cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::NoTimestamp, + VisitTimeStampCheck::NewTimestamp, + ); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_cookie_rejected_if_login_timestamp_too_old() { - block_on(async { - let mut srv = - create_identity_server(|c| c.login_deadline(Duration::days(90))).await; - let cookie = login_cookie( - COOKIE_LOGIN, - Some(SystemTime::now() - Duration::days(180).to_std().unwrap()), - None, - ); - let mut resp = test::call_service( - &mut srv, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::NewTimestamp, - VisitTimeStampCheck::NoTimestamp, - ); - assert_logged_in(resp, None).await; - }) + #[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 cookie = login_cookie( + COOKIE_LOGIN, + Some(SystemTime::now() - Duration::days(180).to_std().unwrap()), + None, + ); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::NewTimestamp, + VisitTimeStampCheck::NoTimestamp, + ); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_cookie_rejected_if_visit_timestamp_too_old() { - block_on(async { - let mut 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).to_std().unwrap()), - ); - let mut resp = test::call_service( - &mut srv, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::NoTimestamp, - VisitTimeStampCheck::NewTimestamp, - ); - assert_logged_in(resp, None).await; - }) + #[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 cookie = login_cookie( + COOKIE_LOGIN, + None, + Some(SystemTime::now() - Duration::days(180).to_std().unwrap()), + ); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::NoTimestamp, + VisitTimeStampCheck::NewTimestamp, + ); + assert_logged_in(resp, None).await; } - #[test] - fn test_identity_cookie_not_updated_on_login_deadline() { - block_on(async { - let mut 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, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_no_login_cookie(&mut resp); - assert_logged_in(resp, Some(COOKIE_LOGIN)).await; - }) + #[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 cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_no_login_cookie(&mut resp); + assert_logged_in(resp, Some(COOKIE_LOGIN)).await; } - #[test] - fn test_identity_cookie_updated_on_visit_deadline() { - block_on(async { - let mut srv = create_identity_server(|c| { - c.visit_deadline(Duration::days(90)) - .login_deadline(Duration::days(90)) - }) - .await; - let timestamp = SystemTime::now() - Duration::days(1).to_std().unwrap(); - let cookie = login_cookie(COOKIE_LOGIN, Some(timestamp), Some(timestamp)); - let mut resp = test::call_service( - &mut srv, - TestRequest::with_uri("/") - .cookie(cookie.clone()) - .to_request(), - ) - .await; - assert_login_cookie( - &mut resp, - COOKIE_LOGIN, - LoginTimestampCheck::OldTimestamp(timestamp), - VisitTimeStampCheck::NewTimestamp, - ); - assert_logged_in(resp, Some(COOKIE_LOGIN)).await; + #[actix_rt::test] + async fn test_identity_cookie_updated_on_visit_deadline() { + let mut srv = create_identity_server(|c| { + c.visit_deadline(Duration::days(90)) + .login_deadline(Duration::days(90)) }) + .await; + let timestamp = SystemTime::now() - Duration::days(1).to_std().unwrap(); + let cookie = login_cookie(COOKIE_LOGIN, Some(timestamp), Some(timestamp)); + let mut resp = test::call_service( + &mut srv, + TestRequest::with_uri("/") + .cookie(cookie.clone()) + .to_request(), + ) + .await; + assert_login_cookie( + &mut resp, + COOKIE_LOGIN, + LoginTimestampCheck::OldTimestamp(timestamp), + VisitTimeStampCheck::NewTimestamp, + ); + assert_logged_in(resp, Some(COOKIE_LOGIN)).await; } } diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index dd7852c8e..c49896761 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -813,12 +813,11 @@ mod tests { use actix_http::h1::Payload; use actix_utils::mpsc; use actix_web::http::header::{DispositionParam, DispositionType}; - use actix_web::test::block_on; use bytes::Bytes; use futures::future::lazy; - #[test] - fn test_boundary() { + #[actix_rt::test] + async fn test_boundary() { let headers = HeaderMap::new(); match Multipart::boundary(&headers) { Err(MultipartError::NoContentType) => (), @@ -891,246 +890,228 @@ mod tests { (bytes, headers) } - #[test] - fn test_multipart_no_end_crlf() { - block_on(async { - let (sender, payload) = create_stream(); - let (bytes, headers) = create_simple_request_with_header(); - let bytes_stripped = bytes.slice_to(bytes.len()); // strip crlf + #[actix_rt::test] + async fn test_multipart_no_end_crlf() { + let (sender, payload) = create_stream(); + let (bytes, headers) = create_simple_request_with_header(); + let bytes_stripped = bytes.slice_to(bytes.len()); // strip crlf - sender.send(Ok(bytes_stripped)).unwrap(); - drop(sender); // eof + sender.send(Ok(bytes_stripped)).unwrap(); + drop(sender); // eof - let mut multipart = Multipart::new(&headers, payload); + let mut multipart = Multipart::new(&headers, payload); - match multipart.next().await.unwrap() { - Ok(_) => (), - _ => unreachable!(), - } + match multipart.next().await.unwrap() { + Ok(_) => (), + _ => unreachable!(), + } - match multipart.next().await.unwrap() { - Ok(_) => (), - _ => unreachable!(), - } + match multipart.next().await.unwrap() { + Ok(_) => (), + _ => unreachable!(), + } - match multipart.next().await { - None => (), - _ => unreachable!(), - } - }) + match multipart.next().await { + None => (), + _ => unreachable!(), + } } - #[test] - fn test_multipart() { - block_on(async { - let (sender, payload) = create_stream(); - let (bytes, headers) = create_simple_request_with_header(); + #[actix_rt::test] + async fn test_multipart() { + let (sender, payload) = create_stream(); + let (bytes, headers) = create_simple_request_with_header(); - sender.send(Ok(bytes)).unwrap(); + sender.send(Ok(bytes)).unwrap(); - let mut multipart = Multipart::new(&headers, payload); - match multipart.next().await { - Some(Ok(mut field)) => { - let cd = field.content_disposition().unwrap(); - assert_eq!(cd.disposition, DispositionType::FormData); - assert_eq!(cd.parameters[0], DispositionParam::Name("file".into())); + let mut multipart = Multipart::new(&headers, payload); + match multipart.next().await { + Some(Ok(mut field)) => { + let cd = field.content_disposition().unwrap(); + assert_eq!(cd.disposition, DispositionType::FormData); + assert_eq!(cd.parameters[0], DispositionParam::Name("file".into())); - assert_eq!(field.content_type().type_(), mime::TEXT); - assert_eq!(field.content_type().subtype(), mime::PLAIN); + assert_eq!(field.content_type().type_(), mime::TEXT); + assert_eq!(field.content_type().subtype(), mime::PLAIN); - match field.next().await.unwrap() { - Ok(chunk) => assert_eq!(chunk, "test"), - _ => unreachable!(), - } - match field.next().await { - None => (), - _ => unreachable!(), - } + match field.next().await.unwrap() { + Ok(chunk) => assert_eq!(chunk, "test"), + _ => unreachable!(), } - _ => unreachable!(), - } - - match multipart.next().await.unwrap() { - Ok(mut field) => { - assert_eq!(field.content_type().type_(), mime::TEXT); - assert_eq!(field.content_type().subtype(), mime::PLAIN); - - match field.next().await { - Some(Ok(chunk)) => assert_eq!(chunk, "data"), - _ => unreachable!(), - } - match field.next().await { - None => (), - _ => unreachable!(), - } + match field.next().await { + None => (), + _ => unreachable!(), } - _ => unreachable!(), } + _ => unreachable!(), + } - match multipart.next().await { - None => (), - _ => unreachable!(), - } - }); - } + match multipart.next().await.unwrap() { + Ok(mut field) => { + assert_eq!(field.content_type().type_(), mime::TEXT); + assert_eq!(field.content_type().subtype(), mime::PLAIN); - #[test] - fn test_stream() { - block_on(async { - let (sender, payload) = create_stream(); - let (bytes, headers) = create_simple_request_with_header(); - - sender.send(Ok(bytes)).unwrap(); - - let mut multipart = Multipart::new(&headers, payload); - match multipart.next().await.unwrap() { - Ok(mut field) => { - let cd = field.content_disposition().unwrap(); - assert_eq!(cd.disposition, DispositionType::FormData); - assert_eq!(cd.parameters[0], DispositionParam::Name("file".into())); - - assert_eq!(field.content_type().type_(), mime::TEXT); - assert_eq!(field.content_type().subtype(), mime::PLAIN); - - match field.next().await.unwrap() { - Ok(chunk) => assert_eq!(chunk, "test"), - _ => unreachable!(), - } - match field.next().await { - None => (), - _ => unreachable!(), - } + match field.next().await { + Some(Ok(chunk)) => assert_eq!(chunk, "data"), + _ => unreachable!(), } - _ => unreachable!(), - } - - match multipart.next().await { - Some(Ok(mut field)) => { - assert_eq!(field.content_type().type_(), mime::TEXT); - assert_eq!(field.content_type().subtype(), mime::PLAIN); - - match field.next().await { - Some(Ok(chunk)) => assert_eq!(chunk, "data"), - _ => unreachable!(), - } - match field.next().await { - None => (), - _ => unreachable!(), - } + match field.next().await { + None => (), + _ => unreachable!(), } - _ => unreachable!(), } + _ => unreachable!(), + } - match multipart.next().await { - None => (), - _ => unreachable!(), + match multipart.next().await { + None => (), + _ => unreachable!(), + } + } + + #[actix_rt::test] + async fn test_stream() { + let (sender, payload) = create_stream(); + let (bytes, headers) = create_simple_request_with_header(); + + sender.send(Ok(bytes)).unwrap(); + + let mut multipart = Multipart::new(&headers, payload); + match multipart.next().await.unwrap() { + Ok(mut field) => { + let cd = field.content_disposition().unwrap(); + assert_eq!(cd.disposition, DispositionType::FormData); + assert_eq!(cd.parameters[0], DispositionParam::Name("file".into())); + + assert_eq!(field.content_type().type_(), mime::TEXT); + assert_eq!(field.content_type().subtype(), mime::PLAIN); + + match field.next().await.unwrap() { + Ok(chunk) => assert_eq!(chunk, "test"), + _ => unreachable!(), + } + match field.next().await { + None => (), + _ => unreachable!(), + } } - }); + _ => unreachable!(), + } + + match multipart.next().await { + Some(Ok(mut field)) => { + assert_eq!(field.content_type().type_(), mime::TEXT); + assert_eq!(field.content_type().subtype(), mime::PLAIN); + + match field.next().await { + Some(Ok(chunk)) => assert_eq!(chunk, "data"), + _ => unreachable!(), + } + match field.next().await { + None => (), + _ => unreachable!(), + } + } + _ => unreachable!(), + } + + match multipart.next().await { + None => (), + _ => unreachable!(), + } } - #[test] - fn test_basic() { - block_on(async { - let (_, payload) = Payload::create(false); - let mut payload = PayloadBuffer::new(payload); + #[actix_rt::test] + async fn test_basic() { + let (_, payload) = Payload::create(false); + let mut payload = PayloadBuffer::new(payload); - assert_eq!(payload.buf.len(), 0); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!(None, payload.read_max(1).unwrap()); - }) + assert_eq!(payload.buf.len(), 0); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + assert_eq!(None, payload.read_max(1).unwrap()); } - #[test] - fn test_eof() { - block_on(async { - let (mut sender, payload) = Payload::create(false); - let mut payload = PayloadBuffer::new(payload); + #[actix_rt::test] + async fn test_eof() { + let (mut sender, payload) = Payload::create(false); + let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_max(4).unwrap()); - sender.feed_data(Bytes::from("data")); - sender.feed_eof(); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + assert_eq!(None, payload.read_max(4).unwrap()); + sender.feed_data(Bytes::from("data")); + sender.feed_eof(); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap()); - assert_eq!(payload.buf.len(), 0); - assert!(payload.read_max(1).is_err()); - assert!(payload.eof); - }) + assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap()); + assert_eq!(payload.buf.len(), 0); + assert!(payload.read_max(1).is_err()); + assert!(payload.eof); } - #[test] - fn test_err() { - block_on(async { - let (mut sender, payload) = Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_max(1).unwrap()); - sender.set_error(PayloadError::Incomplete(None)); - lazy(|cx| payload.poll_stream(cx)).await.err().unwrap(); - }) + #[actix_rt::test] + async fn test_err() { + let (mut sender, payload) = Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + assert_eq!(None, payload.read_max(1).unwrap()); + sender.set_error(PayloadError::Incomplete(None)); + lazy(|cx| payload.poll_stream(cx)).await.err().unwrap(); } - #[test] - fn test_readmax() { - block_on(async { - let (mut sender, payload) = Payload::create(false); - let mut payload = PayloadBuffer::new(payload); + #[actix_rt::test] + async fn test_readmax() { + let (mut sender, payload) = Payload::create(false); + let mut payload = PayloadBuffer::new(payload); - sender.feed_data(Bytes::from("line1")); - sender.feed_data(Bytes::from("line2")); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!(payload.buf.len(), 10); + sender.feed_data(Bytes::from("line1")); + sender.feed_data(Bytes::from("line2")); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + assert_eq!(payload.buf.len(), 10); - assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap()); - assert_eq!(payload.buf.len(), 5); + assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap()); + assert_eq!(payload.buf.len(), 5); - assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap()); - assert_eq!(payload.buf.len(), 0); - }) + assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap()); + assert_eq!(payload.buf.len(), 0); } - #[test] - fn test_readexactly() { - block_on(async { - let (mut sender, payload) = Payload::create(false); - let mut payload = PayloadBuffer::new(payload); + #[actix_rt::test] + async fn test_readexactly() { + let (mut sender, payload) = Payload::create(false); + let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_exact(2)); + assert_eq!(None, payload.read_exact(2)); - sender.feed_data(Bytes::from("line1")); - sender.feed_data(Bytes::from("line2")); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + sender.feed_data(Bytes::from("line1")); + sender.feed_data(Bytes::from("line2")); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2)); - assert_eq!(payload.buf.len(), 8); + assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2)); + assert_eq!(payload.buf.len(), 8); - assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4)); - assert_eq!(payload.buf.len(), 4); - }) + assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4)); + assert_eq!(payload.buf.len(), 4); } - #[test] - fn test_readuntil() { - block_on(async { - let (mut sender, payload) = Payload::create(false); - let mut payload = PayloadBuffer::new(payload); + #[actix_rt::test] + async fn test_readuntil() { + let (mut sender, payload) = Payload::create(false); + let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_until(b"ne").unwrap()); + assert_eq!(None, payload.read_until(b"ne").unwrap()); - sender.feed_data(Bytes::from("line1")); - sender.feed_data(Bytes::from("line2")); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + sender.feed_data(Bytes::from("line1")); + sender.feed_data(Bytes::from("line2")); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!( - Some(Bytes::from("line")), - payload.read_until(b"ne").unwrap() - ); - assert_eq!(payload.buf.len(), 6); + assert_eq!( + Some(Bytes::from("line")), + payload.read_until(b"ne").unwrap() + ); + assert_eq!(payload.buf.len(), 6); - assert_eq!( - Some(Bytes::from("1line2")), - payload.read_until(b"2").unwrap() - ); - assert_eq!(payload.buf.len(), 0); - }) + assert_eq!( + Some(Bytes::from("1line2")), + payload.read_until(b"2").unwrap() + ); + assert_eq!(payload.buf.len(), 0); } } diff --git a/actix-session/src/cookie.rs b/actix-session/src/cookie.rs index bb5fba97b..5d66d6537 100644 --- a/actix-session/src/cookie.rs +++ b/actix-session/src/cookie.rs @@ -364,125 +364,117 @@ mod tests { use actix_web::{test, web, App}; use bytes::Bytes; - #[test] - fn cookie_session() { - test::block_on(async { - let mut app = test::init_service( - App::new() - .wrap(CookieSession::signed(&[0; 32]).secure(false)) - .service(web::resource("/").to(|ses: Session| { - async move { - let _ = ses.set("counter", 100); - "test" - } - })), - ) - .await; + #[actix_rt::test] + async fn cookie_session() { + let mut app = test::init_service( + App::new() + .wrap(CookieSession::signed(&[0; 32]).secure(false)) + .service(web::resource("/").to(|ses: Session| { + async move { + let _ = ses.set("counter", 100); + "test" + } + })), + ) + .await; - let request = test::TestRequest::get().to_request(); - let response = app.call(request).await.unwrap(); - assert!(response - .response() - .cookies() - .find(|c| c.name() == "actix-session") - .is_some()); - }) + let request = test::TestRequest::get().to_request(); + let response = app.call(request).await.unwrap(); + assert!(response + .response() + .cookies() + .find(|c| c.name() == "actix-session") + .is_some()); } - #[test] - fn private_cookie() { - test::block_on(async { - let mut app = test::init_service( - App::new() - .wrap(CookieSession::private(&[0; 32]).secure(false)) - .service(web::resource("/").to(|ses: Session| { - async move { - let _ = ses.set("counter", 100); - "test" - } - })), - ) - .await; + #[actix_rt::test] + async fn private_cookie() { + let mut app = test::init_service( + App::new() + .wrap(CookieSession::private(&[0; 32]).secure(false)) + .service(web::resource("/").to(|ses: Session| { + async move { + let _ = ses.set("counter", 100); + "test" + } + })), + ) + .await; - let request = test::TestRequest::get().to_request(); - let response = app.call(request).await.unwrap(); - assert!(response - .response() - .cookies() - .find(|c| c.name() == "actix-session") - .is_some()); - }) + let request = test::TestRequest::get().to_request(); + let response = app.call(request).await.unwrap(); + assert!(response + .response() + .cookies() + .find(|c| c.name() == "actix-session") + .is_some()); } - #[test] - fn cookie_session_extractor() { - test::block_on(async { - let mut app = test::init_service( - App::new() - .wrap(CookieSession::signed(&[0; 32]).secure(false)) - .service(web::resource("/").to(|ses: Session| { - async move { - let _ = ses.set("counter", 100); - "test" - } - })), - ) - .await; + #[actix_rt::test] + async fn cookie_session_extractor() { + let mut app = test::init_service( + App::new() + .wrap(CookieSession::signed(&[0; 32]).secure(false)) + .service(web::resource("/").to(|ses: Session| { + async move { + let _ = ses.set("counter", 100); + "test" + } + })), + ) + .await; - let request = test::TestRequest::get().to_request(); - let response = app.call(request).await.unwrap(); - assert!(response - .response() - .cookies() - .find(|c| c.name() == "actix-session") - .is_some()); - }) + let request = test::TestRequest::get().to_request(); + let response = app.call(request).await.unwrap(); + assert!(response + .response() + .cookies() + .find(|c| c.name() == "actix-session") + .is_some()); } - #[test] - fn basics() { - test::block_on(async { - let mut app = test::init_service( - App::new() - .wrap( - CookieSession::signed(&[0; 32]) - .path("/test/") - .name("actix-test") - .domain("localhost") - .http_only(true) - .same_site(SameSite::Lax) - .max_age(100), - ) - .service(web::resource("/").to(|ses: Session| { - async move { - let _ = ses.set("counter", 100); - "test" - } - })) - .service(web::resource("/test/").to(|ses: Session| { - async move { - let val: usize = ses.get("counter").unwrap().unwrap(); - format!("counter: {}", val) - } - })), - ) - .await; + #[actix_rt::test] + async fn basics() { + let mut app = test::init_service( + App::new() + .wrap( + CookieSession::signed(&[0; 32]) + .path("/test/") + .name("actix-test") + .domain("localhost") + .http_only(true) + .same_site(SameSite::Lax) + .max_age(100), + ) + .service(web::resource("/").to(|ses: Session| { + async move { + let _ = ses.set("counter", 100); + "test" + } + })) + .service(web::resource("/test/").to(|ses: Session| { + async move { + let val: usize = ses.get("counter").unwrap().unwrap(); + format!("counter: {}", val) + } + })), + ) + .await; - let request = test::TestRequest::get().to_request(); - let response = app.call(request).await.unwrap(); - let cookie = response - .response() - .cookies() - .find(|c| c.name() == "actix-test") - .unwrap() - .clone(); - assert_eq!(cookie.path().unwrap(), "/test/"); + let request = test::TestRequest::get().to_request(); + let response = app.call(request).await.unwrap(); + let cookie = response + .response() + .cookies() + .find(|c| c.name() == "actix-test") + .unwrap() + .clone(); + assert_eq!(cookie.path().unwrap(), "/test/"); - let request = test::TestRequest::with_uri("/test/") - .cookie(cookie) - .to_request(); - let body = test::read_response(&mut app, request).await; - assert_eq!(body, Bytes::from_static(b"counter: 100")); - }) + let request = test::TestRequest::with_uri("/test/") + .cookie(cookie) + .to_request(); + let body = test::read_response(&mut app, request).await; + assert_eq!(body, Bytes::from_static(b"counter: 100")); } } diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 0aa81e476..95883363a 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -17,6 +17,7 @@ syn = { version = "^1", features = ["full", "parsing"] } proc-macro2 = "^1" [dev-dependencies] +actix-rt = { version = "1.0.0-alpha.1" } actix-web = { version = "2.0.0-alpha.1" } actix-http = { version = "0.3.0-alpha.1", features=["openssl"] } actix-http-test = { version = "0.3.0-alpha.1", features=["openssl"] } diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs index 18c01f374..b6ac6dd18 100644 --- a/actix-web-codegen/tests/test_macro.rs +++ b/actix-web-codegen/tests/test_macro.rs @@ -1,5 +1,5 @@ use actix_http::HttpService; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_web::{http, web::Path, App, HttpResponse, Responder}; use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, trace}; use futures::{future, Future}; @@ -69,95 +69,89 @@ async fn get_param_test(_: Path) -> impl Responder { HttpResponse::Ok() } -#[test] -fn test_params() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new( - App::new() - .service(get_param_test) - .service(put_param_test) - .service(delete_param_test), - ) - }); +#[actix_rt::test] +async fn test_params() { + let srv = TestServer::start(|| { + HttpService::new( + App::new() + .service(get_param_test) + .service(put_param_test) + .service(delete_param_test), + ) + }); - let request = srv.request(http::Method::GET, srv.url("/test/it")); - let response = request.send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::OK); + let request = srv.request(http::Method::GET, srv.url("/test/it")); + let response = request.send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::OK); - let request = srv.request(http::Method::PUT, srv.url("/test/it")); - let response = request.send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::CREATED); + let request = srv.request(http::Method::PUT, srv.url("/test/it")); + let response = request.send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::CREATED); - let request = srv.request(http::Method::DELETE, srv.url("/test/it")); - let response = request.send().await.unwrap(); - assert_eq!(response.status(), http::StatusCode::NO_CONTENT); - }) + let request = srv.request(http::Method::DELETE, srv.url("/test/it")); + let response = request.send().await.unwrap(); + assert_eq!(response.status(), http::StatusCode::NO_CONTENT); } -#[test] -fn test_body() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new( - App::new() - .service(post_test) - .service(put_test) - .service(head_test) - .service(connect_test) - .service(options_test) - .service(trace_test) - .service(patch_test) - .service(test), - ) - }); - let request = srv.request(http::Method::GET, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); +#[actix_rt::test] +async fn test_body() { + let srv = TestServer::start(|| { + HttpService::new( + App::new() + .service(post_test) + .service(put_test) + .service(head_test) + .service(connect_test) + .service(options_test) + .service(trace_test) + .service(patch_test) + .service(test), + ) + }); + let request = srv.request(http::Method::GET, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.request(http::Method::HEAD, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); + let request = srv.request(http::Method::HEAD, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.request(http::Method::CONNECT, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); + let request = srv.request(http::Method::CONNECT, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.request(http::Method::OPTIONS, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); + let request = srv.request(http::Method::OPTIONS, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.request(http::Method::TRACE, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); + let request = srv.request(http::Method::TRACE, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.request(http::Method::PATCH, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); + let request = srv.request(http::Method::PATCH, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); - let request = srv.request(http::Method::PUT, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!(response.status(), http::StatusCode::CREATED); + let request = srv.request(http::Method::PUT, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!(response.status(), http::StatusCode::CREATED); - let request = srv.request(http::Method::POST, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!(response.status(), http::StatusCode::NO_CONTENT); + let request = srv.request(http::Method::POST, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!(response.status(), http::StatusCode::NO_CONTENT); - let request = srv.request(http::Method::GET, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - }) + let request = srv.request(http::Method::GET, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_auto_async() { - block_on(async { - let srv = TestServer::start(|| HttpService::new(App::new().service(auto_async))); +#[actix_rt::test] +async fn test_auto_async() { + let srv = TestServer::start(|| HttpService::new(App::new().service(auto_async))); - let request = srv.request(http::Method::GET, srv.url("/test")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - }) + let request = srv.request(http::Method::GET, srv.url("/test")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); } diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 0f338b404..1b35c279b 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -30,7 +30,7 @@ default = ["brotli", "flate2-zlib"] openssl = ["open-ssl", "actix-http/openssl"] # rustls -# rustls = ["rust-tls", "actix-http/rustls"] +rustls = ["rust-tls", "actix-http/rustls"] # brotli encoding, requires c compiler brotli = ["actix-http/brotli"] @@ -45,6 +45,7 @@ flate2-rust = ["actix-http/flate2-rust"] actix-codec = "0.2.0-alpha.1" actix-service = "1.0.0-alpha.1" actix-http = "0.3.0-alpha.1" +actix-rt = "1.0.0-alpha.1" base64 = "0.10.1" bytes = "0.4" @@ -57,12 +58,10 @@ rand = "0.7" serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.6.1" -tokio-timer = "0.3.0-alpha.6" open-ssl = { version="0.10", package="openssl", optional = true } rust-tls = { version = "0.16.0", package="rustls", optional = true, features = ["dangerous_configuration"] } [dev-dependencies] -actix-rt = "1.0.0-alpha.1" actix-connect = { version = "1.0.0-alpha.1", features=["openssl"] } actix-web = { version = "2.0.0-alpha.1", features=["openssl"] } actix-http = { version = "0.3.0-alpha.1", features=["openssl"] } @@ -73,5 +72,4 @@ brotli2 = { version="0.3.2" } flate2 = { version="1.0.2" } env_logger = "0.6" rand = "0.7" -tokio-tcp = "0.1" webpki = { version = "0.21" } diff --git a/awc/src/lib.rs b/awc/src/lib.rs index d6cea6ded..e995519ea 100644 --- a/awc/src/lib.rs +++ b/awc/src/lib.rs @@ -6,19 +6,16 @@ //! use actix_rt::System; //! use awc::Client; //! -//! fn main() { -//! System::new("test").block_on(async { -//! let mut client = Client::default(); +//! #[actix_rt::main] +//! async fn main() { +//! let mut client = Client::default(); //! -//! client.get("http://www.rust-lang.org") // <- Create request builder -//! .header("User-Agent", "Actix-web") -//! .send() // <- Send http request -//! .await -//! .and_then(|response| { // <- server http response -//! println!("Response: {:?}", response); -//! Ok(()) -//! }) -//! }); +//! let response = client.get("http://www.rust-lang.org") // <- Create request builder +//! .header("User-Agent", "Actix-web") +//! .send() // <- Send http request +//! .await; +//! +//! println!("Response: {:?}", response); //! } //! ``` use std::cell::RefCell; diff --git a/awc/src/request.rs b/awc/src/request.rs index c6b09e95c..3660f8086 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -39,19 +39,18 @@ const HTTPS_ENCODING: &str = "gzip, deflate"; /// ```rust /// use actix_rt::System; /// -/// fn main() { -/// System::new("test").block_on(async { -/// let response = awc::Client::new() -/// .get("http://www.rust-lang.org") // <- Create request builder -/// .header("User-Agent", "Actix-web") -/// .send() // <- Send http request -/// .await; +/// #[actix_rt::main] +/// async fn main() { +/// let response = awc::Client::new() +/// .get("http://www.rust-lang.org") // <- Create request builder +/// .header("User-Agent", "Actix-web") +/// .send() // <- Send http request +/// .await; /// -/// response.and_then(|response| { // <- server http response -/// println!("Response: {:?}", response); -/// Ok(()) -/// }) -/// }); +/// response.and_then(|response| { // <- server http response +/// println!("Response: {:?}", response); +/// Ok(()) +/// }); /// } /// ``` pub struct ClientRequest { @@ -308,25 +307,21 @@ impl ClientRequest { /// Set a cookie /// /// ```rust - /// # use actix_rt::System; - /// fn main() { - /// System::new("test").block_on(async { - /// awc::Client::new().get("https://www.rust-lang.org") - /// .cookie( - /// awc::http::Cookie::build("name", "value") - /// .domain("www.rust-lang.org") - /// .path("/") - /// .secure(true) - /// .http_only(true) - /// .finish(), - /// ) - /// .send() - /// .await - /// .and_then(|response| { - /// println!("Response: {:?}", response); - /// Ok(()) - /// }) - /// }); + /// #[actix_rt::main] + /// async fn main() { + /// let resp = awc::Client::new().get("https://www.rust-lang.org") + /// .cookie( + /// awc::http::Cookie::build("name", "value") + /// .domain("www.rust-lang.org") + /// .path("/") + /// .secure(true) + /// .http_only(true) + /// .finish(), + /// ) + /// .send() + /// .await; + /// + /// println!("Response: {:?}", resp); /// } /// ``` pub fn cookie(mut self, cookie: Cookie<'_>) -> Self { diff --git a/awc/src/response.rs b/awc/src/response.rs index 5ef8e18b5..00ab4cee1 100644 --- a/awc/src/response.rs +++ b/awc/src/response.rs @@ -358,41 +358,37 @@ where #[cfg(test)] mod tests { use super::*; - use actix_http_test::block_on; use serde::{Deserialize, Serialize}; use crate::{http::header, test::TestResponse}; - #[test] - fn test_body() { - block_on(async { - let mut req = - TestResponse::with_header(header::CONTENT_LENGTH, "xxxx").finish(); - match req.body().await.err().unwrap() { - PayloadError::UnknownLength => (), - _ => unreachable!("error"), - } + #[actix_rt::test] + async fn test_body() { + let mut req = TestResponse::with_header(header::CONTENT_LENGTH, "xxxx").finish(); + match req.body().await.err().unwrap() { + PayloadError::UnknownLength => (), + _ => unreachable!("error"), + } - let mut req = - TestResponse::with_header(header::CONTENT_LENGTH, "1000000").finish(); - match req.body().await.err().unwrap() { - PayloadError::Overflow => (), - _ => unreachable!("error"), - } + let mut req = + TestResponse::with_header(header::CONTENT_LENGTH, "1000000").finish(); + match req.body().await.err().unwrap() { + PayloadError::Overflow => (), + _ => unreachable!("error"), + } - let mut req = TestResponse::default() - .set_payload(Bytes::from_static(b"test")) - .finish(); - assert_eq!(req.body().await.ok().unwrap(), Bytes::from_static(b"test")); + let mut req = TestResponse::default() + .set_payload(Bytes::from_static(b"test")) + .finish(); + assert_eq!(req.body().await.ok().unwrap(), Bytes::from_static(b"test")); - let mut req = TestResponse::default() - .set_payload(Bytes::from_static(b"11111111111111")) - .finish(); - match req.body().limit(5).await.err().unwrap() { - PayloadError::Overflow => (), - _ => unreachable!("error"), - } - }) + let mut req = TestResponse::default() + .set_payload(Bytes::from_static(b"11111111111111")) + .finish(); + match req.body().limit(5).await.err().unwrap() { + PayloadError::Overflow => (), + _ => unreachable!("error"), + } } #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -414,58 +410,56 @@ mod tests { } } - #[test] - fn test_json_body() { - block_on(async { - let mut req = TestResponse::default().finish(); - let json = JsonBody::<_, MyObject>::new(&mut req).await; - assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); + #[actix_rt::test] + async fn test_json_body() { + let mut req = TestResponse::default().finish(); + let json = JsonBody::<_, MyObject>::new(&mut req).await; + assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); - let mut req = TestResponse::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/text"), - ) - .finish(); - let json = JsonBody::<_, MyObject>::new(&mut req).await; - assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); + let mut req = TestResponse::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/text"), + ) + .finish(); + let json = JsonBody::<_, MyObject>::new(&mut req).await; + assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); - let mut req = TestResponse::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("10000"), - ) - .finish(); + let mut req = TestResponse::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/json"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("10000"), + ) + .finish(); - let json = JsonBody::<_, MyObject>::new(&mut req).limit(100).await; - assert!(json_eq( - json.err().unwrap(), - JsonPayloadError::Payload(PayloadError::Overflow) - )); + let json = JsonBody::<_, MyObject>::new(&mut req).limit(100).await; + assert!(json_eq( + json.err().unwrap(), + JsonPayloadError::Payload(PayloadError::Overflow) + )); - let mut req = TestResponse::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .finish(); + let mut req = TestResponse::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/json"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .finish(); - let json = JsonBody::<_, MyObject>::new(&mut req).await; - assert_eq!( - json.ok().unwrap(), - MyObject { - name: "test".to_owned() - } - ); - }) + let json = JsonBody::<_, MyObject>::new(&mut req).await; + assert_eq!( + json.ok().unwrap(), + MyObject { + name: "test".to_owned() + } + ); } } diff --git a/awc/src/sender.rs b/awc/src/sender.rs index f7461113a..9cf158c0d 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -4,12 +4,12 @@ use std::rc::Rc; use std::task::{Context, Poll}; use std::time::Duration; +use actix_rt::time::{delay_for, Delay}; use bytes::Bytes; use derive_more::From; use futures::{future::LocalBoxFuture, ready, Future, Stream}; use serde::Serialize; use serde_json; -use tokio_timer::{delay_for, Delay}; use actix_http::body::{Body, BodyStream}; use actix_http::encoding::Decoder; diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 8819b4990..075c83562 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -7,8 +7,8 @@ use std::{fmt, str}; use actix_codec::Framed; use actix_http::cookie::{Cookie, CookieJar}; use actix_http::{ws, Payload, RequestHead}; +use actix_rt::time::Timeout; use percent_encoding::percent_encode; -use tokio_timer::Timeout; use actix_http::cookie::USERINFO; pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message}; @@ -389,21 +389,19 @@ impl fmt::Debug for WebsocketsRequest { #[cfg(test)] mod tests { - use actix_web::test::block_on; - use super::*; use crate::Client; - #[test] - fn test_debug() { + #[actix_rt::test] + async fn test_debug() { let request = Client::new().ws("/").header("x-test", "111"); let repr = format!("{:?}", request); assert!(repr.contains("WebsocketsRequest")); assert!(repr.contains("x-test")); } - #[test] - fn test_header_override() { + #[actix_rt::test] + async fn test_header_override() { let req = Client::build() .header(header::CONTENT_TYPE, "111") .finish() @@ -421,8 +419,8 @@ mod tests { ); } - #[test] - fn basic_auth() { + #[actix_rt::test] + async fn basic_auth() { let req = Client::new() .ws("/") .basic_auth("username", Some("password")); @@ -448,8 +446,8 @@ mod tests { ); } - #[test] - fn bearer_auth() { + #[actix_rt::test] + async fn bearer_auth() { let req = Client::new().ws("/").bearer_auth("someS3cr3tAutht0k3n"); assert_eq!( req.head @@ -463,35 +461,33 @@ mod tests { let _ = req.connect(); } - #[test] - fn basics() { - block_on(async { - let req = Client::new() - .ws("http://localhost/") - .origin("test-origin") - .max_frame_size(100) - .server_mode() - .protocols(&["v1", "v2"]) - .set_header_if_none(header::CONTENT_TYPE, "json") - .set_header_if_none(header::CONTENT_TYPE, "text") - .cookie(Cookie::build("cookie1", "value1").finish()); - assert_eq!( - req.origin.as_ref().unwrap().to_str().unwrap(), - "test-origin" - ); - assert_eq!(req.max_size, 100); - assert_eq!(req.server_mode, true); - assert_eq!(req.protocols, Some("v1,v2".to_string())); - assert_eq!( - req.head.headers.get(header::CONTENT_TYPE).unwrap(), - header::HeaderValue::from_static("json") - ); + #[actix_rt::test] + async fn basics() { + let req = Client::new() + .ws("http://localhost/") + .origin("test-origin") + .max_frame_size(100) + .server_mode() + .protocols(&["v1", "v2"]) + .set_header_if_none(header::CONTENT_TYPE, "json") + .set_header_if_none(header::CONTENT_TYPE, "text") + .cookie(Cookie::build("cookie1", "value1").finish()); + assert_eq!( + req.origin.as_ref().unwrap().to_str().unwrap(), + "test-origin" + ); + assert_eq!(req.max_size, 100); + assert_eq!(req.server_mode, true); + assert_eq!(req.protocols, Some("v1,v2".to_string())); + assert_eq!( + req.head.headers.get(header::CONTENT_TYPE).unwrap(), + header::HeaderValue::from_static("json") + ); - let _ = req.connect().await; + let _ = req.connect().await; - assert!(Client::new().ws("/").connect().await.is_err()); - assert!(Client::new().ws("http:///test").connect().await.is_err()); - assert!(Client::new().ws("hmm://test.com/").connect().await.is_err()); - }) + assert!(Client::new().ws("/").connect().await.is_err()); + assert!(Client::new().ws("http:///test").connect().await.is_err()); + assert!(Client::new().ws("hmm://test.com/").connect().await.is_err()); } } diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index 9e1948f79..15e9a07ac 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -13,7 +13,7 @@ use futures::future::ok; use rand::Rng; use actix_http::HttpService; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_service::pipeline_factory; use actix_web::http::Cookie; use actix_web::middleware::{BodyEncoding, Compress}; @@ -42,514 +42,472 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World"; -#[test] -fn test_simple() { - block_on(async { - let srv = TestServer::start(|| { +#[actix_rt::test] +async fn test_simple() { + let srv = + TestServer::start(|| { HttpService::new(App::new().service( web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))), )) }); - let request = srv.get("/").header("x-test", "111").send(); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + let request = srv.get("/").header("x-test", "111").send(); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - let mut response = srv.post("/").send().await.unwrap(); - assert!(response.status().is_success()); + let mut response = srv.post("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - // camel case - let response = srv.post("/").camel_case().send().await.unwrap(); - assert!(response.status().is_success()); - }) + // camel case + let response = srv.post("/").camel_case().send().await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_json() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new( - App::new().service( - web::resource("/") - .route(web::to(|_: web::Json| HttpResponse::Ok())), - ), - ) - }); +#[actix_rt::test] +async fn test_json() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service( + web::resource("/").route(web::to(|_: web::Json| HttpResponse::Ok())), + )) + }); - let request = srv - .get("/") - .header("x-test", "111") - .send_json(&"TEST".to_string()); - let response = request.await.unwrap(); - assert!(response.status().is_success()); - }) + let request = srv + .get("/") + .header("x-test", "111") + .send_json(&"TEST".to_string()); + let response = request.await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_form() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - |_: web::Form>| HttpResponse::Ok(), - )))) - }); +#[actix_rt::test] +async fn test_form() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to( + |_: web::Form>| HttpResponse::Ok(), + )))) + }); - let mut data = HashMap::new(); - let _ = data.insert("key".to_string(), "TEST".to_string()); + let mut data = HashMap::new(); + let _ = data.insert("key".to_string(), "TEST".to_string()); - let request = srv.get("/").header("x-test", "111").send_form(&data); - let response = request.await.unwrap(); - assert!(response.status().is_success()); - }) + let request = srv.get("/").header("x-test", "111").send_form(&data); + let response = request.await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn test_timeout() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - || { - async { - tokio_timer::delay_for(Duration::from_millis(200)).await; - Ok::<_, Error>(HttpResponse::Ok().body(STR)) - } - }, - )))) - }); +#[actix_rt::test] +async fn test_timeout() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to(|| { + async { + actix_rt::time::delay_for(Duration::from_millis(200)).await; + Ok::<_, Error>(HttpResponse::Ok().body(STR)) + } + })))) + }); - let connector = awc::Connector::new() - .connector(actix_connect::new_connector( - actix_connect::start_default_resolver(), - )) - .timeout(Duration::from_secs(15)) - .finish(); + let connector = awc::Connector::new() + .connector(actix_connect::new_connector( + actix_connect::start_default_resolver(), + )) + .timeout(Duration::from_secs(15)) + .finish(); - let client = awc::Client::build() - .connector(connector) - .timeout(Duration::from_millis(50)) - .finish(); + let client = awc::Client::build() + .connector(connector) + .timeout(Duration::from_millis(50)) + .finish(); - let request = client.get(srv.url("/")).send(); - match request.await { - Err(SendRequestError::Timeout) => (), - _ => panic!(), - } - }) + let request = client.get(srv.url("/")).send(); + match request.await { + Err(SendRequestError::Timeout) => (), + _ => panic!(), + } } -#[test] -fn test_timeout_override() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - || { - async { - tokio_timer::delay_for(Duration::from_millis(200)).await; - Ok::<_, Error>(HttpResponse::Ok().body(STR)) - } - }, - )))) - }); +#[actix_rt::test] +async fn test_timeout_override() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to(|| { + async { + actix_rt::time::delay_for(Duration::from_millis(200)).await; + Ok::<_, Error>(HttpResponse::Ok().body(STR)) + } + })))) + }); - let client = awc::Client::build() - .timeout(Duration::from_millis(50000)) - .finish(); - let request = client - .get(srv.url("/")) - .timeout(Duration::from_millis(50)) - .send(); - match request.await { - Err(SendRequestError::Timeout) => (), - _ => panic!(), - } - }) + let client = awc::Client::build() + .timeout(Duration::from_millis(50000)) + .finish(); + let request = client + .get(srv.url("/")) + .timeout(Duration::from_millis(50)) + .send(); + match request.await { + Err(SendRequestError::Timeout) => (), + _ => panic!(), + } } -#[test] -fn test_connection_reuse() { - block_on(async { - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +#[actix_rt::test] +async fn test_connection_reuse() { + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then(HttpService::new(App::new().service( - web::resource("/").route(web::to(|| HttpResponse::Ok())), - ))) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then(HttpService::new( + App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok()))), + )) + }); - let client = awc::Client::default(); + let client = awc::Client::default(); - // req 1 - let request = client.get(srv.url("/")).send(); - let response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.url("/")).send(); + let response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req = client.post(srv.url("/")); - let response = req.send().await.unwrap(); - assert!(response.status().is_success()); + // req 2 + let req = client.post(srv.url("/")); + let response = req.send().await.unwrap(); + assert!(response.status().is_success()); - // one connection - assert_eq!(num.load(Ordering::Relaxed), 1); - }) + // one connection + assert_eq!(num.load(Ordering::Relaxed), 1); } -#[test] -fn test_connection_force_close() { - block_on(async { - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +#[actix_rt::test] +async fn test_connection_force_close() { + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then(HttpService::new(App::new().service( - web::resource("/").route(web::to(|| HttpResponse::Ok())), - ))) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then(HttpService::new( + App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok()))), + )) + }); - let client = awc::Client::default(); + let client = awc::Client::default(); - // req 1 - let request = client.get(srv.url("/")).force_close().send(); - let response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.url("/")).force_close().send(); + let response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req = client.post(srv.url("/")).force_close(); - let response = req.send().await.unwrap(); - assert!(response.status().is_success()); + // req 2 + let req = client.post(srv.url("/")).force_close(); + let response = req.send().await.unwrap(); + assert!(response.status().is_success()); - // two connection - assert_eq!(num.load(Ordering::Relaxed), 2); - }) + // two connection + assert_eq!(num.load(Ordering::Relaxed), 2); } -#[test] -fn test_connection_server_close() { - block_on(async { - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +#[actix_rt::test] +async fn test_connection_server_close() { + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then(HttpService::new( - App::new().service( - web::resource("/") - .route(web::to(|| HttpResponse::Ok().force_close().finish())), - ), - )) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then(HttpService::new( + App::new().service( + web::resource("/") + .route(web::to(|| HttpResponse::Ok().force_close().finish())), + ), + )) + }); - let client = awc::Client::default(); + let client = awc::Client::default(); - // req 1 - let request = client.get(srv.url("/")).send(); - let response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.url("/")).send(); + let response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req = client.post(srv.url("/")); - let response = req.send().await.unwrap(); - assert!(response.status().is_success()); + // req 2 + let req = client.post(srv.url("/")); + let response = req.send().await.unwrap(); + assert!(response.status().is_success()); - // two connection - assert_eq!(num.load(Ordering::Relaxed), 2); - }) + // two connection + assert_eq!(num.load(Ordering::Relaxed), 2); } -#[test] -fn test_connection_wait_queue() { - block_on(async { - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +#[actix_rt::test] +async fn test_connection_wait_queue() { + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then(HttpService::new(App::new().service( - web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))), - ))) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then(HttpService::new(App::new().service( + web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))), + ))) + }); - let client = awc::Client::build() - .connector(awc::Connector::new().limit(1).finish()) - .finish(); + let client = awc::Client::build() + .connector(awc::Connector::new().limit(1).finish()) + .finish(); - // req 1 - let request = client.get(srv.url("/")).send(); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.url("/")).send(); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req2 = client.post(srv.url("/")); - let req2_fut = req2.send(); + // req 2 + let req2 = client.post(srv.url("/")); + let req2_fut = req2.send(); - // read response 1 - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); + // read response 1 + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - // req 2 - let response = req2_fut.await.unwrap(); - assert!(response.status().is_success()); + // req 2 + let response = req2_fut.await.unwrap(); + assert!(response.status().is_success()); - // two connection - assert_eq!(num.load(Ordering::Relaxed), 1); - }) + // two connection + assert_eq!(num.load(Ordering::Relaxed), 1); } -#[test] -fn test_connection_wait_queue_force_close() { - block_on(async { - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +#[actix_rt::test] +async fn test_connection_wait_queue_force_close() { + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then(HttpService::new( - App::new().service( - web::resource("/") - .route(web::to(|| HttpResponse::Ok().force_close().body(STR))), - ), - )) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then(HttpService::new( + App::new().service( + web::resource("/") + .route(web::to(|| HttpResponse::Ok().force_close().body(STR))), + ), + )) + }); - let client = awc::Client::build() - .connector(awc::Connector::new().limit(1).finish()) - .finish(); + let client = awc::Client::build() + .connector(awc::Connector::new().limit(1).finish()) + .finish(); - // req 1 - let request = client.get(srv.url("/")).send(); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.url("/")).send(); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req2 = client.post(srv.url("/")); - let req2_fut = req2.send(); + // req 2 + let req2 = client.post(srv.url("/")); + let req2_fut = req2.send(); - // read response 1 - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); + // read response 1 + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - // req 2 - let response = req2_fut.await.unwrap(); - assert!(response.status().is_success()); + // req 2 + let response = req2_fut.await.unwrap(); + assert!(response.status().is_success()); - // two connection - assert_eq!(num.load(Ordering::Relaxed), 2); - }) + // two connection + assert_eq!(num.load(Ordering::Relaxed), 2); } -#[test] -fn test_with_query_parameter() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").to( - |req: HttpRequest| { - if req.query_string().contains("qp") { - HttpResponse::Ok() - } else { - HttpResponse::BadRequest() - } - }, - ))) - }); - - let res = awc::Client::new() - .get(srv.url("/?qp=5")) - .send() - .await - .unwrap(); - assert!(res.status().is_success()); - }) -} - -#[test] -fn test_no_decompress() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().wrap(Compress::default()).service( - web::resource("/").route(web::to(|| { - let mut res = HttpResponse::Ok().body(STR); - res.encoding(header::ContentEncoding::Gzip); - res - })), - )) - }); - - let mut res = awc::Client::new() - .get(srv.url("/")) - .no_decompress() - .send() - .await - .unwrap(); - assert!(res.status().is_success()); - - // read response - let bytes = res.body().await.unwrap(); - - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - - // POST - let mut res = awc::Client::new() - .post(srv.url("/")) - .no_decompress() - .send() - .await - .unwrap(); - assert!(res.status().is_success()); - - let bytes = res.body().await.unwrap(); - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -fn test_client_gzip_encoding() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - || { - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(STR.as_ref()).unwrap(); - let data = e.finish().unwrap(); - +#[actix_rt::test] +async fn test_with_query_parameter() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").to( + |req: HttpRequest| { + if req.query_string().contains("qp") { HttpResponse::Ok() - .header("content-encoding", "gzip") - .body(data) - }, - )))) - }); + } else { + HttpResponse::BadRequest() + } + }, + ))) + }); - // client request - let mut response = srv.post("/").send().await.unwrap(); - assert!(response.status().is_success()); - - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + let res = awc::Client::new() + .get(srv.url("/?qp=5")) + .send() + .await + .unwrap(); + assert!(res.status().is_success()); } -#[test] -fn test_client_gzip_encoding_large() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - || { - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(STR.repeat(10).as_ref()).unwrap(); - let data = e.finish().unwrap(); +#[actix_rt::test] +async fn test_no_decompress() { + let srv = TestServer::start(|| { + HttpService::new(App::new().wrap(Compress::default()).service( + web::resource("/").route(web::to(|| { + let mut res = HttpResponse::Ok().body(STR); + res.encoding(header::ContentEncoding::Gzip); + res + })), + )) + }); - HttpResponse::Ok() - .header("content-encoding", "gzip") - .body(data) - }, - )))) - }); + let mut res = awc::Client::new() + .get(srv.url("/")) + .no_decompress() + .send() + .await + .unwrap(); + assert!(res.status().is_success()); - // client request - let mut response = srv.post("/").send().await.unwrap(); - assert!(response.status().is_success()); + // read response + let bytes = res.body().await.unwrap(); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from(STR.repeat(10))); - }) + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); + + // POST + let mut res = awc::Client::new() + .post(srv.url("/")) + .no_decompress() + .send() + .await + .unwrap(); + assert!(res.status().is_success()); + + let bytes = res.body().await.unwrap(); + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } -#[test] -fn test_client_gzip_encoding_large_random() { - block_on(async { - let data = rand::thread_rng() - .sample_iter(&rand::distributions::Alphanumeric) - .take(100_000) - .collect::(); +#[actix_rt::test] +async fn test_client_gzip_encoding() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to(|| { + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(STR.as_ref()).unwrap(); + let data = e.finish().unwrap(); - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - |data: Bytes| { - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(&data).unwrap(); - let data = e.finish().unwrap(); - HttpResponse::Ok() - .header("content-encoding", "gzip") - .body(data) - }, - )))) - }); + HttpResponse::Ok() + .header("content-encoding", "gzip") + .body(data) + })))) + }); - // client request - let mut response = srv.post("/").send_body(data.clone()).await.unwrap(); - assert!(response.status().is_success()); + // client request + let mut response = srv.post("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from(data)); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] -fn test_client_brotli_encoding() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().service(web::resource("/").route(web::to( - |data: Bytes| { - let mut e = BrotliEncoder::new(Vec::new(), 5); - e.write_all(&data).unwrap(); - let data = e.finish().unwrap(); - HttpResponse::Ok() - .header("content-encoding", "br") - .body(data) - }, - )))) - }); +#[actix_rt::test] +async fn test_client_gzip_encoding_large() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to(|| { + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(STR.repeat(10).as_ref()).unwrap(); + let data = e.finish().unwrap(); - // client request - let mut response = srv.post("/").send_body(STR).await.unwrap(); - assert!(response.status().is_success()); + HttpResponse::Ok() + .header("content-encoding", "gzip") + .body(data) + })))) + }); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // client request + let mut response = srv.post("/").send().await.unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from(STR.repeat(10))); } -// #[test] -// fn test_client_brotli_encoding_large_random() { +#[actix_rt::test] +async fn test_client_gzip_encoding_large_random() { + let data = rand::thread_rng() + .sample_iter(&rand::distributions::Alphanumeric) + .take(100_000) + .collect::(); + + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to( + |data: Bytes| { + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(&data).unwrap(); + let data = e.finish().unwrap(); + HttpResponse::Ok() + .header("content-encoding", "gzip") + .body(data) + }, + )))) + }); + + // client request + let mut response = srv.post("/").send_body(data.clone()).await.unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from(data)); +} + +#[actix_rt::test] +async fn test_client_brotli_encoding() { + let srv = TestServer::start(|| { + HttpService::new(App::new().service(web::resource("/").route(web::to( + |data: Bytes| { + let mut e = BrotliEncoder::new(Vec::new(), 5); + e.write_all(&data).unwrap(); + let data = e.finish().unwrap(); + HttpResponse::Ok() + .header("content-encoding", "br") + .body(data) + }, + )))) + }); + + // client request + let mut response = srv.post("/").send_body(STR).await.unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +// #[actix_rt::test] +// async fn test_client_brotli_encoding_large_random() { // let data = rand::thread_rng() // .sample_iter(&rand::distributions::Alphanumeric) // .take(70_000) @@ -583,8 +541,8 @@ fn test_client_brotli_encoding() { // } // #[cfg(feature = "brotli")] -// #[test] -// fn test_client_deflate_encoding() { +// #[actix_rt::test] +// async fn test_client_deflate_encoding() { // let srv = test::TestServer::start(|app| { // app.handler(|req: &HttpRequest| { // req.body() @@ -611,8 +569,8 @@ fn test_client_brotli_encoding() { // assert_eq!(bytes, Bytes::from_static(STR.as_ref())); // } -// #[test] -// fn test_client_deflate_encoding_large_random() { +// #[actix_rt::test] +// async fn test_client_deflate_encoding_large_random() { // let data = rand::thread_rng() // .sample_iter(&rand::distributions::Alphanumeric) // .take(70_000) @@ -644,8 +602,8 @@ fn test_client_brotli_encoding() { // assert_eq!(bytes, Bytes::from(data)); // } -// #[test] -// fn test_client_streaming_explicit() { +// #[actix_rt::test] +// async fn test_client_streaming_explicit() { // let srv = test::TestServer::start(|app| { // app.handler(|req: &HttpRequest| { // req.body() @@ -671,8 +629,8 @@ fn test_client_brotli_encoding() { // assert_eq!(bytes, Bytes::from_static(STR.as_ref())); // } -// #[test] -// fn test_body_streaming_implicit() { +// #[actix_rt::test] +// async fn test_body_streaming_implicit() { // let srv = test::TestServer::start(|app| { // app.handler(|_| { // let body = once(Ok(Bytes::from_static(STR.as_ref()))); @@ -691,83 +649,76 @@ fn test_client_brotli_encoding() { // assert_eq!(bytes, Bytes::from_static(STR.as_ref())); // } -#[test] -fn test_client_cookie_handling() { +#[actix_rt::test] +async fn test_client_cookie_handling() { use std::io::{Error as IoError, ErrorKind}; - block_on(async { - let cookie1 = Cookie::build("cookie1", "value1").finish(); - let cookie2 = Cookie::build("cookie2", "value2") - .domain("www.example.org") - .path("/") - .secure(true) - .http_only(true) - .finish(); - // Q: are all these clones really necessary? A: Yes, possibly - let cookie1b = cookie1.clone(); - let cookie2b = cookie2.clone(); + let cookie1 = Cookie::build("cookie1", "value1").finish(); + let cookie2 = Cookie::build("cookie2", "value2") + .domain("www.example.org") + .path("/") + .secure(true) + .http_only(true) + .finish(); + // Q: are all these clones really necessary? A: Yes, possibly + let cookie1b = cookie1.clone(); + let cookie2b = cookie2.clone(); - let srv = TestServer::start(move || { - let cookie1 = cookie1b.clone(); - let cookie2 = cookie2b.clone(); + let srv = TestServer::start(move || { + let cookie1 = cookie1b.clone(); + let cookie2 = cookie2b.clone(); - HttpService::new(App::new().route( - "/", - web::to(move |req: HttpRequest| { - let cookie1 = cookie1.clone(); - let cookie2 = cookie2.clone(); + HttpService::new(App::new().route( + "/", + web::to(move |req: HttpRequest| { + let cookie1 = cookie1.clone(); + let cookie2 = cookie2.clone(); - async move { - // Check cookies were sent correctly - let res: Result<(), Error> = req - .cookie("cookie1") - .ok_or(()) - .and_then(|c1| { - if c1.value() == "value1" { - Ok(()) - } else { - Err(()) - } - }) - .and_then(|()| req.cookie("cookie2").ok_or(())) - .and_then(|c2| { - if c2.value() == "value2" { - Ok(()) - } else { - Err(()) - } - }) - .map_err(|_| { - Error::from(IoError::from(ErrorKind::NotFound)) - }); + async move { + // Check cookies were sent correctly + let res: Result<(), Error> = req + .cookie("cookie1") + .ok_or(()) + .and_then(|c1| { + if c1.value() == "value1" { + Ok(()) + } else { + Err(()) + } + }) + .and_then(|()| req.cookie("cookie2").ok_or(())) + .and_then(|c2| { + if c2.value() == "value2" { + Ok(()) + } else { + Err(()) + } + }) + .map_err(|_| Error::from(IoError::from(ErrorKind::NotFound))); - if let Err(e) = res { - Err(e) - } else { - // Send some cookies back - Ok::<_, Error>( - HttpResponse::Ok() - .cookie(cookie1) - .cookie(cookie2) - .finish(), - ) - } + if let Err(e) = res { + Err(e) + } else { + // Send some cookies back + Ok::<_, Error>( + HttpResponse::Ok().cookie(cookie1).cookie(cookie2).finish(), + ) } - }), - )) - }); + } + }), + )) + }); - let request = srv.get("/").cookie(cookie1.clone()).cookie(cookie2.clone()); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - let c1 = response.cookie("cookie1").expect("Missing cookie1"); - assert_eq!(c1, cookie1); - let c2 = response.cookie("cookie2").expect("Missing cookie2"); - assert_eq!(c2, cookie2); - }) + let request = srv.get("/").cookie(cookie1.clone()).cookie(cookie2.clone()); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); + let c1 = response.cookie("cookie1").expect("Missing cookie1"); + assert_eq!(c1, cookie1); + let c2 = response.cookie("cookie2").expect("Missing cookie2"); + assert_eq!(c2, cookie2); } -// #[test] +// #[actix_rt::test] // fn client_read_until_eof() { // let addr = test::TestServer::unused_addr(); @@ -797,62 +748,58 @@ fn test_client_cookie_handling() { // assert_eq!(bytes, Bytes::from_static(b"welcome!")); // } -#[test] -fn client_basic_auth() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().route( - "/", - web::to(|req: HttpRequest| { - if req - .headers() - .get(header::AUTHORIZATION) - .unwrap() - .to_str() - .unwrap() - == "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" - { - HttpResponse::Ok() - } else { - HttpResponse::BadRequest() - } - }), - )) - }); +#[actix_rt::test] +async fn client_basic_auth() { + let srv = TestServer::start(|| { + HttpService::new(App::new().route( + "/", + web::to(|req: HttpRequest| { + if req + .headers() + .get(header::AUTHORIZATION) + .unwrap() + .to_str() + .unwrap() + == "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + { + HttpResponse::Ok() + } else { + HttpResponse::BadRequest() + } + }), + )) + }); - // set authorization header to Basic - let request = srv.get("/").basic_auth("username", Some("password")); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - }) + // set authorization header to Basic + let request = srv.get("/").basic_auth("username", Some("password")); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); } -#[test] -fn client_bearer_auth() { - block_on(async { - let srv = TestServer::start(|| { - HttpService::new(App::new().route( - "/", - web::to(|req: HttpRequest| { - if req - .headers() - .get(header::AUTHORIZATION) - .unwrap() - .to_str() - .unwrap() - == "Bearer someS3cr3tAutht0k3n" - { - HttpResponse::Ok() - } else { - HttpResponse::BadRequest() - } - }), - )) - }); +#[actix_rt::test] +async fn client_bearer_auth() { + let srv = TestServer::start(|| { + HttpService::new(App::new().route( + "/", + web::to(|req: HttpRequest| { + if req + .headers() + .get(header::AUTHORIZATION) + .unwrap() + .to_str() + .unwrap() + == "Bearer someS3cr3tAutht0k3n" + { + HttpResponse::Ok() + } else { + HttpResponse::BadRequest() + } + }), + )) + }); - // set authorization header to Bearer - let request = srv.get("/").bearer_auth("someS3cr3tAutht0k3n"); - let response = request.send().await.unwrap(); - assert!(response.status().is_success()); - }) + // set authorization header to Bearer + let request = srv.get("/").bearer_auth("someS3cr3tAutht0k3n"); + let response = request.send().await.unwrap(); + assert!(response.status().is_success()); } diff --git a/awc/tests/test_rustls_client.rs b/awc/tests/test_rustls_client.rs index bdfd21031..ac60d8e83 100644 --- a/awc/tests/test_rustls_client.rs +++ b/awc/tests/test_rustls_client.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use actix_codec::{AsyncRead, AsyncWrite}; use actix_http::HttpService; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_server::ssl::OpensslAcceptor; use actix_service::{pipeline_factory, ServiceFactory}; use actix_web::http::Version; @@ -53,57 +53,54 @@ mod danger { } } -// #[test] -fn _test_connection_reuse_h2() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +// #[actix_rt::test] +async fn _test_connection_reuse_h2() { + let openssl = ssl_acceptor().unwrap(); + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(App::new().service( - web::resource("/").route(web::to(|| HttpResponse::Ok())), - )) - .map_err(|_| ()), - ) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(App::new() + .service(web::resource("/").route(web::to(|| HttpResponse::Ok())))) + .map_err(|_| ()), + ) + }); - // disable ssl verification - let mut config = ClientConfig::new(); - let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; - config.set_protocols(&protos); - config - .dangerous() - .set_certificate_verifier(Arc::new(danger::NoCertificateVerification {})); + // disable ssl verification + let mut config = ClientConfig::new(); + let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + config.set_protocols(&protos); + config + .dangerous() + .set_certificate_verifier(Arc::new(danger::NoCertificateVerification {})); - let client = awc::Client::build() - .connector(awc::Connector::new().rustls(Arc::new(config)).finish()) - .finish(); + let client = awc::Client::build() + .connector(awc::Connector::new().rustls(Arc::new(config)).finish()) + .finish(); - // req 1 - let request = client.get(srv.surl("/")).send(); - let response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.surl("/")).send(); + let response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req = client.post(srv.surl("/")); - let response = req.send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!(response.version(), Version::HTTP_2); + // req 2 + let req = client.post(srv.surl("/")); + let response = req.send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!(response.version(), Version::HTTP_2); - // one connection - assert_eq!(num.load(Ordering::Relaxed), 1); - }) + // one connection + assert_eq!(num.load(Ordering::Relaxed), 1); } diff --git a/awc/tests/test_ssl_client.rs b/awc/tests/test_ssl_client.rs index d37dba291..1abb071a4 100644 --- a/awc/tests/test_ssl_client.rs +++ b/awc/tests/test_ssl_client.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use actix_codec::{AsyncRead, AsyncWrite}; use actix_http::HttpService; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use actix_server::ssl::OpensslAcceptor; use actix_service::{pipeline_factory, ServiceFactory}; use actix_web::http::Version; @@ -35,56 +35,53 @@ fn ssl_acceptor() -> Result> { Ok(actix_server::ssl::OpensslAcceptor::new(builder.build())) } -#[test] -fn test_connection_reuse_h2() { - block_on(async { - let openssl = ssl_acceptor().unwrap(); - let num = Arc::new(AtomicUsize::new(0)); - let num2 = num.clone(); +#[actix_rt::test] +async fn test_connection_reuse_h2() { + let openssl = ssl_acceptor().unwrap(); + let num = Arc::new(AtomicUsize::new(0)); + let num2 = num.clone(); - let srv = TestServer::start(move || { - let num2 = num2.clone(); - pipeline_factory(move |io| { - num2.fetch_add(1, Ordering::Relaxed); - ok(io) - }) - .and_then( - openssl - .clone() - .map_err(|e| println!("Openssl error: {}", e)), - ) - .and_then( - HttpService::build() - .h2(App::new().service( - web::resource("/").route(web::to(|| HttpResponse::Ok())), - )) - .map_err(|_| ()), - ) - }); + let srv = TestServer::start(move || { + let num2 = num2.clone(); + pipeline_factory(move |io| { + num2.fetch_add(1, Ordering::Relaxed); + ok(io) + }) + .and_then( + openssl + .clone() + .map_err(|e| println!("Openssl error: {}", e)), + ) + .and_then( + HttpService::build() + .h2(App::new() + .service(web::resource("/").route(web::to(|| HttpResponse::Ok())))) + .map_err(|_| ()), + ) + }); - // disable ssl verification - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_verify(SslVerifyMode::NONE); - let _ = builder - .set_alpn_protos(b"\x02h2\x08http/1.1") - .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e)); + // disable ssl verification + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + builder.set_verify(SslVerifyMode::NONE); + let _ = builder + .set_alpn_protos(b"\x02h2\x08http/1.1") + .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e)); - let client = awc::Client::build() - .connector(awc::Connector::new().ssl(builder.build()).finish()) - .finish(); + let client = awc::Client::build() + .connector(awc::Connector::new().ssl(builder.build()).finish()) + .finish(); - // req 1 - let request = client.get(srv.surl("/")).send(); - let response = request.await.unwrap(); - assert!(response.status().is_success()); + // req 1 + let request = client.get(srv.surl("/")).send(); + let response = request.await.unwrap(); + assert!(response.status().is_success()); - // req 2 - let req = client.post(srv.surl("/")); - let response = req.send().await.unwrap(); - assert!(response.status().is_success()); - assert_eq!(response.version(), Version::HTTP_2); + // req 2 + let req = client.post(srv.surl("/")); + let response = req.send().await.unwrap(); + assert!(response.status().is_success()); + assert_eq!(response.version(), Version::HTTP_2); - // one connection - assert_eq!(num.load(Ordering::Relaxed), 1); - }) + // one connection + assert_eq!(num.load(Ordering::Relaxed), 1); } diff --git a/awc/tests/test_ws.rs b/awc/tests/test_ws.rs index 633e8db51..2e1d3981e 100644 --- a/awc/tests/test_ws.rs +++ b/awc/tests/test_ws.rs @@ -2,7 +2,7 @@ use std::io; use actix_codec::Framed; use actix_http::{body::BodySize, h1, ws, Error, HttpService, Request, Response}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use bytes::{Bytes, BytesMut}; use futures::future::ok; use futures::{SinkExt, StreamExt}; @@ -28,56 +28,54 @@ async fn ws_service(req: ws::Frame) -> Result { } } -#[test] -fn test_simple() { - block_on(async { - let mut srv = TestServer::start(|| { - HttpService::build() - .upgrade(|(req, mut framed): (Request, Framed<_, _>)| { - async move { - let res = ws::handshake_response(req.head()).finish(); - // send handshake response - framed - .send(h1::Message::Item((res.drop_body(), BodySize::None))) - .await?; +#[actix_rt::test] +async fn test_simple() { + let mut srv = TestServer::start(|| { + HttpService::build() + .upgrade(|(req, mut framed): (Request, Framed<_, _>)| { + async move { + let res = ws::handshake_response(req.head()).finish(); + // send handshake response + framed + .send(h1::Message::Item((res.drop_body(), BodySize::None))) + .await?; - // start websocket service - let framed = framed.into_framed(ws::Codec::new()); - ws::Transport::with(framed, ws_service).await - } - }) - .finish(|_| ok::<_, Error>(Response::NotFound())) - }); + // start websocket service + let framed = framed.into_framed(ws::Codec::new()); + ws::Transport::with(framed, ws_service).await + } + }) + .finish(|_| ok::<_, Error>(Response::NotFound())) + }); - // client service - let mut framed = srv.ws().await.unwrap(); - framed - .send(ws::Message::Text("text".to_string())) - .await - .unwrap(); - let item = framed.next().await.unwrap().unwrap(); - assert_eq!(item, ws::Frame::Text(Some(BytesMut::from("text")))); + // client service + let mut framed = srv.ws().await.unwrap(); + framed + .send(ws::Message::Text("text".to_string())) + .await + .unwrap(); + let item = framed.next().await.unwrap().unwrap(); + assert_eq!(item, ws::Frame::Text(Some(BytesMut::from("text")))); - framed - .send(ws::Message::Binary("text".into())) - .await - .unwrap(); - let item = framed.next().await.unwrap().unwrap(); - assert_eq!( - item, - ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) - ); + framed + .send(ws::Message::Binary("text".into())) + .await + .unwrap(); + let item = framed.next().await.unwrap().unwrap(); + assert_eq!( + item, + ws::Frame::Binary(Some(Bytes::from_static(b"text").into())) + ); - framed.send(ws::Message::Ping("text".into())).await.unwrap(); - let item = framed.next().await.unwrap().unwrap(); - assert_eq!(item, ws::Frame::Pong("text".to_string().into())); + framed.send(ws::Message::Ping("text".into())).await.unwrap(); + let item = framed.next().await.unwrap().unwrap(); + assert_eq!(item, ws::Frame::Pong("text".to_string().into())); - framed - .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) - .await - .unwrap(); + framed + .send(ws::Message::Close(Some(ws::CloseCode::Normal.into()))) + .await + .unwrap(); - let item = framed.next().await.unwrap().unwrap(); - assert_eq!(item, ws::Frame::Close(Some(ws::CloseCode::Normal.into()))); - }) + let item = framed.next().await.unwrap().unwrap(); + assert_eq!(item, ws::Frame::Close(Some(ws::CloseCode::Normal.into()))); } diff --git a/src/app.rs b/src/app.rs index a9dc3f29a..d67817d21 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2,12 +2,10 @@ use std::cell::RefCell; use std::fmt; use std::future::Future; use std::marker::PhantomData; -use std::pin::Pin; use std::rc::Rc; -use std::task::{Context, Poll}; use actix_http::body::{Body, MessageBody}; -use actix_service::boxed::{self, BoxedNewService}; +use actix_service::boxed::{self, BoxServiceFactory}; use actix_service::{ apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, Transform, }; @@ -25,7 +23,7 @@ use crate::service::{ ServiceResponse, }; -type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>; +type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; type FnDataFactory = Box LocalBoxFuture<'static, Result, ()>>>; @@ -485,231 +483,195 @@ where mod tests { use actix_service::Service; use bytes::Bytes; - use futures::future::{ok, Future}; + use futures::future::ok; use super::*; use crate::http::{header, HeaderValue, Method, StatusCode}; use crate::middleware::DefaultHeaders; - use crate::service::{ServiceRequest, ServiceResponse}; - use crate::test::{block_on, call_service, init_service, read_body, TestRequest}; - use crate::{web, Error, HttpRequest, HttpResponse}; + use crate::service::ServiceRequest; + use crate::test::{call_service, init_service, read_body, TestRequest}; + use crate::{web, HttpRequest, HttpResponse}; - #[test] - fn test_default_resource() { - block_on(async { - let mut srv = init_service( - App::new().service(web::resource("/test").to(|| HttpResponse::Ok())), - ) + #[actix_rt::test] + async fn test_default_resource() { + let mut srv = init_service( + App::new().service(web::resource("/test").to(|| HttpResponse::Ok())), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/blah").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + + let mut srv = init_service( + App::new() + .service(web::resource("/test").to(|| HttpResponse::Ok())) + .service( + web::resource("/test2") + .default_service(|r: ServiceRequest| { + ok(r.into_response(HttpResponse::Created())) + }) + .route(web::get().to(|| HttpResponse::Ok())), + ) + .default_service(|r: ServiceRequest| { + ok(r.into_response(HttpResponse::MethodNotAllowed())) + }), + ) + .await; + + let req = TestRequest::with_uri("/blah").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + + let req = TestRequest::with_uri("/test2").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/test2") + .method(Method::POST) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + } + + #[actix_rt::test] + async fn test_data_factory() { + let mut srv = + init_service(App::new().data_factory(|| ok::<_, ()>(10usize)).service( + web::resource("/").to(|_: web::Data| HttpResponse::Ok()), + )) .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); - let req = TestRequest::with_uri("/blah").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - let mut srv = init_service( - App::new() - .service(web::resource("/test").to(|| HttpResponse::Ok())) - .service( - web::resource("/test2") - .default_service(|r: ServiceRequest| { - ok(r.into_response(HttpResponse::Created())) - }) - .route(web::get().to(|| HttpResponse::Ok())), - ) - .default_service(|r: ServiceRequest| { - ok(r.into_response(HttpResponse::MethodNotAllowed())) - }), - ) + let mut srv = + init_service(App::new().data_factory(|| ok::<_, ()>(10u32)).service( + web::resource("/").to(|_: web::Data| HttpResponse::Ok()), + )) .await; - - let req = TestRequest::with_uri("/blah").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - - let req = TestRequest::with_uri("/test2").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/test2") - .method(Method::POST) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - }) + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); } - #[test] - fn test_data_factory() { - block_on(async { - let mut srv = - init_service(App::new().data_factory(|| ok::<_, ()>(10usize)).service( - web::resource("/").to(|_: web::Data| HttpResponse::Ok()), - )) - .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let mut srv = - init_service(App::new().data_factory(|| ok::<_, ()>(10u32)).service( - web::resource("/").to(|_: web::Data| HttpResponse::Ok()), - )) - .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); - }) + #[actix_rt::test] + async fn test_wrap() { + let mut srv = init_service( + App::new() + .wrap( + DefaultHeaders::new() + .header(header::CONTENT_TYPE, HeaderValue::from_static("0001")), + ) + .route("/test", web::get().to(|| HttpResponse::Ok())), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); } - fn md( - req: ServiceRequest, - srv: &mut S, - ) -> impl Future, Error>> - where - S: Service< - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - >, - { - let fut = srv.call(req); - async move { - let mut res = fut.await?; - res.headers_mut() - .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001")); - Ok(res) - } + #[actix_rt::test] + async fn test_router_wrap() { + let mut srv = init_service( + App::new() + .route("/test", web::get().to(|| HttpResponse::Ok())) + .wrap( + DefaultHeaders::new() + .header(header::CONTENT_TYPE, HeaderValue::from_static("0001")), + ), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); } - #[test] - fn test_wrap() { - block_on(async { - let mut srv = - init_service( - App::new() - .wrap(DefaultHeaders::new().header( + #[actix_rt::test] + async fn test_wrap_fn() { + let mut srv = init_service( + App::new() + .wrap_fn(|req, srv| { + let fut = srv.call(req); + async move { + let mut res = fut.await?; + res.headers_mut().insert( header::CONTENT_TYPE, HeaderValue::from_static("0001"), + ); + Ok(res) + } + }) + .service(web::resource("/test").to(|| HttpResponse::Ok())), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); + } + + #[actix_rt::test] + async fn test_router_wrap_fn() { + let mut srv = init_service( + App::new() + .route("/test", web::get().to(|| HttpResponse::Ok())) + .wrap_fn(|req, srv| { + let fut = srv.call(req); + async { + let mut res = fut.await?; + res.headers_mut().insert( + header::CONTENT_TYPE, + HeaderValue::from_static("0001"), + ); + Ok(res) + } + }), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); + } + + #[actix_rt::test] + async fn test_external_resource() { + let mut srv = init_service( + App::new() + .external_resource("youtube", "https://youtube.com/watch/{video_id}") + .route( + "/test", + web::get().to(|req: HttpRequest| { + HttpResponse::Ok().body(format!( + "{}", + req.url_for("youtube", &["12345"]).unwrap() )) - .route("/test", web::get().to(|| HttpResponse::Ok())), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) - } - - #[test] - fn test_router_wrap() { - block_on(async { - let mut srv = - init_service( - App::new() - .route("/test", web::get().to(|| HttpResponse::Ok())) - .wrap(DefaultHeaders::new().header( - header::CONTENT_TYPE, - HeaderValue::from_static("0001"), - )), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) - } - - #[test] - fn test_wrap_fn() { - block_on(async { - let mut srv = init_service( - App::new() - .wrap_fn(|req, srv| { - let fut = srv.call(req); - async move { - let mut res = fut.await?; - res.headers_mut().insert( - header::CONTENT_TYPE, - HeaderValue::from_static("0001"), - ); - Ok(res) - } - }) - .service(web::resource("/test").to(|| HttpResponse::Ok())), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) - } - - #[test] - fn test_router_wrap_fn() { - block_on(async { - let mut srv = init_service( - App::new() - .route("/test", web::get().to(|| HttpResponse::Ok())) - .wrap_fn(|req, srv| { - let fut = srv.call(req); - async { - let mut res = fut.await?; - res.headers_mut().insert( - header::CONTENT_TYPE, - HeaderValue::from_static("0001"), - ); - Ok(res) - } }), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) - } - - #[test] - fn test_external_resource() { - block_on(async { - let mut srv = init_service( - App::new() - .external_resource("youtube", "https://youtube.com/watch/{video_id}") - .route( - "/test", - web::get().to(|req: HttpRequest| { - HttpResponse::Ok().body(format!( - "{}", - req.url_for("youtube", &["12345"]).unwrap() - )) - }), - ), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - let body = read_body(resp).await; - assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345")); - }) + ), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + let body = read_body(resp).await; + assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345")); } } diff --git a/src/app_service.rs b/src/app_service.rs index 7407ee2fb..3fa5a6eed 100644 --- a/src/app_service.rs +++ b/src/app_service.rs @@ -8,9 +8,9 @@ use std::task::{Context, Poll}; use actix_http::{Extensions, Request, Response}; use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url}; use actix_server_config::ServerConfig; -use actix_service::boxed::{self, BoxedNewService, BoxedService}; +use actix_service::boxed::{self, BoxService, BoxServiceFactory}; use actix_service::{service_fn, Service, ServiceFactory}; -use futures::future::{ok, Either, FutureExt, LocalBoxFuture, Ready}; +use futures::future::{ok, FutureExt, LocalBoxFuture}; use crate::config::{AppConfig, AppService}; use crate::data::DataFactory; @@ -21,9 +21,9 @@ use crate::rmap::ResourceMap; use crate::service::{AppServiceFactory, ServiceRequest, ServiceResponse}; type Guards = Vec>; -type HttpService = BoxedService; -type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>; -type BoxedResponse = LocalBoxFuture<'static, Result>; +type HttpService = BoxService; +type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; +type BoxResponse = LocalBoxFuture<'static, Result>; type FnDataFactory = Box LocalBoxFuture<'static, Result, ()>>>; @@ -387,7 +387,7 @@ impl Service for AppRouting { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; - type Future = BoxedResponse; + type Future = BoxResponse; fn poll_ready(&mut self, _: &mut Context) -> Poll> { if self.ready.is_none() { @@ -447,13 +447,12 @@ impl ServiceFactory for AppEntry { #[cfg(test)] mod tests { - use actix_service::Service; - use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::sync::Arc; - use crate::{test, web, App, HttpResponse}; + use crate::test::{init_service, TestRequest}; + use crate::{web, App, HttpResponse}; + use actix_service::Service; struct DropData(Arc); @@ -463,19 +462,20 @@ mod tests { } } - #[test] - fn drop_data() { + #[actix_rt::test] + async fn test_drop_data() { let data = Arc::new(AtomicBool::new(false)); - test::block_on(async { - let mut app = test::init_service( + + { + let mut app = init_service( App::new() .data(DropData(data.clone())) .service(web::resource("/test").to(|| HttpResponse::Ok())), ) .await; - let req = test::TestRequest::with_uri("/test").to_request(); + let req = TestRequest::with_uri("/test").to_request(); let _ = app.call(req).await.unwrap(); - }); + } assert!(data.load(Ordering::Relaxed)); } } diff --git a/src/config.rs b/src/config.rs index 3ce18f98b..57ba10079 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,7 @@ use crate::service::{ type Guards = Vec>; type HttpNewService = - boxed::BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>; + boxed::BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; /// Application configuration pub struct AppService { @@ -246,28 +246,27 @@ mod tests { use super::*; use crate::http::{Method, StatusCode}; - use crate::test::{block_on, call_service, init_service, read_body, TestRequest}; + use crate::test::{call_service, init_service, read_body, TestRequest}; use crate::{web, App, HttpRequest, HttpResponse}; - #[test] - fn test_data() { - block_on(async { - let cfg = |cfg: &mut ServiceConfig| { - cfg.data(10usize); - }; + #[actix_rt::test] + async fn test_data() { + let cfg = |cfg: &mut ServiceConfig| { + cfg.data(10usize); + }; - let mut srv = init_service(App::new().configure(cfg).service( + let mut srv = + init_service(App::new().configure(cfg).service( web::resource("/").to(|_: web::Data| HttpResponse::Ok()), )) .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); } - // #[test] - // fn test_data_factory() { + // #[actix_rt::test] + // async fn test_data_factory() { // let cfg = |cfg: &mut ServiceConfig| { // cfg.data_factory(|| { // sleep(std::time::Duration::from_millis(50)).then(|_| { @@ -282,7 +281,7 @@ mod tests { // web::resource("/").to(|_: web::Data| HttpResponse::Ok()), // )); // let req = TestRequest::default().to_request(); - // let resp = block_on(srv.call(req)).unwrap(); + // let resp = srv.call(req).await.unwrap(); // assert_eq!(resp.status(), StatusCode::OK); // let cfg2 = |cfg: &mut ServiceConfig| { @@ -294,63 +293,58 @@ mod tests { // .configure(cfg2), // ); // let req = TestRequest::default().to_request(); - // let resp = block_on(srv.call(req)).unwrap(); + // let resp = srv.call(req).await.unwrap(); // assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); // } - #[test] - fn test_external_resource() { - block_on(async { - let mut srv = init_service( - App::new() - .configure(|cfg| { - cfg.external_resource( - "youtube", - "https://youtube.com/watch/{video_id}", - ); - }) - .route( - "/test", - web::get().to(|req: HttpRequest| { - HttpResponse::Ok().body(format!( - "{}", - req.url_for("youtube", &["12345"]).unwrap() - )) - }), - ), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - let body = read_body(resp).await; - assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345")); - }) + #[actix_rt::test] + async fn test_external_resource() { + let mut srv = init_service( + App::new() + .configure(|cfg| { + cfg.external_resource( + "youtube", + "https://youtube.com/watch/{video_id}", + ); + }) + .route( + "/test", + web::get().to(|req: HttpRequest| { + HttpResponse::Ok().body(format!( + "{}", + req.url_for("youtube", &["12345"]).unwrap() + )) + }), + ), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + let body = read_body(resp).await; + assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345")); } - #[test] - fn test_service() { - block_on(async { - let mut srv = init_service(App::new().configure(|cfg| { - cfg.service( - web::resource("/test") - .route(web::get().to(|| HttpResponse::Created())), - ) - .route("/index.html", web::get().to(|| HttpResponse::Ok())); - })) - .await; + #[actix_rt::test] + async fn test_service() { + let mut srv = init_service(App::new().configure(|cfg| { + cfg.service( + web::resource("/test").route(web::get().to(|| HttpResponse::Created())), + ) + .route("/index.html", web::get().to(|| HttpResponse::Ok())); + })) + .await; - let req = TestRequest::with_uri("/test") - .method(Method::GET) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::CREATED); + let req = TestRequest::with_uri("/test") + .method(Method::GET) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::CREATED); - let req = TestRequest::with_uri("/index.html") - .method(Method::GET) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) + let req = TestRequest::with_uri("/index.html") + .method(Method::GET) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); } } diff --git a/src/data.rs b/src/data.rs index 5ace3a8f3..e8928188f 100644 --- a/src/data.rs +++ b/src/data.rs @@ -139,104 +139,97 @@ mod tests { use super::*; use crate::http::StatusCode; - use crate::test::{block_on, init_service, TestRequest}; + use crate::test::{init_service, TestRequest}; use crate::{web, App, HttpResponse}; - #[test] - fn test_data_extractor() { - block_on(async { - let mut srv = init_service(App::new().data(10usize).service( + #[actix_rt::test] + async fn test_data_extractor() { + let mut srv = + init_service(App::new().data(10usize).service( web::resource("/").to(|_: web::Data| HttpResponse::Ok()), )) .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); - let mut srv = init_service(App::new().data(10u32).service( + let mut srv = + init_service(App::new().data(10u32).service( web::resource("/").to(|_: web::Data| HttpResponse::Ok()), )) .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); - }) + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); } - #[test] - fn test_register_data_extractor() { - block_on(async { - let mut srv = - init_service(App::new().register_data(Data::new(10usize)).service( - web::resource("/").to(|_: web::Data| HttpResponse::Ok()), - )) - .await; - - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let mut srv = - init_service(App::new().register_data(Data::new(10u32)).service( - web::resource("/").to(|_: web::Data| HttpResponse::Ok()), - )) - .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); - }) - } - - #[test] - fn test_route_data_extractor() { - block_on(async { - let mut srv = init_service(App::new().service( - web::resource("/").data(10usize).route(web::get().to( - |data: web::Data| { - let _ = data.clone(); - HttpResponse::Ok() - }, - )), + #[actix_rt::test] + async fn test_register_data_extractor() { + let mut srv = + init_service(App::new().register_data(Data::new(10usize)).service( + web::resource("/").to(|_: web::Data| HttpResponse::Ok()), )) .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); - // different type - let mut srv = init_service( - App::new().service( - web::resource("/") - .data(10u32) - .route(web::get().to(|_: web::Data| HttpResponse::Ok())), - ), - ) - .await; - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); - }) - } - - #[test] - fn test_override_data() { - block_on(async { - let mut srv = init_service(App::new().data(1usize).service( - web::resource("/").data(10usize).route(web::get().to( - |data: web::Data| { - assert_eq!(*data, 10); - let _ = data.clone(); - HttpResponse::Ok() - }, - )), + let mut srv = + init_service(App::new().register_data(Data::new(10u32)).service( + web::resource("/").to(|_: web::Data| HttpResponse::Ok()), )) .await; + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); + } - let req = TestRequest::default().to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) + #[actix_rt::test] + async fn test_route_data_extractor() { + let mut srv = + init_service(App::new().service(web::resource("/").data(10usize).route( + web::get().to(|data: web::Data| { + let _ = data.clone(); + HttpResponse::Ok() + }), + ))) + .await; + + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + // different type + let mut srv = init_service( + App::new().service( + web::resource("/") + .data(10u32) + .route(web::get().to(|_: web::Data| HttpResponse::Ok())), + ), + ) + .await; + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); + } + + #[actix_rt::test] + async fn test_override_data() { + let mut srv = init_service(App::new().data(1usize).service( + web::resource("/").data(10usize).route(web::get().to( + |data: web::Data| { + assert_eq!(*data, 10); + let _ = data.clone(); + HttpResponse::Ok() + }, + )), + )) + .await; + + let req = TestRequest::default().to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); } } diff --git a/src/extract.rs b/src/extract.rs index 9c8633368..d43402c73 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -270,7 +270,7 @@ mod tests { use serde_derive::Deserialize; use super::*; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; use crate::types::{Form, FormConfig}; #[derive(Deserialize, Debug, PartialEq)] @@ -278,8 +278,8 @@ mod tests { hello: String, } - #[test] - fn test_option() { + #[actix_rt::test] + async fn test_option() { let (req, mut pl) = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded", @@ -287,7 +287,9 @@ mod tests { .data(FormConfig::default().limit(4096)) .to_http_parts(); - let r = block_on(Option::>::from_request(&req, &mut pl)).unwrap(); + let r = Option::>::from_request(&req, &mut pl) + .await + .unwrap(); assert_eq!(r, None); let (req, mut pl) = TestRequest::with_header( @@ -298,7 +300,9 @@ mod tests { .set_payload(Bytes::from_static(b"hello=world")) .to_http_parts(); - let r = block_on(Option::>::from_request(&req, &mut pl)).unwrap(); + let r = Option::>::from_request(&req, &mut pl) + .await + .unwrap(); assert_eq!( r, Some(Form(Info { @@ -314,12 +318,14 @@ mod tests { .set_payload(Bytes::from_static(b"bye=world")) .to_http_parts(); - let r = block_on(Option::>::from_request(&req, &mut pl)).unwrap(); + let r = Option::>::from_request(&req, &mut pl) + .await + .unwrap(); assert_eq!(r, None); } - #[test] - fn test_result() { + #[actix_rt::test] + async fn test_result() { let (req, mut pl) = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded", @@ -328,7 +334,8 @@ mod tests { .set_payload(Bytes::from_static(b"hello=world")) .to_http_parts(); - let r = block_on(Result::, Error>::from_request(&req, &mut pl)) + let r = Result::, Error>::from_request(&req, &mut pl) + .await .unwrap() .unwrap(); assert_eq!( @@ -346,8 +353,9 @@ mod tests { .set_payload(Bytes::from_static(b"bye=world")) .to_http_parts(); - let r = - block_on(Result::, Error>::from_request(&req, &mut pl)).unwrap(); + let r = Result::, Error>::from_request(&req, &mut pl) + .await + .unwrap(); assert!(r.is_err()); } } diff --git a/src/lib.rs b/src/lib.rs index 8063d0d35..4d1facd8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![allow(clippy::borrow_interior_mutable_const, unused_imports, dead_code)] +#![allow(clippy::borrow_interior_mutable_const)] //! Actix web is a small, pragmatic, and extremely fast web framework //! for Rust. //! @@ -143,9 +143,9 @@ pub mod dev { HttpServiceFactory, ServiceRequest, ServiceResponse, WebService, }; - //pub use crate::types::form::UrlEncoded; - //pub use crate::types::json::JsonBody; - //pub use crate::types::readlines::Readlines; + pub use crate::types::form::UrlEncoded; + pub use crate::types::json::JsonBody; + pub use crate::types::readlines::Readlines; pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody, SizedStream}; pub use actix_http::encoding::Decoder as Decompress; @@ -174,17 +174,16 @@ pub mod client { //! use actix_rt::System; //! use actix_web::client::Client; //! - //! fn main() { - //! System::new("test").block_on(async { - //! let mut client = Client::default(); + //! #[actix_rt::main] + //! async fn main() { + //! let mut client = Client::default(); //! - //! // Create request builder and send request - //! let response = client.get("http://www.rust-lang.org") - //! .header("User-Agent", "Actix-web") - //! .send().await; // <- Send http request + //! // Create request builder and send request + //! let response = client.get("http://www.rust-lang.org") + //! .header("User-Agent", "Actix-web") + //! .send().await; // <- Send http request //! - //! println!("Response: {:?}", response); - //! }); + //! println!("Response: {:?}", response); //! } //! ``` pub use awc::error::{ diff --git a/src/middleware/condition.rs b/src/middleware/condition.rs index 6603fc001..2ede81783 100644 --- a/src/middleware/condition.rs +++ b/src/middleware/condition.rs @@ -2,7 +2,7 @@ use std::task::{Context, Poll}; use actix_service::{Service, Transform}; -use futures::future::{ok, Either, FutureExt, LocalBoxFuture, Ready}; +use futures::future::{ok, Either, FutureExt, LocalBoxFuture}; /// `Middleware` for conditionally enables another middleware. /// The controled middleware must not change the `Service` interfaces. @@ -102,7 +102,7 @@ mod tests { use crate::error::Result; use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode}; use crate::middleware::errhandlers::*; - use crate::test::{self, block_on, TestRequest}; + use crate::test::{self, TestRequest}; use crate::HttpResponse; fn render_500(mut res: ServiceResponse) -> Result> { @@ -112,46 +112,40 @@ mod tests { Ok(ErrorHandlerResponse::Response(res)) } - #[test] - fn test_handler_enabled() { - block_on(async { - let srv = |req: ServiceRequest| { - ok(req.into_response(HttpResponse::InternalServerError().finish())) - }; + #[actix_rt::test] + async fn test_handler_enabled() { + let srv = |req: ServiceRequest| { + ok(req.into_response(HttpResponse::InternalServerError().finish())) + }; - let mw = ErrorHandlers::new() - .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500); + let mw = + ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500); - let mut mw = Condition::new(true, mw) - .new_transform(srv.into_service()) - .await - .unwrap(); - let resp = - test::call_service(&mut mw, TestRequest::default().to_srv_request()) - .await; - assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - }) + let mut mw = Condition::new(true, mw) + .new_transform(srv.into_service()) + .await + .unwrap(); + let resp = + test::call_service(&mut mw, TestRequest::default().to_srv_request()).await; + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); } - #[test] - fn test_handler_disabled() { - block_on(async { - let srv = |req: ServiceRequest| { - ok(req.into_response(HttpResponse::InternalServerError().finish())) - }; + #[actix_rt::test] + async fn test_handler_disabled() { + let srv = |req: ServiceRequest| { + ok(req.into_response(HttpResponse::InternalServerError().finish())) + }; - let mw = ErrorHandlers::new() - .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500); + let mw = + ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500); - let mut mw = Condition::new(false, mw) - .new_transform(srv.into_service()) - .await - .unwrap(); + let mut mw = Condition::new(false, mw) + .new_transform(srv.into_service()) + .await + .unwrap(); - let resp = - test::call_service(&mut mw, TestRequest::default().to_srv_request()) - .await; - assert_eq!(resp.headers().get(CONTENT_TYPE), None); - }) + let resp = + test::call_service(&mut mw, TestRequest::default().to_srv_request()).await; + assert_eq!(resp.headers().get(CONTENT_TYPE), None); } } diff --git a/src/middleware/defaultheaders.rs b/src/middleware/defaultheaders.rs index 5c995503a..05a031065 100644 --- a/src/middleware/defaultheaders.rs +++ b/src/middleware/defaultheaders.rs @@ -1,6 +1,4 @@ //! Middleware for setting default response headers -use std::future::Future; -use std::pin::Pin; use std::rc::Rc; use std::task::{Context, Poll}; @@ -161,55 +159,50 @@ mod tests { use super::*; use crate::dev::ServiceRequest; use crate::http::header::CONTENT_TYPE; - use crate::test::{block_on, ok_service, TestRequest}; + use crate::test::{ok_service, TestRequest}; use crate::HttpResponse; - #[test] - fn test_default_headers() { - block_on(async { - let mut mw = DefaultHeaders::new() - .header(CONTENT_TYPE, "0001") - .new_transform(ok_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_default_headers() { + let mut mw = DefaultHeaders::new() + .header(CONTENT_TYPE, "0001") + .new_transform(ok_service()) + .await + .unwrap(); - let req = TestRequest::default().to_srv_request(); - let resp = mw.call(req).await.unwrap(); - assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); + let req = TestRequest::default().to_srv_request(); + let resp = mw.call(req).await.unwrap(); + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - let req = TestRequest::default().to_srv_request(); - let srv = |req: ServiceRequest| { - ok(req.into_response( - HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish(), - )) - }; - let mut mw = DefaultHeaders::new() - .header(CONTENT_TYPE, "0001") - .new_transform(srv.into_service()) - .await - .unwrap(); - let resp = mw.call(req).await.unwrap(); - assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002"); - }) + let req = TestRequest::default().to_srv_request(); + let srv = |req: ServiceRequest| { + ok(req + .into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish())) + }; + let mut mw = DefaultHeaders::new() + .header(CONTENT_TYPE, "0001") + .new_transform(srv.into_service()) + .await + .unwrap(); + let resp = mw.call(req).await.unwrap(); + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002"); } - #[test] - fn test_content_type() { - block_on(async { - let srv = - |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())); - let mut mw = DefaultHeaders::new() - .content_type() - .new_transform(srv.into_service()) - .await - .unwrap(); + #[actix_rt::test] + async fn test_content_type() { + let srv = + |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())); + let mut mw = DefaultHeaders::new() + .content_type() + .new_transform(srv.into_service()) + .await + .unwrap(); - let req = TestRequest::default().to_srv_request(); - let resp = mw.call(req).await.unwrap(); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - "application/octet-stream" - ); - }) + let req = TestRequest::default().to_srv_request(); + let resp = mw.call(req).await.unwrap(); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + "application/octet-stream" + ); } } diff --git a/src/middleware/errhandlers.rs b/src/middleware/errhandlers.rs index c8a702857..3dc1f0828 100644 --- a/src/middleware/errhandlers.rs +++ b/src/middleware/errhandlers.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use std::task::{Context, Poll}; use actix_service::{Service, Transform}; -use futures::future::{err, ok, Either, Future, FutureExt, LocalBoxFuture, Ready}; +use futures::future::{ok, FutureExt, LocalBoxFuture, Ready}; use hashbrown::HashMap; use crate::dev::{ServiceRequest, ServiceResponse}; @@ -151,7 +151,7 @@ mod tests { use super::*; use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode}; - use crate::test::{self, block_on, TestRequest}; + use crate::test::{self, TestRequest}; use crate::HttpResponse; fn render_500(mut res: ServiceResponse) -> Result> { @@ -161,24 +161,21 @@ mod tests { Ok(ErrorHandlerResponse::Response(res)) } - #[test] - fn test_handler() { - block_on(async { - let srv = |req: ServiceRequest| { - ok(req.into_response(HttpResponse::InternalServerError().finish())) - }; + #[actix_rt::test] + async fn test_handler() { + let srv = |req: ServiceRequest| { + ok(req.into_response(HttpResponse::InternalServerError().finish())) + }; - let mut mw = ErrorHandlers::new() - .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500) - .new_transform(srv.into_service()) - .await - .unwrap(); + let mut mw = ErrorHandlers::new() + .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500) + .new_transform(srv.into_service()) + .await + .unwrap(); - let resp = - test::call_service(&mut mw, TestRequest::default().to_srv_request()) - .await; - assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - }) + let resp = + test::call_service(&mut mw, TestRequest::default().to_srv_request()).await; + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); } fn render_500_async( @@ -190,23 +187,20 @@ mod tests { Ok(ErrorHandlerResponse::Future(ok(res).boxed_local())) } - #[test] - fn test_handler_async() { - block_on(async { - let srv = |req: ServiceRequest| { - ok(req.into_response(HttpResponse::InternalServerError().finish())) - }; + #[actix_rt::test] + async fn test_handler_async() { + let srv = |req: ServiceRequest| { + ok(req.into_response(HttpResponse::InternalServerError().finish())) + }; - let mut mw = ErrorHandlers::new() - .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500_async) - .new_transform(srv.into_service()) - .await - .unwrap(); + let mut mw = ErrorHandlers::new() + .handler(StatusCode::INTERNAL_SERVER_ERROR, render_500_async) + .new_transform(srv.into_service()) + .await + .unwrap(); - let resp = - test::call_service(&mut mw, TestRequest::default().to_srv_request()) - .await; - assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - }) + let resp = + test::call_service(&mut mw, TestRequest::default().to_srv_request()).await; + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); } } diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index 45df4bf34..a57ea2961 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -479,10 +479,10 @@ mod tests { use super::*; use crate::http::{header, StatusCode}; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; - #[test] - fn test_logger() { + #[actix_rt::test] + async fn test_logger() { let srv = |req: ServiceRequest| { ok(req.into_response( HttpResponse::build(StatusCode::OK) @@ -492,18 +492,18 @@ mod tests { }; let logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test"); - let mut srv = block_on(logger.new_transform(srv.into_service())).unwrap(); + let mut srv = logger.new_transform(srv.into_service()).await.unwrap(); let req = TestRequest::with_header( header::USER_AGENT, header::HeaderValue::from_static("ACTIX-WEB"), ) .to_srv_request(); - let _res = block_on(srv.call(req)); + let _res = srv.call(req).await; } - #[test] - fn test_url_path() { + #[actix_rt::test] + async fn test_url_path() { let mut format = Format::new("%T %U"); let req = TestRequest::with_header( header::USER_AGENT, @@ -533,8 +533,8 @@ mod tests { assert!(s.contains("/test/route/yeah")); } - #[test] - fn test_default_format() { + #[actix_rt::test] + async fn test_default_format() { let mut format = Format::default(); let req = TestRequest::with_header( @@ -566,8 +566,8 @@ mod tests { assert!(s.contains("ACTIX-WEB")); } - #[test] - fn test_request_time_format() { + #[actix_rt::test] + async fn test_request_time_format() { let mut format = Format::new("%t"); let req = TestRequest::default().to_srv_request(); diff --git a/src/middleware/normalize.rs b/src/middleware/normalize.rs index b7eb1384a..2926eacc9 100644 --- a/src/middleware/normalize.rs +++ b/src/middleware/normalize.rs @@ -105,62 +105,56 @@ mod tests { use super::*; use crate::dev::ServiceRequest; - use crate::test::{block_on, call_service, init_service, TestRequest}; + use crate::test::{call_service, init_service, TestRequest}; use crate::{web, App, HttpResponse}; - #[test] - fn test_wrap() { - block_on(async { - let mut app = init_service( - App::new() - .wrap(NormalizePath::default()) - .service(web::resource("/v1/something/").to(|| HttpResponse::Ok())), - ) - .await; + #[actix_rt::test] + async fn test_wrap() { + let mut app = init_service( + App::new() + .wrap(NormalizePath::default()) + .service(web::resource("/v1/something/").to(|| HttpResponse::Ok())), + ) + .await; - let req = TestRequest::with_uri("/v1//something////").to_request(); - let res = call_service(&mut app, req).await; - assert!(res.status().is_success()); - }) + let req = TestRequest::with_uri("/v1//something////").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); } - #[test] - fn test_in_place_normalization() { - block_on(async { - let srv = |req: ServiceRequest| { - assert_eq!("/v1/something/", req.path()); - ok(req.into_response(HttpResponse::Ok().finish())) - }; + #[actix_rt::test] + async fn test_in_place_normalization() { + let srv = |req: ServiceRequest| { + assert_eq!("/v1/something/", req.path()); + ok(req.into_response(HttpResponse::Ok().finish())) + }; - let mut normalize = NormalizePath - .new_transform(srv.into_service()) - .await - .unwrap(); + let mut normalize = NormalizePath + .new_transform(srv.into_service()) + .await + .unwrap(); - let req = TestRequest::with_uri("/v1//something////").to_srv_request(); - let res = normalize.call(req).await.unwrap(); - assert!(res.status().is_success()); - }) + let req = TestRequest::with_uri("/v1//something////").to_srv_request(); + let res = normalize.call(req).await.unwrap(); + assert!(res.status().is_success()); } - #[test] - fn should_normalize_nothing() { - block_on(async { - const URI: &str = "/v1/something/"; + #[actix_rt::test] + async fn should_normalize_nothing() { + const URI: &str = "/v1/something/"; - let srv = |req: ServiceRequest| { - assert_eq!(URI, req.path()); - ok(req.into_response(HttpResponse::Ok().finish())) - }; + let srv = |req: ServiceRequest| { + assert_eq!(URI, req.path()); + ok(req.into_response(HttpResponse::Ok().finish())) + }; - let mut normalize = NormalizePath - .new_transform(srv.into_service()) - .await - .unwrap(); + let mut normalize = NormalizePath + .new_transform(srv.into_service()) + .await + .unwrap(); - let req = TestRequest::with_uri(URI).to_srv_request(); - let res = normalize.call(req).await.unwrap(); - assert!(res.status().is_success()); - }) + let req = TestRequest::with_uri(URI).to_srv_request(); + let res = normalize.call(req).await.unwrap(); + assert!(res.status().is_success()); } } diff --git a/src/request.rs b/src/request.rs index 19072fcb1..84f0503c0 100644 --- a/src/request.rs +++ b/src/request.rs @@ -350,7 +350,7 @@ mod tests { use super::*; use crate::dev::{ResourceDef, ResourceMap}; use crate::http::{header, StatusCode}; - use crate::test::{block_on, call_service, init_service, TestRequest}; + use crate::test::{call_service, init_service, TestRequest}; use crate::{web, App, HttpResponse}; #[test] @@ -466,16 +466,62 @@ mod tests { ); } - #[test] - fn test_app_data() { - block_on(async { - let mut srv = init_service(App::new().data(10usize).service( - web::resource("/").to(|req: HttpRequest| { - if req.app_data::().is_some() { - HttpResponse::Ok() - } else { - HttpResponse::BadRequest() - } + #[actix_rt::test] + async fn test_app_data() { + let mut srv = init_service(App::new().data(10usize).service( + web::resource("/").to(|req: HttpRequest| { + if req.app_data::().is_some() { + HttpResponse::Ok() + } else { + HttpResponse::BadRequest() + } + }), + )) + .await; + + let req = TestRequest::default().to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + + let mut srv = init_service(App::new().data(10u32).service( + web::resource("/").to(|req: HttpRequest| { + if req.app_data::().is_some() { + HttpResponse::Ok() + } else { + HttpResponse::BadRequest() + } + }), + )) + .await; + + let req = TestRequest::default().to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + } + + #[actix_rt::test] + async fn test_extensions_dropped() { + struct Tracker { + pub dropped: bool, + } + struct Foo { + tracker: Rc>, + } + impl Drop for Foo { + fn drop(&mut self) { + self.tracker.borrow_mut().dropped = true; + } + } + + let tracker = Rc::new(RefCell::new(Tracker { dropped: false })); + { + let tracker2 = Rc::clone(&tracker); + let mut srv = init_service(App::new().data(10u32).service( + web::resource("/").to(move |req: HttpRequest| { + req.extensions_mut().insert(Foo { + tracker: Rc::clone(&tracker2), + }); + HttpResponse::Ok() }), )) .await; @@ -483,58 +529,8 @@ mod tests { let req = TestRequest::default().to_request(); let resp = call_service(&mut srv, req).await; assert_eq!(resp.status(), StatusCode::OK); + } - let mut srv = init_service(App::new().data(10u32).service( - web::resource("/").to(|req: HttpRequest| { - if req.app_data::().is_some() { - HttpResponse::Ok() - } else { - HttpResponse::BadRequest() - } - }), - )) - .await; - - let req = TestRequest::default().to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - }) - } - - #[test] - fn test_extensions_dropped() { - block_on(async { - struct Tracker { - pub dropped: bool, - } - struct Foo { - tracker: Rc>, - } - impl Drop for Foo { - fn drop(&mut self) { - self.tracker.borrow_mut().dropped = true; - } - } - - let tracker = Rc::new(RefCell::new(Tracker { dropped: false })); - { - let tracker2 = Rc::clone(&tracker); - let mut srv = init_service(App::new().data(10u32).service( - web::resource("/").to(move |req: HttpRequest| { - req.extensions_mut().insert(Foo { - tracker: Rc::clone(&tracker2), - }); - HttpResponse::Ok() - }), - )) - .await; - - let req = TestRequest::default().to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - } - - assert!(tracker.borrow().dropped); - }) + assert!(tracker.borrow().dropped); } } diff --git a/src/resource.rs b/src/resource.rs index 758e2f282..866cbecf5 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -6,12 +6,11 @@ use std::rc::Rc; use std::task::{Context, Poll}; use actix_http::{Error, Extensions, Response}; -use actix_service::boxed::{self, BoxedNewService, BoxedService}; +use actix_service::boxed::{self, BoxService, BoxServiceFactory}; use actix_service::{ apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform, }; use futures::future::{ok, Either, LocalBoxFuture, Ready}; -use pin_project::pin_project; use crate::data::Data; use crate::dev::{insert_slash, AppService, HttpServiceFactory, ResourceDef}; @@ -22,8 +21,8 @@ use crate::responder::Responder; use crate::route::{CreateRouteService, Route, RouteService}; use crate::service::{ServiceRequest, ServiceResponse}; -type HttpService = BoxedService; -type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>; +type HttpService = BoxService; +type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; /// *Resource* is an entry in resources table which corresponds to requested URL. /// @@ -585,40 +584,20 @@ impl ServiceFactory for ResourceEndpoint { mod tests { use std::time::Duration; + use actix_rt::time::delay_for; use actix_service::Service; - use futures::future::{ok, Future}; - use tokio_timer::delay_for; + use futures::future::ok; use crate::http::{header, HeaderValue, Method, StatusCode}; use crate::middleware::DefaultHeaders; - use crate::service::{ServiceRequest, ServiceResponse}; - use crate::test::{block_on, call_service, init_service, TestRequest}; + use crate::service::ServiceRequest; + use crate::test::{call_service, init_service, TestRequest}; use crate::{guard, web, App, Error, HttpResponse}; - fn md( - req: ServiceRequest, - srv: &mut S, - ) -> impl Future, Error>> - where - S: Service< - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - >, - { - let fut = srv.call(req); - async move { - let mut res = fut.await?; - res.headers_mut() - .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001")); - Ok(res) - } - } - - #[test] - fn test_middleware() { - block_on(async { - let mut srv = init_service( + #[actix_rt::test] + async fn test_middleware() { + let mut srv = + init_service( App::new().service( web::resource("/test") .name("test") @@ -630,185 +609,173 @@ mod tests { ), ) .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); } - #[test] - fn test_middleware_fn() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::resource("/test") - .wrap_fn(|req, srv| { - let fut = srv.call(req); - async { - fut.await.map(|mut res| { - res.headers_mut().insert( - header::CONTENT_TYPE, - HeaderValue::from_static("0001"), - ); - res - }) - } - }) - .route(web::get().to(|| HttpResponse::Ok())), - ), - ) + #[actix_rt::test] + async fn test_middleware_fn() { + let mut srv = init_service( + App::new().service( + web::resource("/test") + .wrap_fn(|req, srv| { + let fut = srv.call(req); + async { + fut.await.map(|mut res| { + res.headers_mut().insert( + header::CONTENT_TYPE, + HeaderValue::from_static("0001"), + ); + res + }) + } + }) + .route(web::get().to(|| HttpResponse::Ok())), + ), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); + } + + #[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()) + } + }))) .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn test_to() { - block_on(async { - let mut srv = - 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(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - }) - } + #[actix_rt::test] + async fn test_default_resource() { + let mut srv = init_service( + App::new() + .service( + web::resource("/test").route(web::get().to(|| HttpResponse::Ok())), + ) + .default_service(|r: ServiceRequest| { + ok(r.into_response(HttpResponse::BadRequest())) + }), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); - #[test] - fn test_default_resource() { - block_on(async { - let mut srv = init_service( - App::new() - .service( - web::resource("/test") - .route(web::get().to(|| HttpResponse::Ok())), - ) + let req = TestRequest::with_uri("/test") + .method(Method::POST) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + + let mut srv = init_service( + App::new().service( + web::resource("/test") + .route(web::get().to(|| HttpResponse::Ok())) .default_service(|r: ServiceRequest| { ok(r.into_response(HttpResponse::BadRequest())) }), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); + ), + ) + .await; - let req = TestRequest::with_uri("/test") - .method(Method::POST) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + let req = TestRequest::with_uri("/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); - let mut srv = init_service( - App::new().service( - web::resource("/test") - .route(web::get().to(|| HttpResponse::Ok())) - .default_service(|r: ServiceRequest| { - ok(r.into_response(HttpResponse::BadRequest())) - }), + let req = TestRequest::with_uri("/test") + .method(Method::POST) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + } + + #[actix_rt::test] + async fn test_resource_guards() { + let mut srv = init_service( + App::new() + .service( + web::resource("/test/{p}") + .guard(guard::Get()) + .to(|| HttpResponse::Ok()), + ) + .service( + web::resource("/test/{p}") + .guard(guard::Put()) + .to(|| HttpResponse::Created()), + ) + .service( + web::resource("/test/{p}") + .guard(guard::Delete()) + .to(|| HttpResponse::NoContent()), ), - ) - .await; + ) + .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::with_uri("/test/it") + .method(Method::GET) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); - let req = TestRequest::with_uri("/test") - .method(Method::POST) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - }) + let req = TestRequest::with_uri("/test/it") + .method(Method::PUT) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::CREATED); + + let req = TestRequest::with_uri("/test/it") + .method(Method::DELETE) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::NO_CONTENT); } - #[test] - fn test_resource_guards() { - block_on(async { - let mut srv = init_service( - App::new() - .service( - web::resource("/test/{p}") - .guard(guard::Get()) - .to(|| HttpResponse::Ok()), - ) - .service( - web::resource("/test/{p}") - .guard(guard::Put()) - .to(|| HttpResponse::Created()), - ) - .service( - web::resource("/test/{p}") - .guard(guard::Delete()) - .to(|| HttpResponse::NoContent()), - ), - ) - .await; + #[actix_rt::test] + async fn test_data() { + let mut srv = init_service( + App::new() + .data(1.0f64) + .data(1usize) + .register_data(web::Data::new('-')) + .service( + web::resource("/test") + .data(10usize) + .register_data(web::Data::new('*')) + .guard(guard::Get()) + .to( + |data1: web::Data, + data2: web::Data, + data3: web::Data| { + assert_eq!(*data1, 10); + assert_eq!(*data2, '*'); + assert_eq!(*data3, 1.0); + HttpResponse::Ok() + }, + ), + ), + ) + .await; - let req = TestRequest::with_uri("/test/it") - .method(Method::GET) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/test/it") - .method(Method::PUT) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::CREATED); - - let req = TestRequest::with_uri("/test/it") - .method(Method::DELETE) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::NO_CONTENT); - }) - } - - #[test] - fn test_data() { - block_on(async { - let mut srv = init_service( - App::new() - .data(1.0f64) - .data(1usize) - .register_data(web::Data::new('-')) - .service( - web::resource("/test") - .data(10usize) - .register_data(web::Data::new('*')) - .guard(guard::Get()) - .to( - |data1: web::Data, - data2: web::Data, - data3: web::Data| { - assert_eq!(*data1, 10); - assert_eq!(*data2, '*'); - assert_eq!(*data3, 1.0); - 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); - }) + 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/responder.rs b/src/responder.rs index fd86bb686..7b30315f5 100644 --- a/src/responder.rs +++ b/src/responder.rs @@ -10,7 +10,7 @@ use actix_http::http::{ }; use actix_http::{Error, Response, ResponseBuilder}; use bytes::{Bytes, BytesMut}; -use futures::future::{err, ok, Either as EitherFuture, LocalBoxFuture, Ready}; +use futures::future::{err, ok, Either as EitherFuture, Ready}; use futures::ready; use pin_project::{pin_project, project}; @@ -457,37 +457,34 @@ pub(crate) mod tests { use super::*; use crate::dev::{Body, ResponseBody}; use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode}; - use crate::test::{block_on, init_service, TestRequest}; + use crate::test::{init_service, TestRequest}; use crate::{error, web, App, HttpResponse}; - #[test] - fn test_option_responder() { - block_on(async { - let mut srv = init_service( - App::new() - .service( - web::resource("/none") - .to(|| async { Option::<&'static str>::None }), - ) - .service(web::resource("/some").to(|| async { Some("some") })), - ) - .await; + #[actix_rt::test] + async fn test_option_responder() { + let mut srv = init_service( + App::new() + .service( + web::resource("/none").to(|| async { Option::<&'static str>::None }), + ) + .service(web::resource("/some").to(|| async { Some("some") })), + ) + .await; - let req = TestRequest::with_uri("/none").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); + let req = TestRequest::with_uri("/none").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); - let req = TestRequest::with_uri("/some").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - match resp.response().body() { - ResponseBody::Body(Body::Bytes(ref b)) => { - let bytes: Bytes = b.clone().into(); - assert_eq!(bytes, Bytes::from_static(b"some")); - } - _ => panic!(), + let req = TestRequest::with_uri("/some").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + match resp.response().body() { + ResponseBody::Body(Body::Bytes(ref b)) => { + let bytes: Bytes = b.clone().into(); + assert_eq!(bytes, Bytes::from_static(b"some")); } - }) + _ => panic!(), + } } pub(crate) trait BodyTest { @@ -516,153 +513,142 @@ pub(crate) mod tests { } } - #[test] - fn test_responder() { - block_on(async { - let req = TestRequest::default().to_http_request(); + #[actix_rt::test] + async fn test_responder() { + let req = TestRequest::default().to_http_request(); - let resp: HttpResponse = "test".respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("text/plain; charset=utf-8") - ); + let resp: HttpResponse = "test".respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); - let resp: HttpResponse = b"test".respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("application/octet-stream") - ); + let resp: HttpResponse = b"test".respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("application/octet-stream") + ); - let resp: HttpResponse = "test".to_string().respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("text/plain; charset=utf-8") - ); + let resp: HttpResponse = "test".to_string().respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); - let resp: HttpResponse = - (&"test".to_string()).respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("text/plain; charset=utf-8") - ); + let resp: HttpResponse = (&"test".to_string()).respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); - let resp: HttpResponse = - Bytes::from_static(b"test").respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("application/octet-stream") - ); + let resp: HttpResponse = + Bytes::from_static(b"test").respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("application/octet-stream") + ); - let resp: HttpResponse = BytesMut::from(b"test".as_ref()) - .respond_to(&req) - .await - .unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("application/octet-stream") - ); - - // InternalError - let resp: HttpResponse = - error::InternalError::new("err", StatusCode::BAD_REQUEST) - .respond_to(&req) - .await - .unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - }) - } - - #[test] - fn test_result_responder() { - block_on(async { - let req = TestRequest::default().to_http_request(); - - // Result - let resp: HttpResponse = Ok::<_, Error>("test".to_string()) - .respond_to(&req) - .await - .unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.body().bin_ref(), b"test"); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("text/plain; charset=utf-8") - ); - - let res = Err::(error::InternalError::new( - "err", - StatusCode::BAD_REQUEST, - )) + let resp: HttpResponse = BytesMut::from(b"test".as_ref()) .respond_to(&req) - .await; - assert!(res.is_err()); - }) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("application/octet-stream") + ); + + // InternalError + let resp: HttpResponse = + error::InternalError::new("err", StatusCode::BAD_REQUEST) + .respond_to(&req) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); } - #[test] - fn test_custom_responder() { - block_on(async { - let req = TestRequest::default().to_http_request(); - let res = "test" - .to_string() - .with_status(StatusCode::BAD_REQUEST) - .respond_to(&req) - .await - .unwrap(); - assert_eq!(res.status(), StatusCode::BAD_REQUEST); - assert_eq!(res.body().bin_ref(), b"test"); + #[actix_rt::test] + async fn test_result_responder() { + let req = TestRequest::default().to_http_request(); - let res = "test" - .to_string() - .with_header("content-type", "json") - .respond_to(&req) - .await - .unwrap(); + // Result + let resp: HttpResponse = Ok::<_, Error>("test".to_string()) + .respond_to(&req) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!(resp.body().bin_ref(), b"test"); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("text/plain; charset=utf-8") + ); - assert_eq!(res.status(), StatusCode::OK); - assert_eq!(res.body().bin_ref(), b"test"); - assert_eq!( - res.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("json") - ); - }) + let res = + Err::(error::InternalError::new("err", StatusCode::BAD_REQUEST)) + .respond_to(&req) + .await; + assert!(res.is_err()); } - #[test] - fn test_tuple_responder_with_status_code() { - block_on(async { - let req = TestRequest::default().to_http_request(); - let res = ("test".to_string(), StatusCode::BAD_REQUEST) - .respond_to(&req) - .await - .unwrap(); - assert_eq!(res.status(), StatusCode::BAD_REQUEST); - assert_eq!(res.body().bin_ref(), b"test"); + #[actix_rt::test] + async fn test_custom_responder() { + let req = TestRequest::default().to_http_request(); + let res = "test" + .to_string() + .with_status(StatusCode::BAD_REQUEST) + .respond_to(&req) + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::BAD_REQUEST); + assert_eq!(res.body().bin_ref(), b"test"); - let req = TestRequest::default().to_http_request(); - let res = ("test".to_string(), StatusCode::OK) - .with_header("content-type", "json") - .respond_to(&req) - .await - .unwrap(); - assert_eq!(res.status(), StatusCode::OK); - assert_eq!(res.body().bin_ref(), b"test"); - assert_eq!( - res.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("json") - ); - }) + let res = "test" + .to_string() + .with_header("content-type", "json") + .respond_to(&req) + .await + .unwrap(); + + assert_eq!(res.status(), StatusCode::OK); + assert_eq!(res.body().bin_ref(), b"test"); + assert_eq!( + res.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("json") + ); + } + + #[actix_rt::test] + async fn test_tuple_responder_with_status_code() { + let req = TestRequest::default().to_http_request(); + let res = ("test".to_string(), StatusCode::BAD_REQUEST) + .respond_to(&req) + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::BAD_REQUEST); + assert_eq!(res.body().bin_ref(), b"test"); + + let req = TestRequest::default().to_http_request(); + let res = ("test".to_string(), StatusCode::OK) + .with_header("content-type", "json") + .respond_to(&req) + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + assert_eq!(res.body().bin_ref(), b"test"); + assert_eq!( + res.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("json") + ); } } diff --git a/src/route.rs b/src/route.rs index 3ebfc3f52..93f88bfe2 100644 --- a/src/route.rs +++ b/src/route.rs @@ -5,7 +5,7 @@ use std::task::{Context, Poll}; use actix_http::{http::Method, Error}; use actix_service::{Service, ServiceFactory}; -use futures::future::{ok, ready, Either, FutureExt, LocalBoxFuture, Ready}; +use futures::future::{ready, FutureExt, LocalBoxFuture}; use crate::extract::FromRequest; use crate::guard::{self, Guard}; @@ -342,93 +342,90 @@ where mod tests { use std::time::Duration; + use actix_rt::time::delay_for; use bytes::Bytes; - use futures::Future; use serde_derive::Serialize; - use tokio_timer::delay_for; use crate::http::{Method, StatusCode}; - use crate::test::{block_on, call_service, init_service, read_body, TestRequest}; - use crate::{error, web, App, Error, HttpResponse}; + use crate::test::{call_service, init_service, read_body, TestRequest}; + use crate::{error, web, App, HttpResponse}; #[derive(Serialize, PartialEq, Debug)] struct MyObject { name: String, } - #[test] - fn test_route() { - block_on(async { - let mut srv = init_service( - App::new() - .service( - web::resource("/test") - .route(web::get().to(|| HttpResponse::Ok())) - .route(web::put().to(|| { - async { - Err::(error::ErrorBadRequest("err")) - } - })) - .route(web::post().to(|| { - async { - delay_for(Duration::from_millis(100)).await; - HttpResponse::Created() - } - })) - .route(web::delete().to(|| { - async { - delay_for(Duration::from_millis(100)).await; - Err::(error::ErrorBadRequest("err")) - } - })), - ) - .service(web::resource("/json").route(web::get().to(|| { - async { - delay_for(Duration::from_millis(25)).await; - web::Json(MyObject { - name: "test".to_string(), - }) - } - }))), - ) - .await; + #[actix_rt::test] + async fn test_route() { + let mut srv = init_service( + App::new() + .service( + web::resource("/test") + .route(web::get().to(|| HttpResponse::Ok())) + .route(web::put().to(|| { + async { + Err::(error::ErrorBadRequest("err")) + } + })) + .route(web::post().to(|| { + async { + delay_for(Duration::from_millis(100)).await; + HttpResponse::Created() + } + })) + .route(web::delete().to(|| { + async { + delay_for(Duration::from_millis(100)).await; + Err::(error::ErrorBadRequest("err")) + } + })), + ) + .service(web::resource("/json").route(web::get().to(|| { + async { + delay_for(Duration::from_millis(25)).await; + web::Json(MyObject { + name: "test".to_string(), + }) + } + }))), + ) + .await; - let req = TestRequest::with_uri("/test") - .method(Method::GET) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::with_uri("/test") + .method(Method::GET) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); - let req = TestRequest::with_uri("/test") - .method(Method::POST) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::CREATED); + let req = TestRequest::with_uri("/test") + .method(Method::POST) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::CREATED); - let req = TestRequest::with_uri("/test") - .method(Method::PUT) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + let req = TestRequest::with_uri("/test") + .method(Method::PUT) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - let req = TestRequest::with_uri("/test") - .method(Method::DELETE) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + let req = TestRequest::with_uri("/test") + .method(Method::DELETE) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - let req = TestRequest::with_uri("/test") - .method(Method::HEAD) - .to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + let req = TestRequest::with_uri("/test") + .method(Method::HEAD) + .to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - let req = TestRequest::with_uri("/json").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::with_uri("/json").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); - let body = read_body(resp).await; - assert_eq!(body, Bytes::from_static(b"{\"name\":\"test\"}")); - }) + let body = read_body(resp).await; + assert_eq!(body, Bytes::from_static(b"{\"name\":\"test\"}")); } } diff --git a/src/scope.rs b/src/scope.rs index 9bec0a1ff..db6f5da57 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -6,7 +6,7 @@ use std::task::{Context, Poll}; use actix_http::{Extensions, Response}; use actix_router::{ResourceDef, ResourceInfo, Router}; -use actix_service::boxed::{self, BoxedNewService, BoxedService}; +use actix_service::boxed::{self, BoxService, BoxServiceFactory}; use actix_service::{ apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform, }; @@ -25,8 +25,8 @@ use crate::service::{ }; type Guards = Vec>; -type HttpService = BoxedService; -type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>; +type HttpService = BoxService; +type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; type BoxedResponse = LocalBoxFuture<'static, Result>; /// Resources scope. @@ -666,443 +666,389 @@ mod tests { use actix_service::Service; use bytes::Bytes; use futures::future::ok; - use futures::Future; use crate::dev::{Body, ResponseBody}; use crate::http::{header, HeaderValue, Method, StatusCode}; use crate::middleware::DefaultHeaders; - use crate::service::{ServiceRequest, ServiceResponse}; - use crate::test::{block_on, call_service, init_service, read_body, TestRequest}; - use crate::{guard, web, App, Error, HttpRequest, HttpResponse}; + use crate::service::ServiceRequest; + use crate::test::{call_service, init_service, read_body, TestRequest}; + use crate::{guard, web, App, HttpRequest, HttpResponse}; - #[test] - fn test_scope() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app") - .service(web::resource("/path1").to(|| HttpResponse::Ok())), - ), - ) - .await; + #[actix_rt::test] + async fn test_scope() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .service(web::resource("/path1").to(|| HttpResponse::Ok())), + ), + ) + .await; - let req = TestRequest::with_uri("/app/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) + let req = TestRequest::with_uri("/app/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn test_scope_root() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app") + #[actix_rt::test] + async fn test_scope_root() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .service(web::resource("").to(|| HttpResponse::Ok())) + .service(web::resource("/").to(|| HttpResponse::Created())), + ), + ) + .await; + + let req = TestRequest::with_uri("/app").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/app/").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + } + + #[actix_rt::test] + async fn test_scope_root2() { + let mut srv = init_service(App::new().service( + web::scope("/app/").service(web::resource("").to(|| HttpResponse::Ok())), + )) + .await; + + let req = TestRequest::with_uri("/app").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + + let req = TestRequest::with_uri("/app/").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + } + + #[actix_rt::test] + async fn test_scope_root3() { + let mut srv = init_service(App::new().service( + web::scope("/app/").service(web::resource("/").to(|| HttpResponse::Ok())), + )) + .await; + + let req = TestRequest::with_uri("/app").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + + let req = TestRequest::with_uri("/app/").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + } + + #[actix_rt::test] + async fn test_scope_route() { + let mut srv = init_service( + App::new().service( + web::scope("app") + .route("/path1", web::get().to(|| HttpResponse::Ok())) + .route("/path1", web::delete().to(|| HttpResponse::Ok())), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/app/path1") + .method(Method::DELETE) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/app/path1") + .method(Method::POST) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + } + + #[actix_rt::test] + async fn test_scope_route_without_leading_slash() { + let mut srv = init_service( + App::new().service( + web::scope("app").service( + web::resource("path1") + .route(web::get().to(|| HttpResponse::Ok())) + .route(web::delete().to(|| HttpResponse::Ok())), + ), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/app/path1") + .method(Method::DELETE) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let req = TestRequest::with_uri("/app/path1") + .method(Method::POST) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + } + + #[actix_rt::test] + async fn test_scope_guard() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .guard(guard::Get()) + .service(web::resource("/path1").to(|| HttpResponse::Ok())), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/path1") + .method(Method::POST) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + + let req = TestRequest::with_uri("/app/path1") + .method(Method::GET) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + } + + #[actix_rt::test] + 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"])) + } + }), + ))) + .await; + + let req = TestRequest::with_uri("/ab-project1/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + match resp.response().body() { + ResponseBody::Body(Body::Bytes(ref b)) => { + let bytes: Bytes = b.clone().into(); + assert_eq!(bytes, Bytes::from_static(b"project: project1")); + } + _ => panic!(), + } + + let req = TestRequest::with_uri("/aa-project1/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + } + + #[actix_rt::test] + async fn test_nested_scope() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .service(web::scope("/t1").service( + web::resource("/path1").to(|| HttpResponse::Created()), + )), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/t1/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + } + + #[actix_rt::test] + async fn test_nested_scope_no_slash() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .service(web::scope("t1").service( + web::resource("/path1").to(|| HttpResponse::Created()), + )), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/t1/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + } + + #[actix_rt::test] + async fn test_nested_scope_root() { + let mut srv = init_service( + App::new().service( + web::scope("/app").service( + web::scope("/t1") .service(web::resource("").to(|| HttpResponse::Ok())) .service(web::resource("/").to(|| HttpResponse::Created())), ), - ) - .await; + ), + ) + .await; - let req = TestRequest::with_uri("/app").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::with_uri("/app/t1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); - let req = TestRequest::with_uri("/app/").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - }) + let req = TestRequest::with_uri("/app/t1/").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); } - #[test] - fn test_scope_root2() { - block_on(async { - let mut srv = init_service(App::new().service( - web::scope("/app/").service(web::resource("").to(|| HttpResponse::Ok())), - )) - .await; - - let req = TestRequest::with_uri("/app").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - let req = TestRequest::with_uri("/app/").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) - } - - #[test] - fn test_scope_root3() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app/") - .service(web::resource("/").to(|| HttpResponse::Ok())), - ), - ) - .await; - - let req = TestRequest::with_uri("/app").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - let req = TestRequest::with_uri("/app/").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) - } - - #[test] - fn test_scope_route() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("app") - .route("/path1", web::get().to(|| HttpResponse::Ok())) - .route("/path1", web::delete().to(|| HttpResponse::Ok())), - ), - ) - .await; - - let req = TestRequest::with_uri("/app/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/app/path1") - .method(Method::DELETE) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/app/path1") - .method(Method::POST) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) - } - - #[test] - fn test_scope_route_without_leading_slash() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("app").service( - web::resource("path1") - .route(web::get().to(|| HttpResponse::Ok())) - .route(web::delete().to(|| HttpResponse::Ok())), - ), - ), - ) - .await; - - let req = TestRequest::with_uri("/app/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/app/path1") - .method(Method::DELETE) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/app/path1") - .method(Method::POST) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - }) - } - - #[test] - fn test_scope_guard() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app") + #[actix_rt::test] + async fn test_nested_scope_filter() { + let mut srv = init_service( + App::new().service( + web::scope("/app").service( + web::scope("/t1") .guard(guard::Get()) .service(web::resource("/path1").to(|| HttpResponse::Ok())), ), - ) - .await; + ), + ) + .await; - let req = TestRequest::with_uri("/app/path1") - .method(Method::POST) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); + let req = TestRequest::with_uri("/app/t1/path1") + .method(Method::POST) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); - let req = TestRequest::with_uri("/app/path1") - .method(Method::GET) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) + let req = TestRequest::with_uri("/app/t1/path1") + .method(Method::GET) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); } - #[test] - fn test_scope_variable_segment() { - block_on(async { - 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"])) - } - }), - ))) - .await; + #[actix_rt::test] + 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"])) + } + }, + )), + ))) + .await; - let req = TestRequest::with_uri("/ab-project1/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); + let req = TestRequest::with_uri("/app/project_1/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); - match resp.response().body() { - ResponseBody::Body(Body::Bytes(ref b)) => { - let bytes: Bytes = b.clone().into(); - assert_eq!(bytes, Bytes::from_static(b"project: project1")); - } - _ => panic!(), + match resp.response().body() { + ResponseBody::Body(Body::Bytes(ref b)) => { + let bytes: Bytes = b.clone().into(); + assert_eq!(bytes, Bytes::from_static(b"project: project_1")); } - - let req = TestRequest::with_uri("/aa-project1/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) - } - - #[test] - fn test_nested_scope() { - block_on(async { - let mut srv = - init_service(App::new().service( - web::scope("/app").service(web::scope("/t1").service( - web::resource("/path1").to(|| HttpResponse::Created()), - )), - )) - .await; - - let req = TestRequest::with_uri("/app/t1/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - }) - } - - #[test] - fn test_nested_scope_no_slash() { - block_on(async { - let mut srv = - init_service(App::new().service( - web::scope("/app").service(web::scope("t1").service( - web::resource("/path1").to(|| HttpResponse::Created()), - )), - )) - .await; - - let req = TestRequest::with_uri("/app/t1/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - }) - } - - #[test] - fn test_nested_scope_root() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app").service( - web::scope("/t1") - .service(web::resource("").to(|| HttpResponse::Ok())) - .service(web::resource("/").to(|| HttpResponse::Created())), - ), - ), - ) - .await; - - let req = TestRequest::with_uri("/app/t1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - - let req = TestRequest::with_uri("/app/t1/").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - }) - } - - #[test] - fn test_nested_scope_filter() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app").service( - web::scope("/t1") - .guard(guard::Get()) - .service(web::resource("/path1").to(|| HttpResponse::Ok())), - ), - ), - ) - .await; - - let req = TestRequest::with_uri("/app/t1/path1") - .method(Method::POST) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - - let req = TestRequest::with_uri("/app/t1/path1") - .method(Method::GET) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) - } - - #[test] - fn test_nested_scope_with_variable_segment() { - block_on(async { - 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"] - )) - } - }, - )), - ))) - .await; - - let req = TestRequest::with_uri("/app/project_1/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - - match resp.response().body() { - ResponseBody::Body(Body::Bytes(ref b)) => { - let bytes: Bytes = b.clone().into(); - assert_eq!(bytes, Bytes::from_static(b"project: project_1")); - } - _ => panic!(), - } - }) - } - - #[test] - fn test_nested2_scope_with_variable_segment() { - block_on(async { - 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"], - )) - } - }), - )), - ))) - .await; - - let req = TestRequest::with_uri("/app/test/1/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::CREATED); - - match resp.response().body() { - ResponseBody::Body(Body::Bytes(ref b)) => { - let bytes: Bytes = b.clone().into(); - assert_eq!(bytes, Bytes::from_static(b"project: test - 1")); - } - _ => panic!(), - } - - let req = TestRequest::with_uri("/app/test/1/path2").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) - } - - #[test] - fn test_default_resource() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("/app") - .service(web::resource("/path1").to(|| HttpResponse::Ok())) - .default_service(|r: ServiceRequest| { - ok(r.into_response(HttpResponse::BadRequest())) - }), - ), - ) - .await; - - let req = TestRequest::with_uri("/app/path2").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - - let req = TestRequest::with_uri("/path2").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::NOT_FOUND); - }) - } - - #[test] - fn test_default_resource_propagation() { - block_on(async { - let mut srv = init_service( - App::new() - .service(web::scope("/app1").default_service( - web::resource("").to(|| HttpResponse::BadRequest()), - )) - .service(web::scope("/app2")) - .default_service(|r: ServiceRequest| { - ok(r.into_response(HttpResponse::MethodNotAllowed())) - }), - ) - .await; - - let req = TestRequest::with_uri("/non-exist").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - - let req = TestRequest::with_uri("/app1/non-exist").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - - let req = TestRequest::with_uri("/app2/non-exist").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); - }) - } - - fn md( - req: ServiceRequest, - srv: &mut S, - ) -> impl Future, Error>> - where - S: Service< - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - >, - { - let fut = srv.call(req); - async move { - let mut res = fut.await?; - res.headers_mut() - .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001")); - Ok(res) + _ => panic!(), } } - #[test] - fn test_middleware() { - block_on(async { - let mut srv = init_service( + #[actix_rt::test] + 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"], + )) + } + }), + )), + ))) + .await; + + let req = TestRequest::with_uri("/app/test/1/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + + match resp.response().body() { + ResponseBody::Body(Body::Bytes(ref b)) => { + let bytes: Bytes = b.clone().into(); + assert_eq!(bytes, Bytes::from_static(b"project: test - 1")); + } + _ => panic!(), + } + + let req = TestRequest::with_uri("/app/test/1/path2").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + } + + #[actix_rt::test] + async fn test_default_resource() { + let mut srv = init_service( + App::new().service( + web::scope("/app") + .service(web::resource("/path1").to(|| HttpResponse::Ok())) + .default_service(|r: ServiceRequest| { + ok(r.into_response(HttpResponse::BadRequest())) + }), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/path2").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/path2").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); + } + + #[actix_rt::test] + async fn test_default_resource_propagation() { + let mut srv = init_service( + App::new() + .service(web::scope("/app1").default_service( + web::resource("").to(|| HttpResponse::BadRequest()), + )) + .service(web::scope("/app2")) + .default_service(|r: ServiceRequest| { + ok(r.into_response(HttpResponse::MethodNotAllowed())) + }), + ) + .await; + + let req = TestRequest::with_uri("/non-exist").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + + let req = TestRequest::with_uri("/app1/non-exist").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/app2/non-exist").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + } + + #[actix_rt::test] + async fn test_middleware() { + let mut srv = + init_service( App::new().service( web::scope("app") .wrap(DefaultHeaders::new().header( @@ -1117,186 +1063,169 @@ mod tests { ) .await; - let req = TestRequest::with_uri("/app/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) + let req = TestRequest::with_uri("/app/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); } - #[test] - fn test_middleware_fn() { - block_on(async { - let mut srv = init_service( - App::new().service( - web::scope("app") - .wrap_fn(|req, srv| { - let fut = srv.call(req); - async move { - let mut res = fut.await?; - res.headers_mut().insert( - header::CONTENT_TYPE, - HeaderValue::from_static("0001"), - ); - Ok(res) - } - }) - .route("/test", web::get().to(|| HttpResponse::Ok())), - ), - ) - .await; - - let req = TestRequest::with_uri("/app/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - HeaderValue::from_static("0001") - ); - }) - } - - #[test] - fn test_override_data() { - block_on(async { - let mut srv = init_service(App::new().data(1usize).service( - web::scope("app").data(10usize).route( - "/t", - web::get().to(|data: web::Data| { - assert_eq!(*data, 10); - let _ = data.clone(); - 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); - }) - } - - #[test] - fn test_override_register_data() { - block_on(async { - let mut srv = init_service( - App::new().register_data(web::Data::new(1usize)).service( - web::scope("app") - .register_data(web::Data::new(10usize)) - .route( - "/t", - web::get().to(|data: web::Data| { - assert_eq!(*data, 10); - let _ = data.clone(); - 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); - }) - } - - #[test] - fn test_scope_config() { - block_on(async { - let mut srv = - init_service(App::new().service(web::scope("/app").configure(|s| { - s.route("/path1", web::get().to(|| HttpResponse::Ok())); - }))) - .await; - - let req = TestRequest::with_uri("/app/path1").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) - } - - #[test] - fn test_scope_config_2() { - block_on(async { - let mut srv = - init_service(App::new().service(web::scope("/app").configure(|s| { - s.service(web::scope("/v1").configure(|s| { - s.route("/", web::get().to(|| HttpResponse::Ok())); - })); - }))) - .await; - - let req = TestRequest::with_uri("/app/v1/").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - }) - } - - #[test] - fn test_url_for_external() { - block_on(async { - let mut srv = - init_service(App::new().service(web::scope("/app").configure(|s| { - s.service(web::scope("/v1").configure(|s| { - s.external_resource( - "youtube", - "https://youtube.com/watch/{video_id}", - ); - s.route( - "/", - web::get().to(|req: HttpRequest| { - async move { - HttpResponse::Ok().body(format!( - "{}", - req.url_for("youtube", &["xxxxxx"]) - .unwrap() - .as_str() - )) - } - }), - ); - })); - }))) - .await; - - let req = TestRequest::with_uri("/app/v1/").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - let body = read_body(resp).await; - assert_eq!(body, &b"https://youtube.com/watch/xxxxxx"[..]); - }) - } - - #[test] - fn test_url_for_nested() { - block_on(async { - 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| { + #[actix_rt::test] + async fn test_middleware_fn() { + let mut srv = init_service( + App::new().service( + web::scope("app") + .wrap_fn(|req, srv| { + let fut = srv.call(req); async move { - HttpResponse::Ok().body(format!( - "{}", - req.url_for("c", &["12345"]).unwrap() - )) + let mut res = fut.await?; + res.headers_mut().insert( + header::CONTENT_TYPE, + HeaderValue::from_static("0001"), + ); + Ok(res) } - }), - )), - ))) + }) + .route("/test", web::get().to(|| HttpResponse::Ok())), + ), + ) + .await; + + let req = TestRequest::with_uri("/app/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + HeaderValue::from_static("0001") + ); + } + + #[actix_rt::test] + async fn test_override_data() { + let mut srv = init_service(App::new().data(1usize).service( + web::scope("app").data(10usize).route( + "/t", + web::get().to(|data: web::Data| { + assert_eq!(*data, 10); + let _ = data.clone(); + 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_register_data() { + let mut srv = init_service( + App::new().register_data(web::Data::new(1usize)).service( + web::scope("app") + .register_data(web::Data::new(10usize)) + .route( + "/t", + web::get().to(|data: web::Data| { + assert_eq!(*data, 10); + let _ = data.clone(); + 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_scope_config() { + let mut srv = + init_service(App::new().service(web::scope("/app").configure(|s| { + s.route("/path1", web::get().to(|| HttpResponse::Ok())); + }))) .await; - let req = TestRequest::with_uri("/a/b/c/test").to_request(); - let resp = call_service(&mut srv, req).await; - assert_eq!(resp.status(), StatusCode::OK); - let body = read_body(resp).await; - assert_eq!( - body, - Bytes::from_static(b"http://localhost:8080/a/b/c/12345") - ); - }) + let req = TestRequest::with_uri("/app/path1").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + } + + #[actix_rt::test] + async fn test_scope_config_2() { + let mut srv = + init_service(App::new().service(web::scope("/app").configure(|s| { + s.service(web::scope("/v1").configure(|s| { + s.route("/", web::get().to(|| HttpResponse::Ok())); + })); + }))) + .await; + + let req = TestRequest::with_uri("/app/v1/").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + } + + #[actix_rt::test] + async fn test_url_for_external() { + let mut srv = + init_service(App::new().service(web::scope("/app").configure(|s| { + s.service(web::scope("/v1").configure(|s| { + s.external_resource( + "youtube", + "https://youtube.com/watch/{video_id}", + ); + s.route( + "/", + web::get().to(|req: HttpRequest| { + async move { + HttpResponse::Ok().body(format!( + "{}", + req.url_for("youtube", &["xxxxxx"]) + .unwrap() + .as_str() + )) + } + }), + ); + })); + }))) + .await; + + let req = TestRequest::with_uri("/app/v1/").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + let body = read_body(resp).await; + assert_eq!(body, &b"https://youtube.com/watch/xxxxxx"[..]); + } + + #[actix_rt::test] + 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())) + } + }), + )), + ))) + .await; + + let req = TestRequest::with_uri("/a/b/c/test").to_request(); + let resp = call_service(&mut srv, req).await; + assert_eq!(resp.status(), StatusCode::OK); + let body = read_body(resp).await; + assert_eq!( + body, + Bytes::from_static(b"http://localhost:8080/a/b/c/12345") + ); } } diff --git a/src/service.rs b/src/service.rs index 39540b067..b392e6e8b 100644 --- a/src/service.rs +++ b/src/service.rs @@ -10,7 +10,6 @@ use actix_http::{ }; use actix_router::{Path, Resource, ResourceDef, Url}; use actix_service::{IntoServiceFactory, ServiceFactory}; -use futures::future::{ok, Ready}; use crate::config::{AppConfig, AppService}; use crate::data::Data; @@ -529,9 +528,10 @@ where #[cfg(test)] mod tests { use super::*; - use crate::test::{block_on, init_service, TestRequest}; + use crate::test::{init_service, TestRequest}; use crate::{guard, http, web, App, HttpResponse}; use actix_service::Service; + use futures::future::ok; #[test] fn test_service_request() { @@ -554,35 +554,29 @@ mod tests { assert!(ServiceRequest::from_request(r).is_err()); } - #[test] - fn test_service() { - block_on(async { - let mut srv = init_service( - App::new().service(web::service("/test").name("test").finish( - |req: ServiceRequest| { - ok(req.into_response(HttpResponse::Ok().finish())) - }, - )), - ) - .await; - let req = TestRequest::with_uri("/test").to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), http::StatusCode::OK); + #[actix_rt::test] + async fn test_service() { + let mut srv = init_service( + App::new().service(web::service("/test").name("test").finish( + |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())), + )), + ) + .await; + let req = TestRequest::with_uri("/test").to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), http::StatusCode::OK); - let mut srv = init_service(App::new().service( - web::service("/test").guard(guard::Get()).finish( - |req: ServiceRequest| { - ok(req.into_response(HttpResponse::Ok().finish())) - }, - ), - )) - .await; - let req = TestRequest::with_uri("/test") - .method(http::Method::PUT) - .to_request(); - let resp = srv.call(req).await.unwrap(); - assert_eq!(resp.status(), http::StatusCode::NOT_FOUND); - }) + let mut srv = init_service( + App::new().service(web::service("/test").guard(guard::Get()).finish( + |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())), + )), + ) + .await; + let req = TestRequest::with_uri("/test") + .method(http::Method::PUT) + .to_request(); + let resp = srv.call(req).await.unwrap(); + assert_eq!(resp.status(), http::StatusCode::NOT_FOUND); } #[test] diff --git a/src/test.rs b/src/test.rs index 0776b0f15..e19393156 100644 --- a/src/test.rs +++ b/src/test.rs @@ -9,14 +9,13 @@ use actix_router::{Path, ResourceDef, Url}; use actix_server_config::ServerConfig; use actix_service::{IntoService, IntoServiceFactory, Service, ServiceFactory}; use bytes::{Bytes, BytesMut}; -use futures::future::{ok, Future, FutureExt}; +use futures::future::ok; use futures::stream::{Stream, StreamExt}; use serde::de::DeserializeOwned; use serde::Serialize; use serde_json; pub use actix_http::test::TestBuffer; -pub use actix_testing::{block_fn, block_on, run_on}; use crate::config::{AppConfig, AppConfigInner}; use crate::data::Data; @@ -51,8 +50,8 @@ pub fn default_service( /// use actix_service::Service; /// use actix_web::{test, web, App, HttpResponse, http::StatusCode}; /// -/// #[test] -/// fn test_init_service() { +/// #[actix_rt::test] +/// async fn test_init_service() { /// let mut app = test::init_service( /// App::new() /// .service(web::resource("/test").to(|| async { HttpResponse::Ok() })) @@ -62,7 +61,7 @@ pub fn default_service( /// let req = test::TestRequest::with_uri("/test").to_request(); /// /// // Execute application -/// let resp = test::block_on(app.call(req)).unwrap(); +/// let resp = app.call(req).await.unwrap(); /// assert_eq!(resp.status(), StatusCode::OK); /// } /// ``` @@ -116,14 +115,13 @@ where } /// Helper function that returns a response body of a TestRequest -/// This function blocks the current thread until futures complete. /// /// ```rust /// use actix_web::{test, web, App, HttpResponse, http::header}; /// use bytes::Bytes; /// -/// #[test] -/// fn test_index() { +/// #[actix_rt::test] +/// async fn test_index() { /// let mut app = test::init_service( /// App::new().service( /// web::resource("/index.html") @@ -149,7 +147,7 @@ where let mut resp = app .call(req) .await - .unwrap_or_else(|_| panic!("read_response failed at block_on unwrap")); + .unwrap_or_else(|_| panic!("read_response failed at application call")); let mut body = resp.take_body(); let mut bytes = BytesMut::new(); @@ -160,14 +158,13 @@ where } /// Helper function that returns a response body of a ServiceResponse. -/// This function blocks the current thread until futures complete. /// /// ```rust /// use actix_web::{test, web, App, HttpResponse, http::header}; /// use bytes::Bytes; /// -/// #[test] -/// fn test_index() { +/// #[actix_rt::test] +/// async fn test_index() { /// let mut app = test::init_service( /// App::new().service( /// web::resource("/index.html") @@ -210,7 +207,6 @@ where } /// Helper function that returns a deserialized response body of a TestRequest -/// This function blocks the current thread until futures complete. /// /// ```rust /// use actix_web::{App, test, web, HttpResponse, http::header}; @@ -222,8 +218,8 @@ where /// name: String /// } /// -/// #[test] -/// fn test_add_person() { +/// #[actix_rt::test] +/// async fn test_add_person() { /// let mut app = test::init_service( /// App::new().service( /// web::resource("/people") @@ -512,90 +508,81 @@ mod tests { use super::*; use crate::{http::header, web, App, HttpResponse}; - #[test] - fn test_basics() { - block_on(async { - let req = TestRequest::with_hdr(header::ContentType::json()) - .version(Version::HTTP_2) - .set(header::Date(SystemTime::now().into())) - .param("test", "123") - .data(10u32) - .to_http_request(); - assert!(req.headers().contains_key(header::CONTENT_TYPE)); - assert!(req.headers().contains_key(header::DATE)); - assert_eq!(&req.match_info()["test"], "123"); - assert_eq!(req.version(), Version::HTTP_2); - let data = req.get_app_data::().unwrap(); - assert!(req.get_app_data::().is_none()); - assert_eq!(*data, 10); - assert_eq!(*data.get_ref(), 10); + #[actix_rt::test] + async fn test_basics() { + let req = TestRequest::with_hdr(header::ContentType::json()) + .version(Version::HTTP_2) + .set(header::Date(SystemTime::now().into())) + .param("test", "123") + .data(10u32) + .to_http_request(); + assert!(req.headers().contains_key(header::CONTENT_TYPE)); + assert!(req.headers().contains_key(header::DATE)); + assert_eq!(&req.match_info()["test"], "123"); + assert_eq!(req.version(), Version::HTTP_2); + let data = req.get_app_data::().unwrap(); + assert!(req.get_app_data::().is_none()); + assert_eq!(*data, 10); + assert_eq!(*data.get_ref(), 10); - assert!(req.app_data::().is_none()); - let data = req.app_data::().unwrap(); - assert_eq!(*data, 10); - }) + assert!(req.app_data::().is_none()); + let data = req.app_data::().unwrap(); + assert_eq!(*data, 10); } - #[test] - fn test_request_methods() { - block_on(async { - let mut app = init_service( - App::new().service( - web::resource("/index.html") - .route( - web::put().to(|| async { HttpResponse::Ok().body("put!") }), - ) - .route( - web::patch() - .to(|| async { HttpResponse::Ok().body("patch!") }), - ) - .route( - web::delete() - .to(|| async { HttpResponse::Ok().body("delete!") }), - ), - ), - ) + #[actix_rt::test] + async fn test_request_methods() { + let mut app = init_service( + App::new().service( + web::resource("/index.html") + .route(web::put().to(|| async { HttpResponse::Ok().body("put!") })) + .route( + web::patch().to(|| async { HttpResponse::Ok().body("patch!") }), + ) + .route( + web::delete() + .to(|| async { HttpResponse::Ok().body("delete!") }), + ), + ), + ) + .await; + + let put_req = TestRequest::put() + .uri("/index.html") + .header(header::CONTENT_TYPE, "application/json") + .to_request(); + + let result = read_response(&mut app, put_req).await; + assert_eq!(result, Bytes::from_static(b"put!")); + + let patch_req = TestRequest::patch() + .uri("/index.html") + .header(header::CONTENT_TYPE, "application/json") + .to_request(); + + let result = read_response(&mut app, patch_req).await; + assert_eq!(result, Bytes::from_static(b"patch!")); + + let delete_req = TestRequest::delete().uri("/index.html").to_request(); + let result = read_response(&mut app, delete_req).await; + assert_eq!(result, Bytes::from_static(b"delete!")); + } + + #[actix_rt::test] + async fn test_response() { + let mut app = + init_service(App::new().service(web::resource("/index.html").route( + web::post().to(|| async { HttpResponse::Ok().body("welcome!") }), + ))) .await; - let put_req = TestRequest::put() - .uri("/index.html") - .header(header::CONTENT_TYPE, "application/json") - .to_request(); + let req = TestRequest::post() + .uri("/index.html") + .header(header::CONTENT_TYPE, "application/json") + .to_request(); - let result = read_response(&mut app, put_req).await; - assert_eq!(result, Bytes::from_static(b"put!")); - - let patch_req = TestRequest::patch() - .uri("/index.html") - .header(header::CONTENT_TYPE, "application/json") - .to_request(); - - let result = read_response(&mut app, patch_req).await; - assert_eq!(result, Bytes::from_static(b"patch!")); - - let delete_req = TestRequest::delete().uri("/index.html").to_request(); - let result = read_response(&mut app, delete_req).await; - assert_eq!(result, Bytes::from_static(b"delete!")); - }) - } - - #[test] - fn test_response() { - block_on(async { - let mut app = - init_service(App::new().service(web::resource("/index.html").route( - web::post().to(|| async { HttpResponse::Ok().body("welcome!") }), - ))) - .await; - - let req = TestRequest::post() - .uri("/index.html") - .header(header::CONTENT_TYPE, "application/json") - .to_request(); - - let result = read_response(&mut app, req).await; - assert_eq!(result, Bytes::from_static(b"welcome!")); - }) + let result = read_response(&mut app, req).await; + assert_eq!(result, Bytes::from_static(b"welcome!")); } #[derive(Serialize, Deserialize)] @@ -604,114 +591,103 @@ mod tests { name: String, } - #[test] - fn test_response_json() { - block_on(async { - let mut app = - init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| { - async { HttpResponse::Ok().json(person.into_inner()) } - }), - ))) - .await; + #[actix_rt::test] + async fn test_response_json() { + let mut app = init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| { + async { HttpResponse::Ok().json(person.into_inner()) } + }), + ))) + .await; - let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes(); + let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes(); - let req = TestRequest::post() - .uri("/people") - .header(header::CONTENT_TYPE, "application/json") - .set_payload(payload) - .to_request(); + let req = TestRequest::post() + .uri("/people") + .header(header::CONTENT_TYPE, "application/json") + .set_payload(payload) + .to_request(); - let result: Person = read_response_json(&mut app, req).await; - assert_eq!(&result.id, "12345"); - }) + let result: Person = read_response_json(&mut app, req).await; + assert_eq!(&result.id, "12345"); } - #[test] - fn test_request_response_form() { - block_on(async { - let mut app = - init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Form| { - async { HttpResponse::Ok().json(person.into_inner()) } - }), - ))) - .await; + #[actix_rt::test] + async fn test_request_response_form() { + let mut app = init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Form| { + async { HttpResponse::Ok().json(person.into_inner()) } + }), + ))) + .await; - let payload = Person { - id: "12345".to_string(), - name: "User name".to_string(), - }; + let payload = Person { + id: "12345".to_string(), + name: "User name".to_string(), + }; - let req = TestRequest::post() - .uri("/people") - .set_form(&payload) - .to_request(); + let req = TestRequest::post() + .uri("/people") + .set_form(&payload) + .to_request(); - assert_eq!(req.content_type(), "application/x-www-form-urlencoded"); + assert_eq!(req.content_type(), "application/x-www-form-urlencoded"); - let result: Person = read_response_json(&mut app, req).await; - assert_eq!(&result.id, "12345"); - assert_eq!(&result.name, "User name"); - }) + let result: Person = read_response_json(&mut app, req).await; + assert_eq!(&result.id, "12345"); + assert_eq!(&result.name, "User name"); } - #[test] - fn test_request_response_json() { - block_on(async { - let mut app = - init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| { - async { HttpResponse::Ok().json(person.into_inner()) } - }), - ))) - .await; + #[actix_rt::test] + async fn test_request_response_json() { + let mut app = init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| { + async { HttpResponse::Ok().json(person.into_inner()) } + }), + ))) + .await; - let payload = Person { - id: "12345".to_string(), - name: "User name".to_string(), - }; + let payload = Person { + id: "12345".to_string(), + name: "User name".to_string(), + }; - let req = TestRequest::post() - .uri("/people") - .set_json(&payload) - .to_request(); + let req = TestRequest::post() + .uri("/people") + .set_json(&payload) + .to_request(); - assert_eq!(req.content_type(), "application/json"); + assert_eq!(req.content_type(), "application/json"); - let result: Person = read_response_json(&mut app, req).await; - assert_eq!(&result.id, "12345"); - assert_eq!(&result.name, "User name"); - }) + let result: Person = read_response_json(&mut app, req).await; + assert_eq!(&result.id, "12345"); + assert_eq!(&result.name, "User name"); } - #[test] - fn test_async_with_block() { - block_on(async { - async fn async_with_block() -> Result { - let res = web::block(move || Some(4usize).ok_or("wrong")).await; + #[actix_rt::test] + async fn test_async_with_block() { + async fn async_with_block() -> Result { + let res = web::block(move || Some(4usize).ok_or("wrong")).await; - match res? { - Ok(value) => Ok(HttpResponse::Ok() - .content_type("text/plain") - .body(format!("Async with block value: {}", value))), - Err(_) => panic!("Unexpected"), - } + match res? { + Ok(value) => Ok(HttpResponse::Ok() + .content_type("text/plain") + .body(format!("Async with block value: {}", value))), + Err(_) => panic!("Unexpected"), } + } - let mut app = init_service( - App::new().service(web::resource("/index.html").to(async_with_block)), - ) - .await; + let mut app = init_service( + App::new().service(web::resource("/index.html").to(async_with_block)), + ) + .await; - let req = TestRequest::post().uri("/index.html").to_request(); - let res = app.call(req).await.unwrap(); - assert!(res.status().is_success()); - }) + let req = TestRequest::post().uri("/index.html").to_request(); + let res = app.call(req).await.unwrap(); + assert!(res.status().is_success()); } - // #[test] + // #[actix_rt::test] // fn test_actor() { // use actix::Actor; diff --git a/src/types/form.rs b/src/types/form.rs index c20dc7a05..e1bd52375 100644 --- a/src/types/form.rs +++ b/src/types/form.rs @@ -10,7 +10,7 @@ use actix_http::{Error, HttpMessage, Payload, Response}; use bytes::BytesMut; use encoding_rs::{Encoding, UTF_8}; use futures::future::{err, ok, FutureExt, LocalBoxFuture, Ready}; -use futures::{Stream, StreamExt}; +use futures::StreamExt; use serde::de::DeserializeOwned; use serde::Serialize; @@ -370,7 +370,7 @@ mod tests { use super::*; use crate::http::header::{HeaderValue, CONTENT_TYPE}; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; #[derive(Deserialize, Serialize, Debug, PartialEq)] struct Info { @@ -378,26 +378,22 @@ mod tests { counter: i64, } - #[test] - fn test_form() { - block_on(async { - let (req, mut pl) = TestRequest::with_header( - CONTENT_TYPE, - "application/x-www-form-urlencoded", - ) - .header(CONTENT_LENGTH, "11") - .set_payload(Bytes::from_static(b"hello=world&counter=123")) - .to_http_parts(); + #[actix_rt::test] + async fn test_form() { + let (req, mut pl) = + TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded") + .header(CONTENT_LENGTH, "11") + .set_payload(Bytes::from_static(b"hello=world&counter=123")) + .to_http_parts(); - let Form(s) = Form::::from_request(&req, &mut pl).await.unwrap(); - assert_eq!( - s, - Info { - hello: "world".into(), - counter: 123 - } - ); - }) + let Form(s) = Form::::from_request(&req, &mut pl).await.unwrap(); + assert_eq!( + s, + Info { + hello: "world".into(), + counter: 123 + } + ); } fn eq(err: UrlencodedError, other: UrlencodedError) -> bool { @@ -418,95 +414,83 @@ mod tests { } } - #[test] - fn test_urlencoded_error() { - block_on(async { - let (req, mut pl) = TestRequest::with_header( - CONTENT_TYPE, - "application/x-www-form-urlencoded", - ) - .header(CONTENT_LENGTH, "xxxx") - .to_http_parts(); - let info = UrlEncoded::::new(&req, &mut pl).await; - assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength)); - - let (req, mut pl) = TestRequest::with_header( - CONTENT_TYPE, - "application/x-www-form-urlencoded", - ) - .header(CONTENT_LENGTH, "1000000") - .to_http_parts(); - let info = UrlEncoded::::new(&req, &mut pl).await; - assert!(eq( - info.err().unwrap(), - UrlencodedError::Overflow { size: 0, limit: 0 } - )); - - let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain") - .header(CONTENT_LENGTH, "10") + #[actix_rt::test] + async fn test_urlencoded_error() { + let (req, mut pl) = + TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded") + .header(CONTENT_LENGTH, "xxxx") .to_http_parts(); - let info = UrlEncoded::::new(&req, &mut pl).await; - assert!(eq(info.err().unwrap(), UrlencodedError::ContentType)); - }) + let info = UrlEncoded::::new(&req, &mut pl).await; + assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength)); + + let (req, mut pl) = + TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded") + .header(CONTENT_LENGTH, "1000000") + .to_http_parts(); + let info = UrlEncoded::::new(&req, &mut pl).await; + assert!(eq( + info.err().unwrap(), + UrlencodedError::Overflow { size: 0, limit: 0 } + )); + + let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain") + .header(CONTENT_LENGTH, "10") + .to_http_parts(); + let info = UrlEncoded::::new(&req, &mut pl).await; + assert!(eq(info.err().unwrap(), UrlencodedError::ContentType)); } - #[test] - fn test_urlencoded() { - block_on(async { - let (req, mut pl) = TestRequest::with_header( - CONTENT_TYPE, - "application/x-www-form-urlencoded", - ) - .header(CONTENT_LENGTH, "11") - .set_payload(Bytes::from_static(b"hello=world&counter=123")) - .to_http_parts(); + #[actix_rt::test] + async fn test_urlencoded() { + let (req, mut pl) = + TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded") + .header(CONTENT_LENGTH, "11") + .set_payload(Bytes::from_static(b"hello=world&counter=123")) + .to_http_parts(); - let info = UrlEncoded::::new(&req, &mut pl).await.unwrap(); - assert_eq!( - info, - Info { - hello: "world".to_owned(), - counter: 123 - } - ); + let info = UrlEncoded::::new(&req, &mut pl).await.unwrap(); + assert_eq!( + info, + Info { + hello: "world".to_owned(), + counter: 123 + } + ); - let (req, mut pl) = TestRequest::with_header( - CONTENT_TYPE, - "application/x-www-form-urlencoded; charset=utf-8", - ) - .header(CONTENT_LENGTH, "11") - .set_payload(Bytes::from_static(b"hello=world&counter=123")) - .to_http_parts(); + let (req, mut pl) = TestRequest::with_header( + CONTENT_TYPE, + "application/x-www-form-urlencoded; charset=utf-8", + ) + .header(CONTENT_LENGTH, "11") + .set_payload(Bytes::from_static(b"hello=world&counter=123")) + .to_http_parts(); - let info = UrlEncoded::::new(&req, &mut pl).await.unwrap(); - assert_eq!( - info, - Info { - hello: "world".to_owned(), - counter: 123 - } - ); - }) + let info = UrlEncoded::::new(&req, &mut pl).await.unwrap(); + assert_eq!( + info, + Info { + hello: "world".to_owned(), + counter: 123 + } + ); } - #[test] - fn test_responder() { - block_on(async { - let req = TestRequest::default().to_http_request(); + #[actix_rt::test] + async fn test_responder() { + let req = TestRequest::default().to_http_request(); - let form = Form(Info { - hello: "world".to_string(), - counter: 123, - }); - let resp = form.respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - HeaderValue::from_static("application/x-www-form-urlencoded") - ); + let form = Form(Info { + hello: "world".to_string(), + counter: 123, + }); + let resp = form.respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(CONTENT_TYPE).unwrap(), + HeaderValue::from_static("application/x-www-form-urlencoded") + ); - use crate::responder::tests::BodyTest; - assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123"); - }) + use crate::responder::tests::BodyTest; + assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123"); } } diff --git a/src/types/json.rs b/src/types/json.rs index 206a4e425..028092d1a 100644 --- a/src/types/json.rs +++ b/src/types/json.rs @@ -8,7 +8,7 @@ use std::{fmt, ops}; use bytes::BytesMut; use futures::future::{err, ok, FutureExt, LocalBoxFuture, Ready}; -use futures::{Stream, StreamExt}; +use futures::StreamExt; use serde::de::DeserializeOwned; use serde::Serialize; use serde_json; @@ -402,7 +402,7 @@ mod tests { use super::*; use crate::error::InternalError; use crate::http::header; - use crate::test::{block_on, load_stream, TestRequest}; + use crate::test::{load_stream, TestRequest}; use crate::HttpResponse; #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -424,236 +424,222 @@ mod tests { } } - #[test] - fn test_responder() { - block_on(async { - let req = TestRequest::default().to_http_request(); + #[actix_rt::test] + async fn test_responder() { + let req = TestRequest::default().to_http_request(); - let j = Json(MyObject { - name: "test".to_string(), - }); - let resp = j.respond_to(&req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!( - resp.headers().get(header::CONTENT_TYPE).unwrap(), - header::HeaderValue::from_static("application/json") - ); + let j = Json(MyObject { + name: "test".to_string(), + }); + let resp = j.respond_to(&req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get(header::CONTENT_TYPE).unwrap(), + header::HeaderValue::from_static("application/json") + ); - use crate::responder::tests::BodyTest; - assert_eq!(resp.body().bin_ref(), b"{\"name\":\"test\"}"); - }) + use crate::responder::tests::BodyTest; + assert_eq!(resp.body().bin_ref(), b"{\"name\":\"test\"}"); } - #[test] - fn test_custom_error_responder() { - block_on(async { - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .data(JsonConfig::default().limit(10).error_handler(|err, _| { - let msg = MyObject { - name: "invalid request".to_string(), - }; - let resp = HttpResponse::BadRequest() - .body(serde_json::to_string(&msg).unwrap()); - InternalError::from_response(err, resp).into() - })) - .to_http_parts(); - - let s = Json::::from_request(&req, &mut pl).await; - let mut resp = Response::from_error(s.err().unwrap().into()); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); - - let body = load_stream(resp.take_body()).await.unwrap(); - let msg: MyObject = serde_json::from_slice(&body).unwrap(); - assert_eq!(msg.name, "invalid request"); - }) - } - - #[test] - fn test_extract() { - block_on(async { - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .to_http_parts(); - - let s = Json::::from_request(&req, &mut pl).await.unwrap(); - assert_eq!(s.name, "test"); - assert_eq!( - s.into_inner(), - MyObject { - name: "test".to_string() - } - ); - - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .data(JsonConfig::default().limit(10)) - .to_http_parts(); - - let s = Json::::from_request(&req, &mut pl).await; - assert!(format!("{}", s.err().unwrap()) - .contains("Json payload size is bigger than allowed")); - - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .data( - JsonConfig::default() - .limit(10) - .error_handler(|_, _| JsonPayloadError::ContentType.into()), - ) - .to_http_parts(); - let s = Json::::from_request(&req, &mut pl).await; - assert!(format!("{}", s.err().unwrap()).contains("Content type error")); - }) - } - - #[test] - fn test_json_body() { - block_on(async { - let (req, mut pl) = TestRequest::default().to_http_parts(); - let json = JsonBody::::new(&req, &mut pl, None).await; - assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); - - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/text"), - ) - .to_http_parts(); - let json = JsonBody::::new(&req, &mut pl, None).await; - assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); - - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("10000"), - ) - .to_http_parts(); - - let json = JsonBody::::new(&req, &mut pl, None) - .limit(100) - .await; - assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow)); - - let (req, mut pl) = TestRequest::default() - .header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("application/json"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .to_http_parts(); - - let json = JsonBody::::new(&req, &mut pl, None).await; - assert_eq!( - json.ok().unwrap(), - MyObject { - name: "test".to_owned() - } - ); - }) - } - - #[test] - fn test_with_json_and_bad_content_type() { - block_on(async { - let (req, mut pl) = TestRequest::with_header( + #[actix_rt::test] + async fn test_custom_error_responder() { + let (req, mut pl) = TestRequest::default() + .header( header::CONTENT_TYPE, - header::HeaderValue::from_static("text/plain"), + header::HeaderValue::from_static("application/json"), ) .header( header::CONTENT_LENGTH, header::HeaderValue::from_static("16"), ) .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .data(JsonConfig::default().limit(4096)) - .to_http_parts(); - - let s = Json::::from_request(&req, &mut pl).await; - assert!(s.is_err()) - }) - } - - #[test] - fn test_with_json_and_good_custom_content_type() { - block_on(async { - let (req, mut pl) = TestRequest::with_header( - header::CONTENT_TYPE, - header::HeaderValue::from_static("text/plain"), - ) - .header( - header::CONTENT_LENGTH, - header::HeaderValue::from_static("16"), - ) - .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .data(JsonConfig::default().content_type(|mime: mime::Mime| { - mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN + .data(JsonConfig::default().limit(10).error_handler(|err, _| { + let msg = MyObject { + name: "invalid request".to_string(), + }; + let resp = HttpResponse::BadRequest() + .body(serde_json::to_string(&msg).unwrap()); + InternalError::from_response(err, resp).into() })) .to_http_parts(); - let s = Json::::from_request(&req, &mut pl).await; - assert!(s.is_ok()) - }) + let s = Json::::from_request(&req, &mut pl).await; + let mut resp = Response::from_error(s.err().unwrap().into()); + assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + + let body = load_stream(resp.take_body()).await.unwrap(); + let msg: MyObject = serde_json::from_slice(&body).unwrap(); + assert_eq!(msg.name, "invalid request"); } - #[test] - fn test_with_json_and_bad_custom_content_type() { - block_on(async { - let (req, mut pl) = TestRequest::with_header( + #[actix_rt::test] + async fn test_extract() { + let (req, mut pl) = TestRequest::default() + .header( header::CONTENT_TYPE, - header::HeaderValue::from_static("text/html"), + header::HeaderValue::from_static("application/json"), ) .header( header::CONTENT_LENGTH, header::HeaderValue::from_static("16"), ) .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) - .data(JsonConfig::default().content_type(|mime: mime::Mime| { - mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN - })) .to_http_parts(); - let s = Json::::from_request(&req, &mut pl).await; - assert!(s.is_err()) - }) + let s = Json::::from_request(&req, &mut pl).await.unwrap(); + assert_eq!(s.name, "test"); + assert_eq!( + s.into_inner(), + MyObject { + name: "test".to_string() + } + ); + + let (req, mut pl) = TestRequest::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/json"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .data(JsonConfig::default().limit(10)) + .to_http_parts(); + + let s = Json::::from_request(&req, &mut pl).await; + assert!(format!("{}", s.err().unwrap()) + .contains("Json payload size is bigger than allowed")); + + let (req, mut pl) = TestRequest::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/json"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .data( + JsonConfig::default() + .limit(10) + .error_handler(|_, _| JsonPayloadError::ContentType.into()), + ) + .to_http_parts(); + let s = Json::::from_request(&req, &mut pl).await; + assert!(format!("{}", s.err().unwrap()).contains("Content type error")); + } + + #[actix_rt::test] + async fn test_json_body() { + let (req, mut pl) = TestRequest::default().to_http_parts(); + let json = JsonBody::::new(&req, &mut pl, None).await; + assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); + + let (req, mut pl) = TestRequest::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/text"), + ) + .to_http_parts(); + let json = JsonBody::::new(&req, &mut pl, None).await; + assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); + + let (req, mut pl) = TestRequest::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/json"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("10000"), + ) + .to_http_parts(); + + let json = JsonBody::::new(&req, &mut pl, None) + .limit(100) + .await; + assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow)); + + let (req, mut pl) = TestRequest::default() + .header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("application/json"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .to_http_parts(); + + let json = JsonBody::::new(&req, &mut pl, None).await; + assert_eq!( + json.ok().unwrap(), + MyObject { + name: "test".to_owned() + } + ); + } + + #[actix_rt::test] + async fn test_with_json_and_bad_content_type() { + let (req, mut pl) = TestRequest::with_header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("text/plain"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .data(JsonConfig::default().limit(4096)) + .to_http_parts(); + + let s = Json::::from_request(&req, &mut pl).await; + assert!(s.is_err()) + } + + #[actix_rt::test] + async fn test_with_json_and_good_custom_content_type() { + let (req, mut pl) = TestRequest::with_header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("text/plain"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .data(JsonConfig::default().content_type(|mime: mime::Mime| { + mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN + })) + .to_http_parts(); + + let s = Json::::from_request(&req, &mut pl).await; + assert!(s.is_ok()) + } + + #[actix_rt::test] + async fn test_with_json_and_bad_custom_content_type() { + let (req, mut pl) = TestRequest::with_header( + header::CONTENT_TYPE, + header::HeaderValue::from_static("text/html"), + ) + .header( + header::CONTENT_LENGTH, + header::HeaderValue::from_static("16"), + ) + .set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) + .data(JsonConfig::default().content_type(|mime: mime::Mime| { + mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN + })) + .to_http_parts(); + + let s = Json::::from_request(&req, &mut pl).await; + assert!(s.is_err()) } } diff --git a/src/types/mod.rs b/src/types/mod.rs index 43a189e2c..b32711e2a 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -12,3 +12,4 @@ pub use self::json::{Json, JsonConfig}; pub use self::path::{Path, PathConfig}; pub use self::payload::{Payload, PayloadConfig}; pub use self::query::{Query, QueryConfig}; +pub use self::readlines::Readlines; diff --git a/src/types/path.rs b/src/types/path.rs index 29a574feb..404759300 100644 --- a/src/types/path.rs +++ b/src/types/path.rs @@ -1,5 +1,4 @@ //! Path extractor - use std::sync::Arc; use std::{fmt, ops}; @@ -253,7 +252,7 @@ mod tests { use serde_derive::Deserialize; use super::*; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; use crate::{error, http, HttpResponse}; #[derive(Deserialize, Debug, Display)] @@ -269,118 +268,110 @@ mod tests { value: u32, } - #[test] - fn test_extract_path_single() { - block_on(async { - let resource = ResourceDef::new("/{value}/"); + #[actix_rt::test] + async fn test_extract_path_single() { + let resource = ResourceDef::new("/{value}/"); - let mut req = TestRequest::with_uri("/32/").to_srv_request(); - resource.match_path(req.match_info_mut()); + let mut req = TestRequest::with_uri("/32/").to_srv_request(); + resource.match_path(req.match_info_mut()); - let (req, mut pl) = req.into_parts(); - assert_eq!(*Path::::from_request(&req, &mut pl).await.unwrap(), 32); - assert!(Path::::from_request(&req, &mut pl).await.is_err()); - }) + let (req, mut pl) = req.into_parts(); + assert_eq!(*Path::::from_request(&req, &mut pl).await.unwrap(), 32); + assert!(Path::::from_request(&req, &mut pl).await.is_err()); } - #[test] - fn test_tuple_extract() { - block_on(async { - let resource = ResourceDef::new("/{key}/{value}/"); + #[actix_rt::test] + async fn test_tuple_extract() { + let resource = ResourceDef::new("/{key}/{value}/"); - let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request(); - resource.match_path(req.match_info_mut()); + let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request(); + resource.match_path(req.match_info_mut()); - let (req, mut pl) = req.into_parts(); - let res = <(Path<(String, String)>,)>::from_request(&req, &mut pl) - .await - .unwrap(); - assert_eq!((res.0).0, "name"); - assert_eq!((res.0).1, "user1"); - - let res = <(Path<(String, String)>, Path<(String, String)>)>::from_request( - &req, &mut pl, - ) + let (req, mut pl) = req.into_parts(); + let res = <(Path<(String, String)>,)>::from_request(&req, &mut pl) .await .unwrap(); - assert_eq!((res.0).0, "name"); - assert_eq!((res.0).1, "user1"); - assert_eq!((res.1).0, "name"); - assert_eq!((res.1).1, "user1"); + assert_eq!((res.0).0, "name"); + assert_eq!((res.0).1, "user1"); - let () = <()>::from_request(&req, &mut pl).await.unwrap(); - }) + let res = <(Path<(String, String)>, Path<(String, String)>)>::from_request( + &req, &mut pl, + ) + .await + .unwrap(); + assert_eq!((res.0).0, "name"); + assert_eq!((res.0).1, "user1"); + assert_eq!((res.1).0, "name"); + assert_eq!((res.1).1, "user1"); + + let () = <()>::from_request(&req, &mut pl).await.unwrap(); } - #[test] - fn test_request_extract() { - block_on(async { - let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request(); + #[actix_rt::test] + async fn test_request_extract() { + let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request(); - let resource = ResourceDef::new("/{key}/{value}/"); - resource.match_path(req.match_info_mut()); + let resource = ResourceDef::new("/{key}/{value}/"); + resource.match_path(req.match_info_mut()); - let (req, mut pl) = req.into_parts(); - let mut s = Path::::from_request(&req, &mut pl).await.unwrap(); - assert_eq!(s.key, "name"); - assert_eq!(s.value, "user1"); - s.value = "user2".to_string(); - assert_eq!(s.value, "user2"); - assert_eq!( - format!("{}, {:?}", s, s), - "MyStruct(name, user2), MyStruct { key: \"name\", value: \"user2\" }" - ); - let s = s.into_inner(); - assert_eq!(s.value, "user2"); + let (req, mut pl) = req.into_parts(); + let mut s = Path::::from_request(&req, &mut pl).await.unwrap(); + assert_eq!(s.key, "name"); + assert_eq!(s.value, "user1"); + s.value = "user2".to_string(); + assert_eq!(s.value, "user2"); + assert_eq!( + format!("{}, {:?}", s, s), + "MyStruct(name, user2), MyStruct { key: \"name\", value: \"user2\" }" + ); + let s = s.into_inner(); + assert_eq!(s.value, "user2"); - let s = Path::<(String, String)>::from_request(&req, &mut pl) - .await - .unwrap(); - assert_eq!(s.0, "name"); - assert_eq!(s.1, "user1"); + let s = Path::<(String, String)>::from_request(&req, &mut pl) + .await + .unwrap(); + assert_eq!(s.0, "name"); + assert_eq!(s.1, "user1"); - let mut req = TestRequest::with_uri("/name/32/").to_srv_request(); - let resource = ResourceDef::new("/{key}/{value}/"); - resource.match_path(req.match_info_mut()); + let mut req = TestRequest::with_uri("/name/32/").to_srv_request(); + let resource = ResourceDef::new("/{key}/{value}/"); + resource.match_path(req.match_info_mut()); - let (req, mut pl) = req.into_parts(); - let s = Path::::from_request(&req, &mut pl).await.unwrap(); - assert_eq!(s.as_ref().key, "name"); - assert_eq!(s.value, 32); + let (req, mut pl) = req.into_parts(); + let s = Path::::from_request(&req, &mut pl).await.unwrap(); + assert_eq!(s.as_ref().key, "name"); + assert_eq!(s.value, 32); - let s = Path::<(String, u8)>::from_request(&req, &mut pl) - .await - .unwrap(); - assert_eq!(s.0, "name"); - assert_eq!(s.1, 32); + let s = Path::<(String, u8)>::from_request(&req, &mut pl) + .await + .unwrap(); + assert_eq!(s.0, "name"); + assert_eq!(s.1, 32); - let res = Path::>::from_request(&req, &mut pl) - .await - .unwrap(); - assert_eq!(res[0], "name".to_owned()); - assert_eq!(res[1], "32".to_owned()); - }) + let res = Path::>::from_request(&req, &mut pl) + .await + .unwrap(); + assert_eq!(res[0], "name".to_owned()); + assert_eq!(res[1], "32".to_owned()); } - #[test] - fn test_custom_err_handler() { - block_on(async { - let (req, mut pl) = TestRequest::with_uri("/name/user1/") - .data(PathConfig::default().error_handler(|err, _| { - error::InternalError::from_response( - err, - HttpResponse::Conflict().finish(), - ) - .into() - })) - .to_http_parts(); + #[actix_rt::test] + async fn test_custom_err_handler() { + let (req, mut pl) = TestRequest::with_uri("/name/user1/") + .data(PathConfig::default().error_handler(|err, _| { + error::InternalError::from_response( + err, + HttpResponse::Conflict().finish(), + ) + .into() + })) + .to_http_parts(); - let s = Path::<(usize,)>::from_request(&req, &mut pl) - .await - .unwrap_err(); - let res: HttpResponse = s.into(); + let s = Path::<(usize,)>::from_request(&req, &mut pl) + .await + .unwrap_err(); + let res: HttpResponse = s.into(); - assert_eq!(res.status(), http::StatusCode::CONFLICT); - }) + assert_eq!(res.status(), http::StatusCode::CONFLICT); } } diff --git a/src/types/payload.rs b/src/types/payload.rs index ee7e11667..2969e385a 100644 --- a/src/types/payload.rs +++ b/src/types/payload.rs @@ -395,10 +395,10 @@ mod tests { use super::*; use crate::http::header; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; - #[test] - fn test_payload_config() { + #[actix_rt::test] + async fn test_payload_config() { let req = TestRequest::default().to_http_request(); let cfg = PayloadConfig::default().mimetype(mime::APPLICATION_JSON); assert!(cfg.check_mimetype(&req).is_err()); @@ -415,32 +415,32 @@ mod tests { assert!(cfg.check_mimetype(&req).is_ok()); } - #[test] - fn test_bytes() { + #[actix_rt::test] + async fn test_bytes() { let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11") .set_payload(Bytes::from_static(b"hello=world")) .to_http_parts(); - let s = block_on(Bytes::from_request(&req, &mut pl)).unwrap(); + let s = Bytes::from_request(&req, &mut pl).await.unwrap(); assert_eq!(s, Bytes::from_static(b"hello=world")); } - #[test] - fn test_string() { + #[actix_rt::test] + async fn test_string() { let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11") .set_payload(Bytes::from_static(b"hello=world")) .to_http_parts(); - let s = block_on(String::from_request(&req, &mut pl)).unwrap(); + let s = String::from_request(&req, &mut pl).await.unwrap(); assert_eq!(s, "hello=world"); } - #[test] - fn test_message_body() { + #[actix_rt::test] + async fn test_message_body() { let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "xxxx") .to_srv_request() .into_parts(); - let res = block_on(HttpMessageBody::new(&req, &mut pl)); + let res = HttpMessageBody::new(&req, &mut pl).await; match res.err().unwrap() { PayloadError::UnknownLength => (), _ => unreachable!("error"), @@ -449,7 +449,7 @@ mod tests { let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "1000000") .to_srv_request() .into_parts(); - let res = block_on(HttpMessageBody::new(&req, &mut pl)); + let res = HttpMessageBody::new(&req, &mut pl).await; match res.err().unwrap() { PayloadError::Overflow => (), _ => unreachable!("error"), @@ -458,13 +458,13 @@ mod tests { let (req, mut pl) = TestRequest::default() .set_payload(Bytes::from_static(b"test")) .to_http_parts(); - let res = block_on(HttpMessageBody::new(&req, &mut pl)); + let res = HttpMessageBody::new(&req, &mut pl).await; assert_eq!(res.ok().unwrap(), Bytes::from_static(b"test")); let (req, mut pl) = TestRequest::default() .set_payload(Bytes::from_static(b"11111111111111")) .to_http_parts(); - let res = block_on(HttpMessageBody::new(&req, &mut pl).limit(5)); + let res = HttpMessageBody::new(&req, &mut pl).limit(5).await; match res.err().unwrap() { PayloadError::Overflow => (), _ => unreachable!("error"), diff --git a/src/types/query.rs b/src/types/query.rs index e442f1c31..b1f4572fa 100644 --- a/src/types/query.rs +++ b/src/types/query.rs @@ -228,7 +228,7 @@ mod tests { use super::*; use crate::error::InternalError; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; use crate::HttpResponse; #[derive(Deserialize, Debug, Display)] @@ -236,8 +236,8 @@ mod tests { id: String, } - #[test] - fn test_service_request_extract() { + #[actix_rt::test] + async fn test_service_request_extract() { let req = TestRequest::with_uri("/name/user1/").to_srv_request(); assert!(Query::::from_query(&req.query_string()).is_err()); @@ -252,48 +252,44 @@ mod tests { assert_eq!(s.id, "test1"); } - #[test] - fn test_request_extract() { - block_on(async { - let req = TestRequest::with_uri("/name/user1/").to_srv_request(); - let (req, mut pl) = req.into_parts(); - assert!(Query::::from_request(&req, &mut pl).await.is_err()); + #[actix_rt::test] + async fn test_request_extract() { + let req = TestRequest::with_uri("/name/user1/").to_srv_request(); + let (req, mut pl) = req.into_parts(); + assert!(Query::::from_request(&req, &mut pl).await.is_err()); - let req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request(); - let (req, mut pl) = req.into_parts(); + let req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request(); + let (req, mut pl) = req.into_parts(); - let mut s = Query::::from_request(&req, &mut pl).await.unwrap(); - assert_eq!(s.id, "test"); - assert_eq!(format!("{}, {:?}", s, s), "test, Id { id: \"test\" }"); + let mut s = Query::::from_request(&req, &mut pl).await.unwrap(); + assert_eq!(s.id, "test"); + assert_eq!(format!("{}, {:?}", s, s), "test, Id { id: \"test\" }"); - s.id = "test1".to_string(); - let s = s.into_inner(); - assert_eq!(s.id, "test1"); - }) + s.id = "test1".to_string(); + let s = s.into_inner(); + assert_eq!(s.id, "test1"); } - #[test] - fn test_custom_error_responder() { - block_on(async { - let req = TestRequest::with_uri("/name/user1/") - .data(QueryConfig::default().error_handler(|e, _| { - let resp = HttpResponse::UnprocessableEntity().finish(); - InternalError::from_response(e, resp).into() - })) - .to_srv_request(); + #[actix_rt::test] + async fn test_custom_error_responder() { + let req = TestRequest::with_uri("/name/user1/") + .data(QueryConfig::default().error_handler(|e, _| { + let resp = HttpResponse::UnprocessableEntity().finish(); + InternalError::from_response(e, resp).into() + })) + .to_srv_request(); - let (req, mut pl) = req.into_parts(); - let query = Query::::from_request(&req, &mut pl).await; + let (req, mut pl) = req.into_parts(); + let query = Query::::from_request(&req, &mut pl).await; - assert!(query.is_err()); - assert_eq!( - query - .unwrap_err() - .as_response_error() - .error_response() - .status(), - StatusCode::UNPROCESSABLE_ENTITY - ); - }) + assert!(query.is_err()); + assert_eq!( + query + .unwrap_err() + .as_response_error() + .error_response() + .status(), + StatusCode::UNPROCESSABLE_ENTITY + ); } } diff --git a/src/types/readlines.rs b/src/types/readlines.rs index e2b3f9c1d..123f8102b 100644 --- a/src/types/readlines.rs +++ b/src/types/readlines.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::future::Future; use std::pin::Pin; use std::str; use std::task::{Context, Poll}; @@ -7,7 +6,6 @@ use std::task::{Context, Poll}; use bytes::{Bytes, BytesMut}; use encoding_rs::{Encoding, UTF_8}; use futures::Stream; -use pin_project::pin_project; use crate::dev::Payload; use crate::error::{PayloadError, ReadlinesError}; @@ -174,12 +172,11 @@ mod tests { use futures::stream::StreamExt; use super::*; - use crate::test::{block_on, TestRequest}; + use crate::test::TestRequest; - #[test] - fn test_readlines() { - block_on(async { - let mut req = TestRequest::default() + #[actix_rt::test] + async fn test_readlines() { + let mut req = TestRequest::default() .set_payload(Bytes::from_static( b"Lorem Ipsum is simply dummy text of the printing and typesetting\n\ industry. Lorem Ipsum has been the industry's standard dummy\n\ @@ -187,21 +184,20 @@ mod tests { )) .to_request(); - let mut stream = Readlines::new(&mut req); - assert_eq!( - stream.next().await.unwrap().unwrap(), - "Lorem Ipsum is simply dummy text of the printing and typesetting\n" - ); + let mut stream = Readlines::new(&mut req); + assert_eq!( + stream.next().await.unwrap().unwrap(), + "Lorem Ipsum is simply dummy text of the printing and typesetting\n" + ); - assert_eq!( - stream.next().await.unwrap().unwrap(), - "industry. Lorem Ipsum has been the industry's standard dummy\n" - ); + assert_eq!( + stream.next().await.unwrap().unwrap(), + "industry. Lorem Ipsum has been the industry's standard dummy\n" + ); - assert_eq!( - stream.next().await.unwrap().unwrap(), - "Contrary to popular belief, Lorem Ipsum is not simply random text." - ); - }) + assert_eq!( + stream.next().await.unwrap().unwrap(), + "Contrary to popular belief, Lorem Ipsum is not simply random text." + ); } } diff --git a/src/web.rs b/src/web.rs index 22630ae81..7f1e8d8f6 100644 --- a/src/web.rs +++ b/src/web.rs @@ -6,7 +6,6 @@ pub use actix_http::Response as HttpResponse; pub use bytes::{Bytes, BytesMut}; pub use futures::channel::oneshot::Canceled; -use crate::error::Error; use crate::extract::FromRequest; use crate::handler::Factory; use crate::resource::Resource; diff --git a/test-server/Cargo.toml b/test-server/Cargo.toml index a2b03ffc2..e59e439fe 100644 --- a/test-server/Cargo.toml +++ b/test-server/Cargo.toml @@ -54,8 +54,6 @@ slab = "0.4" serde_urlencoded = "0.6.1" time = "0.1" tokio-net = "0.2.0-alpha.6" -tokio-timer = "0.3.0-alpha.6" - open-ssl = { version="0.10", package="openssl", optional = true } [dev-dependencies] diff --git a/test-server/src/lib.rs b/test-server/src/lib.rs index 1911c75d6..9ad06397c 100644 --- a/test-server/src/lib.rs +++ b/test-server/src/lib.rs @@ -23,26 +23,25 @@ pub use actix_testing::*; /// /// ```rust /// use actix_http::HttpService; -/// use actix_http_test::{block_on, TestServer}; +/// use actix_http_test::TestServer; /// use actix_web::{web, App, HttpResponse, Error}; /// /// async fn my_handler() -> Result { /// Ok(HttpResponse::Ok().into()) /// } /// -/// fn main() { -/// block_on( async { -/// let mut srv = TestServer::start( -/// || HttpService::new( -/// App::new().service( -/// web::resource("/").to(my_handler)) -/// ) -/// ); +/// #[actix_rt::test] +/// async fn test_example() { +/// let mut srv = TestServer::start( +/// || HttpService::new( +/// App::new().service( +/// web::resource("/").to(my_handler)) +/// ) +/// ); /// -/// let req = srv.get("/"); -/// let response = req.send().await.unwrap(); -/// assert!(response.status().is_success()); -/// }) +/// let req = srv.get("/"); +/// let response = req.send().await.unwrap(); +/// assert!(response.status().is_success()); /// } /// ``` pub struct TestServer; diff --git a/tests/test_httpserver.rs b/tests/test_httpserver.rs index 122f79baf..d19c46ee7 100644 --- a/tests/test_httpserver.rs +++ b/tests/test_httpserver.rs @@ -6,7 +6,7 @@ use std::{net, thread, time::Duration}; use open_ssl::ssl::SslAcceptorBuilder; use actix_http::Response; -use actix_web::{test, web, App, HttpServer}; +use actix_web::{web, App, HttpServer}; fn unused_addr() -> net::SocketAddr { let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap(); @@ -17,9 +17,9 @@ fn unused_addr() -> net::SocketAddr { tcp.local_addr().unwrap() } -#[test] #[cfg(unix)] -fn test_start() { +#[actix_rt::test] +async fn test_start() { let addr = unused_addr(); let (tx, rx) = mpsc::channel(); @@ -53,21 +53,18 @@ fn test_start() { #[cfg(feature = "client")] { use actix_http::client; - use actix_web::test; - test::block_on(async { - let client = awc::Client::build() - .connector( - client::Connector::new() - .timeout(Duration::from_millis(100)) - .finish(), - ) - .finish(); + let client = awc::Client::build() + .connector( + client::Connector::new() + .timeout(Duration::from_millis(100)) + .finish(), + ) + .finish(); - let host = format!("http://{}", addr); - let response = client.get(host.clone()).send().await.unwrap(); - assert!(response.status().is_success()); - }); + let host = format!("http://{}", addr); + let response = client.get(host.clone()).send().await.unwrap(); + assert!(response.status().is_success()); } // stop @@ -91,9 +88,9 @@ fn ssl_acceptor() -> std::io::Result { Ok(builder) } -#[test] +#[actix_rt::test] #[cfg(feature = "openssl")] -fn test_start_ssl() { +async fn test_start_ssl() { let addr = unused_addr(); let (tx, rx) = mpsc::channel(); @@ -119,27 +116,25 @@ fn test_start_ssl() { }); let (srv, sys) = rx.recv().unwrap(); - test::block_on(async move { - use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode}; - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_verify(SslVerifyMode::NONE); - let _ = builder - .set_alpn_protos(b"\x02h2\x08http/1.1") - .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e)); + use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode}; + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + builder.set_verify(SslVerifyMode::NONE); + let _ = builder + .set_alpn_protos(b"\x02h2\x08http/1.1") + .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e)); - let client = awc::Client::build() - .connector( - awc::Connector::new() - .ssl(builder.build()) - .timeout(Duration::from_millis(100)) - .finish(), - ) - .finish(); + let client = awc::Client::build() + .connector( + awc::Connector::new() + .ssl(builder.build()) + .timeout(Duration::from_millis(100)) + .finish(), + ) + .finish(); - let host = format!("https://{}", addr); - let response = client.get(host.clone()).send().await.unwrap(); - assert!(response.status().is_success()); - }); + let host = format!("https://{}", addr); + let response = client.get(host.clone()).send().await.unwrap(); + assert!(response.status().is_success()); // stop let _ = srv.stop(false); diff --git a/tests/test_server.rs b/tests/test_server.rs index 0114b21ff..bfdf3f0ee 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -5,7 +5,7 @@ use actix_http::http::header::{ TRANSFER_ENCODING, }; use actix_http::{h1, Error, HttpService, Response}; -use actix_http_test::{block_on, TestServer}; +use actix_http_test::TestServer; use brotli2::write::{BrotliDecoder, BrotliEncoder}; use bytes::Bytes; use flate2::read::GzDecoder; @@ -39,728 +39,676 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World"; -#[test] -fn test_body() { - block_on(async { - let srv = - TestServer::start(|| { - h1::H1Service::new(App::new().service( - web::resource("/").route(web::to(|| Response::Ok().body(STR))), - )) - }); +#[actix_rt::test] +async fn test_body() { + let srv = TestServer::start(|| { + h1::H1Service::new( + App::new() + .service(web::resource("/").route(web::to(|| Response::Ok().body(STR)))), + ) + }); - let mut response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); + let mut response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -#[test] -fn test_body_gzip() { - block_on(async { - let srv = TestServer::start(|| { - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Gzip)) - .service( - web::resource("/").route(web::to(|| Response::Ok().body(STR))), - ), - ) - }); +#[actix_rt::test] +async fn test_body_gzip() { + let srv = TestServer::start(|| { + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Gzip)) + .service(web::resource("/").route(web::to(|| Response::Ok().body(STR)))), + ) + }); - let mut response = srv - .get("/") - .no_decompress() - .header(ACCEPT_ENCODING, "gzip") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + let mut response = srv + .get("/") + .no_decompress() + .header(ACCEPT_ENCODING, "gzip") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); + // read response + let bytes = response.body().await.unwrap(); - // decode - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) + // decode + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -#[test] -fn test_body_gzip2() { - block_on(async { - let srv = TestServer::start(|| { - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Gzip)) - .service(web::resource("/").route(web::to(|| { - Response::Ok().body(STR).into_body::() - }))), - ) - }); +#[actix_rt::test] +async fn test_body_gzip2() { + let srv = TestServer::start(|| { + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Gzip)) + .service(web::resource("/").route(web::to(|| { + Response::Ok().body(STR).into_body::() + }))), + ) + }); - let mut response = srv - .get("/") - .no_decompress() - .header(ACCEPT_ENCODING, "gzip") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + let mut response = srv + .get("/") + .no_decompress() + .header(ACCEPT_ENCODING, "gzip") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); + // read response + let bytes = response.body().await.unwrap(); - // decode - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) + // decode + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -#[test] -fn test_body_encoding_override() { - block_on(async { - let srv = TestServer::start(|| { - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Gzip)) - .service(web::resource("/").route(web::to(|| { - Response::Ok().encoding(ContentEncoding::Deflate).body(STR) - }))) - .service(web::resource("/raw").route(web::to(|| { - let body = actix_web::dev::Body::Bytes(STR.into()); - let mut response = - Response::with_body(actix_web::http::StatusCode::OK, body); +#[actix_rt::test] +async fn test_body_encoding_override() { + let srv = TestServer::start(|| { + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Gzip)) + .service(web::resource("/").route(web::to(|| { + Response::Ok().encoding(ContentEncoding::Deflate).body(STR) + }))) + .service(web::resource("/raw").route(web::to(|| { + let body = actix_web::dev::Body::Bytes(STR.into()); + let mut response = + Response::with_body(actix_web::http::StatusCode::OK, body); - response.encoding(ContentEncoding::Deflate); + response.encoding(ContentEncoding::Deflate); - response - }))), - ) - }); + response + }))), + ) + }); - // Builder - let mut response = srv - .get("/") - .no_decompress() - .header(ACCEPT_ENCODING, "deflate") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + // Builder + let mut response = srv + .get("/") + .no_decompress() + .header(ACCEPT_ENCODING, "deflate") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); + // read response + let bytes = response.body().await.unwrap(); - // decode - let mut e = ZlibDecoder::new(Vec::new()); - e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); + // decode + let mut e = ZlibDecoder::new(Vec::new()); + e.write_all(bytes.as_ref()).unwrap(); + let dec = e.finish().unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - // Raw Response - let mut response = srv - .request(actix_web::http::Method::GET, srv.url("/raw")) - .no_decompress() - .header(ACCEPT_ENCODING, "deflate") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + // Raw Response + let mut response = srv + .request(actix_web::http::Method::GET, srv.url("/raw")) + .no_decompress() + .header(ACCEPT_ENCODING, "deflate") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); + // read response + let bytes = response.body().await.unwrap(); - // decode - let mut e = ZlibDecoder::new(Vec::new()); - e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) + // decode + let mut e = ZlibDecoder::new(Vec::new()); + e.write_all(bytes.as_ref()).unwrap(); + let dec = e.finish().unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -#[test] -fn test_body_gzip_large() { - block_on(async { - let data = STR.repeat(10); - let srv_data = data.clone(); +#[actix_rt::test] +async fn test_body_gzip_large() { + let data = STR.repeat(10); + let srv_data = data.clone(); - let srv = TestServer::start(move || { - let data = srv_data.clone(); - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Gzip)) - .service( - web::resource("/") - .route(web::to(move || Response::Ok().body(data.clone()))), - ), - ) - }); - - let mut response = srv - .get("/") - .no_decompress() - .header(ACCEPT_ENCODING, "gzip") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); - - // read response - let bytes = response.body().await.unwrap(); - - // decode - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from(data)); - }) -} - -#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -#[test] -fn test_body_gzip_large_random() { - block_on(async { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(70_000) - .collect::(); - let srv_data = data.clone(); - - let srv = TestServer::start(move || { - let data = srv_data.clone(); - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Gzip)) - .service( - web::resource("/") - .route(web::to(move || Response::Ok().body(data.clone()))), - ), - ) - }); - - let mut response = srv - .get("/") - .no_decompress() - .header(ACCEPT_ENCODING, "gzip") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); - - // read response - let bytes = response.body().await.unwrap(); - - // decode - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(dec.len(), data.len()); - assert_eq!(Bytes::from(dec), Bytes::from(data)); - }) -} - -#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -#[test] -fn test_body_chunked_implicit() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Gzip)) - .service(web::resource("/").route(web::get().to(move || { - Response::Ok().streaming(once(ok::<_, Error>( - Bytes::from_static(STR.as_ref()), - ))) - }))), - ) - }); - - let mut response = srv - .get("/") - .no_decompress() - .header(ACCEPT_ENCODING, "gzip") - .send() - .await - .unwrap(); - assert!(response.status().is_success()); - assert_eq!( - response.headers().get(TRANSFER_ENCODING).unwrap(), - &b"chunked"[..] - ); - - // read response - let bytes = response.body().await.unwrap(); - - // decode - let mut e = GzDecoder::new(&bytes[..]); - let mut dec = Vec::new(); - e.read_to_end(&mut dec).unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) -} - -#[test] -#[cfg(feature = "brotli")] -fn test_body_br_streaming() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().wrap(Compress::new(ContentEncoding::Br)).service( - web::resource("/").route(web::to(move || { - Response::Ok().streaming(once(ok::<_, Error>( - Bytes::from_static(STR.as_ref()), - ))) - })), + let srv = TestServer::start(move || { + let data = srv_data.clone(); + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Gzip)) + .service( + web::resource("/") + .route(web::to(move || Response::Ok().body(data.clone()))), ), - ) - }); + ) + }); - let mut response = srv - .get("/") - .header(ACCEPT_ENCODING, "br") - .no_decompress() - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + let mut response = srv + .get("/") + .no_decompress() + .header(ACCEPT_ENCODING, "gzip") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); + // read response + let bytes = response.body().await.unwrap(); - // decode br - let mut e = BrotliDecoder::new(Vec::with_capacity(2048)); - e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) + // decode + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from(data)); } -#[test] -fn test_head_binary() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new(App::new().service(web::resource("/").route( - web::head().to(move || Response::Ok().content_length(100).body(STR)), - ))) - }); - - let mut response = srv.head("/").send().await.unwrap(); - assert!(response.status().is_success()); - - { - let len = response.headers().get(CONTENT_LENGTH).unwrap(); - assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); - } - - // read response - let bytes = response.body().await.unwrap(); - assert!(bytes.is_empty()); - }) -} - -#[test] -fn test_no_chunking() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new(App::new().service(web::resource("/").route(web::to( - move || { - Response::Ok() - .no_chunking() - .content_length(STR.len() as u64) - .streaming(once(ok::<_, Error>(Bytes::from_static( - STR.as_ref(), - )))) - }, - )))) - }); - - let mut response = srv.get("/").send().await.unwrap(); - assert!(response.status().is_success()); - assert!(!response.headers().contains_key(TRANSFER_ENCODING)); - - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) -} - -#[test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_body_deflate() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new() - .wrap(Compress::new(ContentEncoding::Deflate)) - .service( - web::resource("/") - .route(web::to(move || Response::Ok().body(STR))), - ), - ) - }); +#[actix_rt::test] +async fn test_body_gzip_large_random() { + let data = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(70_000) + .collect::(); + let srv_data = data.clone(); - // client request - let mut response = srv - .get("/") - .header(ACCEPT_ENCODING, "deflate") - .no_decompress() - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + let srv = TestServer::start(move || { + let data = srv_data.clone(); + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Gzip)) + .service( + web::resource("/") + .route(web::to(move || Response::Ok().body(data.clone()))), + ), + ) + }); - // read response - let bytes = response.body().await.unwrap(); + let mut response = srv + .get("/") + .no_decompress() + .header(ACCEPT_ENCODING, "gzip") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - let mut e = ZlibDecoder::new(Vec::new()); - e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + + // decode + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(dec.len(), data.len()); + assert_eq!(Bytes::from(dec), Bytes::from(data)); } -#[test] -#[cfg(any(feature = "brotli"))] -fn test_body_brotli() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().wrap(Compress::new(ContentEncoding::Br)).service( +#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] +#[actix_rt::test] +async fn test_body_chunked_implicit() { + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Gzip)) + .service(web::resource("/").route(web::get().to(move || { + Response::Ok().streaming(once(ok::<_, Error>(Bytes::from_static( + STR.as_ref(), + )))) + }))), + ) + }); + + let mut response = srv + .get("/") + .no_decompress() + .header(ACCEPT_ENCODING, "gzip") + .send() + .await + .unwrap(); + assert!(response.status().is_success()); + assert_eq!( + response.headers().get(TRANSFER_ENCODING).unwrap(), + &b"chunked"[..] + ); + + // read response + let bytes = response.body().await.unwrap(); + + // decode + let mut e = GzDecoder::new(&bytes[..]); + let mut dec = Vec::new(); + e.read_to_end(&mut dec).unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +#[cfg(feature = "brotli")] +async fn test_body_br_streaming() { + let srv = TestServer::start(move || { + h1::H1Service::new(App::new().wrap(Compress::new(ContentEncoding::Br)).service( + web::resource("/").route(web::to(move || { + Response::Ok() + .streaming(once(ok::<_, Error>(Bytes::from_static(STR.as_ref())))) + })), + )) + }); + + let mut response = srv + .get("/") + .header(ACCEPT_ENCODING, "br") + .no_decompress() + .send() + .await + .unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = response.body().await.unwrap(); + + // decode br + let mut e = BrotliDecoder::new(Vec::with_capacity(2048)); + e.write_all(bytes.as_ref()).unwrap(); + let dec = e.finish().unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +async fn test_head_binary() { + let srv = TestServer::start(move || { + h1::H1Service::new(App::new().service(web::resource("/").route( + web::head().to(move || Response::Ok().content_length(100).body(STR)), + ))) + }); + + let mut response = srv.head("/").send().await.unwrap(); + assert!(response.status().is_success()); + + { + let len = response.headers().get(CONTENT_LENGTH).unwrap(); + assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); + } + + // read response + let bytes = response.body().await.unwrap(); + assert!(bytes.is_empty()); +} + +#[actix_rt::test] +async fn test_no_chunking() { + let srv = TestServer::start(move || { + h1::H1Service::new(App::new().service(web::resource("/").route(web::to( + move || { + Response::Ok() + .no_chunking() + .content_length(STR.len() as u64) + .streaming(once(ok::<_, Error>(Bytes::from_static(STR.as_ref())))) + }, + )))) + }); + + let mut response = srv.get("/").send().await.unwrap(); + assert!(response.status().is_success()); + assert!(!response.headers().contains_key(TRANSFER_ENCODING)); + + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] +#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] +async fn test_body_deflate() { + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new() + .wrap(Compress::new(ContentEncoding::Deflate)) + .service( web::resource("/").route(web::to(move || Response::Ok().body(STR))), ), - ) - }); + ) + }); - // client request - let mut response = srv - .get("/") - .header(ACCEPT_ENCODING, "br") - .no_decompress() - .send() - .await - .unwrap(); - assert!(response.status().is_success()); + // client request + let mut response = srv + .get("/") + .header(ACCEPT_ENCODING, "deflate") + .no_decompress() + .send() + .await + .unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); + // read response + let bytes = response.body().await.unwrap(); - // decode brotli - let mut e = BrotliDecoder::new(Vec::with_capacity(2048)); - e.write_all(bytes.as_ref()).unwrap(); - let dec = e.finish().unwrap(); - assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); - }) + let mut e = ZlibDecoder::new(Vec::new()); + e.write_all(bytes.as_ref()).unwrap(); + let dec = e.finish().unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); } -#[test] +#[actix_rt::test] +#[cfg(any(feature = "brotli"))] +async fn test_body_brotli() { + let srv = TestServer::start(move || { + h1::H1Service::new(App::new().wrap(Compress::new(ContentEncoding::Br)).service( + web::resource("/").route(web::to(move || Response::Ok().body(STR))), + )) + }); + + // client request + let mut response = srv + .get("/") + .header(ACCEPT_ENCODING, "br") + .no_decompress() + .send() + .await + .unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = response.body().await.unwrap(); + + // decode brotli + let mut e = BrotliDecoder::new(Vec::with_capacity(2048)); + e.write_all(bytes.as_ref()).unwrap(); + let dec = e.finish().unwrap(); + assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref())); +} + +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_encoding() { - block_on(async { - let srv = TestServer::start(move || { - HttpService::new( - App::new().wrap(Compress::default()).service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +async fn test_encoding() { + let srv = TestServer::start(move || { + HttpService::new( + App::new().wrap(Compress::default()).service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - // client request - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(STR.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + // client request + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(STR.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - let request = srv - .post("/") - .header(CONTENT_ENCODING, "gzip") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + let request = srv + .post("/") + .header(CONTENT_ENCODING, "gzip") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_gzip_encoding() { - block_on(async { - let srv = TestServer::start(move || { - HttpService::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +async fn test_gzip_encoding() { + let srv = TestServer::start(move || { + HttpService::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - // client request - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(STR.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + // client request + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(STR.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - let request = srv - .post("/") - .header(CONTENT_ENCODING, "gzip") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + let request = srv + .post("/") + .header(CONTENT_ENCODING, "gzip") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_gzip_encoding_large() { - block_on(async { - let data = STR.repeat(10); - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +async fn test_gzip_encoding_large() { + let data = STR.repeat(10); + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - // client request - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + // client request + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(data.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - let request = srv - .post("/") - .header(CONTENT_ENCODING, "gzip") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + let request = srv + .post("/") + .header(CONTENT_ENCODING, "gzip") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from(data)); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from(data)); } -#[test] +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_reading_gzip_encoding_large_random() { - block_on(async { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(60_000) - .collect::(); +async fn test_reading_gzip_encoding_large_random() { + let data = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(60_000) + .collect::(); - let srv = TestServer::start(move || { - HttpService::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); + let srv = TestServer::start(move || { + HttpService::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - // client request - let mut e = GzEncoder::new(Vec::new(), Compression::default()); - e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + // client request + let mut e = GzEncoder::new(Vec::new(), Compression::default()); + e.write_all(data.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - let request = srv - .post("/") - .header(CONTENT_ENCODING, "gzip") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + let request = srv + .post("/") + .header(CONTENT_ENCODING, "gzip") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes.len(), data.len()); - assert_eq!(bytes, Bytes::from(data)); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes.len(), data.len()); + assert_eq!(bytes, Bytes::from(data)); } -#[test] +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_reading_deflate_encoding() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +async fn test_reading_deflate_encoding() { + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); - e.write_all(STR.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); + e.write_all(STR.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - // client request - let request = srv - .post("/") - .header(CONTENT_ENCODING, "deflate") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // client request + let request = srv + .post("/") + .header(CONTENT_ENCODING, "deflate") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } -#[test] +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_reading_deflate_encoding_large() { - block_on(async { - let data = STR.repeat(10); - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +async fn test_reading_deflate_encoding_large() { + let data = STR.repeat(10); + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); - e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); + e.write_all(data.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - // client request - let request = srv - .post("/") - .header(CONTENT_ENCODING, "deflate") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // client request + let request = srv + .post("/") + .header(CONTENT_ENCODING, "deflate") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from(data)); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from(data)); } -#[test] +#[actix_rt::test] #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] -fn test_reading_deflate_encoding_large_random() { - block_on(async { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(160_000) - .collect::(); +async fn test_reading_deflate_encoding_large_random() { + let data = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(160_000) + .collect::(); - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); - e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); + e.write_all(data.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - // client request - let request = srv - .post("/") - .header(CONTENT_ENCODING, "deflate") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // client request + let request = srv + .post("/") + .header(CONTENT_ENCODING, "deflate") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes.len(), data.len()); - assert_eq!(bytes, Bytes::from(data)); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes.len(), data.len()); + assert_eq!(bytes, Bytes::from(data)); } -#[test] +#[actix_rt::test] #[cfg(feature = "brotli")] -fn test_brotli_encoding() { - block_on(async { - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +async fn test_brotli_encoding() { + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - let mut e = BrotliEncoder::new(Vec::new(), 5); - e.write_all(STR.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + let mut e = BrotliEncoder::new(Vec::new(), 5); + e.write_all(STR.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - // client request - let request = srv - .post("/") - .header(CONTENT_ENCODING, "br") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // client request + let request = srv + .post("/") + .header(CONTENT_ENCODING, "br") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from_static(STR.as_ref())); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } #[cfg(feature = "brotli")] -#[test] -fn test_brotli_encoding_large() { - block_on(async { - let data = STR.repeat(10); - let srv = TestServer::start(move || { - h1::H1Service::new( - App::new().service( - web::resource("/") - .route(web::to(move |body: Bytes| Response::Ok().body(body))), - ), - ) - }); +#[actix_rt::test] +async fn test_brotli_encoding_large() { + let data = STR.repeat(10); + let srv = TestServer::start(move || { + h1::H1Service::new( + App::new().service( + web::resource("/") + .route(web::to(move |body: Bytes| Response::Ok().body(body))), + ), + ) + }); - let mut e = BrotliEncoder::new(Vec::new(), 5); - e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + let mut e = BrotliEncoder::new(Vec::new(), 5); + e.write_all(data.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - // client request - let request = srv - .post("/") - .header(CONTENT_ENCODING, "br") - .send_body(enc.clone()); - let mut response = request.await.unwrap(); - assert!(response.status().is_success()); + // client request + let request = srv + .post("/") + .header(CONTENT_ENCODING, "br") + .send_body(enc.clone()); + let mut response = request.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes, Bytes::from(data)); - }) + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes, Bytes::from(data)); } // #[cfg(all(feature = "brotli", feature = "ssl"))] -// #[test] -// fn test_brotli_encoding_large_ssl() { +// #[actix_rt::test] +// async fn test_brotli_encoding_large_ssl() { // use actix::{Actor, System}; // use openssl::ssl::{ // SslAcceptor, SslConnector, SslFiletype, SslMethod, SslVerifyMode, @@ -819,91 +767,89 @@ fn test_brotli_encoding_large() { feature = "openssl", any(feature = "flate2-zlib", feature = "flate2-rust") ))] -#[test] -fn test_reading_deflate_encoding_large_random_ssl() { - block_on(async { - use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode}; - use rust_tls::internal::pemfile::{certs, pkcs8_private_keys}; - use rust_tls::{NoClientAuth, ServerConfig}; - use std::fs::File; - use std::io::BufReader; - use std::sync::mpsc; +#[actix_rt::test] +async fn test_reading_deflate_encoding_large_random_ssl() { + use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode}; + use rust_tls::internal::pemfile::{certs, pkcs8_private_keys}; + use rust_tls::{NoClientAuth, ServerConfig}; + use std::fs::File; + use std::io::BufReader; + use std::sync::mpsc; - let addr = TestServer::unused_addr(); - let (tx, rx) = mpsc::channel(); + let addr = TestServer::unused_addr(); + let (tx, rx) = mpsc::channel(); - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(160_000) - .collect::(); + let data = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(160_000) + .collect::(); - std::thread::spawn(move || { - let sys = actix_rt::System::new("test"); + std::thread::spawn(move || { + let sys = actix_rt::System::new("test"); - // load ssl keys - let mut config = ServerConfig::new(NoClientAuth::new()); - let cert_file = &mut BufReader::new(File::open("tests/cert.pem").unwrap()); - let key_file = &mut BufReader::new(File::open("tests/key.pem").unwrap()); - let cert_chain = certs(cert_file).unwrap(); - let mut keys = pkcs8_private_keys(key_file).unwrap(); - config.set_single_cert(cert_chain, keys.remove(0)).unwrap(); + // load ssl keys + let mut config = ServerConfig::new(NoClientAuth::new()); + let cert_file = &mut BufReader::new(File::open("tests/cert.pem").unwrap()); + let key_file = &mut BufReader::new(File::open("tests/key.pem").unwrap()); + let cert_chain = certs(cert_file).unwrap(); + let mut keys = pkcs8_private_keys(key_file).unwrap(); + config.set_single_cert(cert_chain, keys.remove(0)).unwrap(); - let srv = HttpServer::new(|| { - App::new().service(web::resource("/").route(web::to(|bytes: Bytes| { - async move { - Ok::<_, Error>( - HttpResponse::Ok() - .encoding(http::ContentEncoding::Identity) - .body(bytes), - ) - } - }))) - }) - .bind_rustls(addr, config) - .unwrap() - .start(); + let srv = HttpServer::new(|| { + App::new().service(web::resource("/").route(web::to(|bytes: Bytes| { + async move { + Ok::<_, Error>( + HttpResponse::Ok() + .encoding(http::ContentEncoding::Identity) + .body(bytes), + ) + } + }))) + }) + .bind_rustls(addr, config) + .unwrap() + .start(); - let _ = tx.send((srv, actix_rt::System::current())); - let _ = sys.run(); - }); - let (srv, _sys) = rx.recv().unwrap(); - let client = { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_verify(SslVerifyMode::NONE); - let _ = builder.set_alpn_protos(b"\x02h2\x08http/1.1").unwrap(); + let _ = tx.send((srv, actix_rt::System::current())); + let _ = sys.run(); + }); + let (srv, _sys) = rx.recv().unwrap(); + let client = { + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + builder.set_verify(SslVerifyMode::NONE); + let _ = builder.set_alpn_protos(b"\x02h2\x08http/1.1").unwrap(); - awc::Client::build() - .connector( - awc::Connector::new() - .timeout(std::time::Duration::from_millis(500)) - .ssl(builder.build()) - .finish(), - ) - .finish() - }; + awc::Client::build() + .connector( + awc::Connector::new() + .timeout(std::time::Duration::from_millis(500)) + .ssl(builder.build()) + .finish(), + ) + .finish() + }; - // encode data - let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); - e.write_all(data.as_ref()).unwrap(); - let enc = e.finish().unwrap(); + // encode data + let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); + e.write_all(data.as_ref()).unwrap(); + let enc = e.finish().unwrap(); - // client request - let req = client - .post(format!("https://localhost:{}/", addr.port())) - .header(http::header::CONTENT_ENCODING, "deflate") - .send_body(enc); + // client request + let req = client + .post(format!("https://localhost:{}/", addr.port())) + .header(http::header::CONTENT_ENCODING, "deflate") + .send_body(enc); - let mut response = req.await.unwrap(); - assert!(response.status().is_success()); + let mut response = req.await.unwrap(); + assert!(response.status().is_success()); - // read response - let bytes = response.body().await.unwrap(); - assert_eq!(bytes.len(), data.len()); - assert_eq!(bytes, Bytes::from(data)); + // read response + let bytes = response.body().await.unwrap(); + assert_eq!(bytes.len(), data.len()); + assert_eq!(bytes, Bytes::from(data)); - // stop - let _ = srv.stop(false); - }) + // stop + let _ = srv.stop(false); } // #[cfg(all(feature = "tls", feature = "ssl"))]