Browse Source

use actix_rt::test for test setup

master
Nikolay Kim 8 months ago
parent
commit
4dc31aac93
80 changed files with 6662 additions and 7397 deletions
  1. +7
    -4
      .travis.yml
  2. +2
    -13
      Cargo.toml
  3. +3
    -0
      actix-cors/Cargo.toml
  4. +335
    -353
      actix-cors/src/lib.rs
  5. +1
    -0
      actix-files/Cargo.toml
  6. +562
    -618
      actix-files/src/lib.rs
  7. +2
    -4
      actix-framed/src/test.rs
  8. +115
    -120
      actix-framed/tests/test_server.rs
  9. +3
    -7
      actix-http/Cargo.toml
  10. +33
    -32
      actix-http/src/body.rs
  11. +3
    -5
      actix-http/src/client/connector.rs
  12. +2
    -3
      actix-http/src/client/h1proto.rs
  13. +1
    -4
      actix-http/src/client/h2proto.rs
  14. +11
    -14
      actix-http/src/client/pool.rs
  15. +14
    -23
      actix-http/src/config.rs
  16. +0
    -1
      actix-http/src/cookie/secure/key.rs
  17. +0
    -4
      actix-http/src/error.rs
  18. +1
    -3
      actix-http/src/h1/decoder.rs
  19. +8
    -9
      actix-http/src/h1/dispatcher.rs
  20. +0
    -2
      actix-http/src/h1/expect.rs
  21. +11
    -17
      actix-http/src/h1/payload.rs
  22. +1
    -1
      actix-http/src/h1/service.rs
  23. +0
    -2
      actix-http/src/h1/upgrade.rs
  24. +0
    -1
      actix-http/src/h1/utils.rs
  25. +2
    -2
      actix-http/src/h2/dispatcher.rs
  26. +1
    -2
      actix-http/src/lib.rs
  27. +0
    -1
      actix-http/src/payload.rs
  28. +0
    -1
      actix-http/src/response.rs
  29. +2
    -2
      actix-http/src/service.rs
  30. +1
    -1
      actix-http/src/test.rs
  31. +44
    -51
      actix-http/tests/test_client.rs
  32. +369
    -398
      actix-http/tests/test_openssl.rs
  33. +312
    -345
      actix-http/tests/test_rustls.rs
  34. +480
    -535
      actix-http/tests/test_server.rs
  35. +43
    -45
      actix-http/tests/test_ws.rs
  36. +291
    -326
      actix-identity/src/lib.rs
  37. +174
    -193
      actix-multipart/src/server.rs
  38. +106
    -114
      actix-session/src/cookie.rs
  39. +1
    -0
      actix-web-codegen/Cargo.toml
  40. +86
    -92
      actix-web-codegen/tests/test_macro.rs
  41. +2
    -4
      awc/Cargo.toml
  42. +9
    -12
      awc/src/lib.rs
  43. +26
    -31
      awc/src/request.rs
  44. +76
    -82
      awc/src/response.rs
  45. +1
    -1
      awc/src/sender.rs
  46. +35
    -39
      awc/src/ws.rs
  47. +549
    -602
      awc/tests/test_client.rs
  48. +45
    -48
      awc/tests/test_rustls_client.rs
  49. +44
    -47
      awc/tests/test_ssl_client.rs
  50. +45
    -47
      awc/tests/test_ws.rs
  51. +170
    -208
      src/app.rs
  52. +18
    -18
      src/app_service.rs
  53. +63
    -69
      src/config.rs
  54. +72
    -79
      src/data.rs
  55. +19
    -11
      src/extract.rs
  56. +12
    -13
      src/lib.rs
  57. +35
    -41
      src/middleware/condition.rs
  58. +41
    -48
      src/middleware/defaultheaders.rs
  59. +32
    -38
      src/middleware/errhandlers.rs
  60. +11
    -11
      src/middleware/logger.rs
  61. +42
    -48
      src/middleware/normalize.rs
  62. +57
    -61
      src/request.rs
  63. +165
    -198
      src/resource.rs
  64. +152
    -166
      src/responder.rs
  65. +76
    -79
      src/route.rs
  66. +467
    -538
      src/scope.rs
  67. +25
    -31
      src/service.rs
  68. +169
    -193
      src/test.rs
  69. +88
    -104
      src/types/form.rs
  70. +183
    -197
      src/types/json.rs
  71. +1
    -0
      src/types/mod.rs
  72. +93
    -102
      src/types/path.rs
  73. +15
    -15
      src/types/payload.rs
  74. +37
    -41
      src/types/query.rs
  75. +19
    -23
      src/types/readlines.rs
  76. +0
    -1
      src/web.rs
  77. +0
    -2
      test-server/Cargo.toml
  78. +12
    -13
      test-server/src/lib.rs
  79. +36
    -41
      tests/test_httpserver.rs
  80. +693
    -747
      tests/test_server.rs

+ 7
- 4
.travis.yml View File

@@ -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"


+ 2
- 13
Cargo.toml View File

@@ -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" }

+ 3
- 0
actix-cors/Cargo.toml View File

@@ -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"

+ 335
- 353
actix-cors/src/lib.rs View File

@@ -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();

let resp = test::call_service(&mut cors, req).await;
assert_eq!(resp.status(), StatusCode::OK);
})
#[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);
}

#[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();

let resp = test::call_service(&mut cors, req).await;
assert_eq!(resp.status(), StatusCode::OK);
})
#[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);
}

#[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();

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);

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());

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)
#[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();

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();

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 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"));

Rc::get_mut(&mut cors.inner).unwrap().preflight = false;

let req = TestRequest::with_header("Origin", "https://www.example.com")
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(
header::ACCESS_CONTROL_REQUEST_HEADERS,
"AUTHORIZATION,ACCEPT",
)
.method(Method::OPTIONS)
.to_srv_request();
.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"));

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"));

Rc::get_mut(&mut cors.inner).unwrap().preflight = false;

let req = TestRequest::with_header("Origin", "https://www.example.com")
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(
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);
})
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();

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();
})
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();
}

#[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();

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);
})
#[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 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();

let req = TestRequest::default().method(Method::GET).to_srv_request();
let resp = test::call_service(&mut cors, req).await;
assert!(resp
.headers()
#[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::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)
.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()
);
})
.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()
);
#[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()
.split(',')
.map(|s| s.trim())
.collect::<Vec<&str>>();

{
let headers = resp
.headers()
.get(header::ACCESS_CONTROL_EXPOSE_HEADERS)
.unwrap()
.to_str()
.unwrap()
.split(',')
.map(|s| s.trim())
.collect::<Vec<&str>>();

for h in exposed_headers {
assert!(headers.contains(&h.as_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 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);
}

let origins_str = resp
.headers()
#[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 resp = test::call_service(&mut cors, req).await;
assert_eq!(
&b"https://example.com"[..],
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.to_str()
.unwrap();
.as_bytes()
);

assert_eq!("https://www.example.com", origins_str);
})
}
let req = TestRequest::with_header("Origin", "https://example.org")
.method(Method::GET)
.to_srv_request();

#[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();

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 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();

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 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()
);
})
#[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 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 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()
);
}
}

+ 1
- 0
actix-files/Cargo.toml View File

@@ -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"] }

+ 562
- 618
actix-files/src/lib.rs
File diff suppressed because it is too large
View File


+ 2
- 4
actix-framed/src/test.rs View File

@@ -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<S> TestRequest<S> {
}

/// This method generates `FramedRequest` instance and executes async handler
pub fn run<F, R, I, E>(self, f: F) -> Result<I, E>
pub async fn run<F, R, I, E>(self, f: F) -> Result<I, E>
where
F: FnOnce(FramedRequest<TestBuffer, S>) -> R,
R: Future<Output = Result<I, E>>,
{
let mut rt = Runtime::new().unwrap();
rt.block_on(f(self.finish()))
f(self.finish()).await
}
}



+ 115
- 120
actix-framed/tests/test_server.rs View File

@@ -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<ws::Message, Error> {
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()))
);
})
#[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()))
});

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_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(|_| ()),
)
});

// 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()))
);
})
.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()))
);
}

+ 3
- 7
actix-http/Cargo.toml View File

@@ -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"


+ 33
- 32
actix-http/src/body.rs View File

@@ -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(),


+ 3
- 5
actix-http/src/client/connector.rs View File

@@ -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;


+ 2
- 3
actix-http/src/client/h1proto.rs View File

@@ -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;


+ 1
- 4
actix-http/src/client/h2proto.rs View File

@@ -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};


+ 11
- 14
actix-http/src/client/pool.rs View File

@@ -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<RefCell<Inner<Io>>>,
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),


+ 14
- 23
actix-http/src/config.rs View File

@@ -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);
}
}

+ 0
- 1
actix-http/src/cookie/secure/key.rs View File

@@ -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;


+ 0
- 4
actix-http/src/error.rs View File

@@ -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 {}


+ 1
- 3
actix-http/src/h1/decoder.rs View File

@@ -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};


+ 8
- 9
actix-http/src/h1/dispatcher.rs View File

@@ -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<TestBuffer>>::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;
}
}

+ 0
- 2
actix-http/src/h1/expect.rs View File

@@ -1,5 +1,3 @@
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

use actix_server_config::ServerConfig;


+ 11
- 17
actix-http/src/h1/payload.rs View File

@@ -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()
);
}
}

+ 1
- 1
actix-http/src/h1/service.rs View File

@@ -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;


+ 0
- 2
actix-http/src/h1/upgrade.rs View File

@@ -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;


+ 0
- 1
actix-http/src/h1/utils.rs View File

@@ -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;


+ 2
- 2
actix-http/src/h2/dispatcher.rs View File

@@ -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,


+ 1
- 2
actix-http/src/lib.rs View File

@@ -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]


+ 0
- 1
actix-http/src/payload.rs View File

@@ -1,4 +1,3 @@
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};



+ 0
- 1
actix-http/src/response.rs View File

@@ -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;


+ 2
- 2
actix-http/src/service.rs View File

@@ -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<T: AsyncRead> AsyncRead for Io<T> {
// }
}

impl<T: AsyncWrite> tokio_io::AsyncWrite for Io<T> {
impl<T: AsyncWrite> actix_codec::AsyncWrite for Io<T> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,


+ 1
- 1
actix-http/src/test.rs View File

@@ -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;


+ 44
- 51
actix-http/tests/test_client.rs View File

@@ -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());
}

+ 369
- 398
actix-http/tests/test_openssl.rs View File

@@ -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};