mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-24 00:21:08 +01:00
use actix_rt::test for test setup
This commit is contained in:
parent
c1c44a7dd6
commit
4dc31aac93
11
.travis.yml
11
.travis.yml
@ -36,9 +36,12 @@ before_script:
|
|||||||
script:
|
script:
|
||||||
- cargo update
|
- cargo update
|
||||||
- cargo check --all --no-default-features
|
- cargo check --all --no-default-features
|
||||||
- cargo test --all-features --all -- --nocapture
|
- |
|
||||||
# - cd actix-http; cargo test --no-default-features --features="rustls" -- --nocapture; cd ..
|
if [[ "$TRAVIS_RUST_VERSION" == "stable" || "$TRAVIS_RUST_VERSION" == "beta" ]]; then
|
||||||
# - cd awc; cargo test --no-default-features --features="rustls" -- --nocapture; cd ..
|
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
|
# Upload docs
|
||||||
after_success:
|
after_success:
|
||||||
@ -51,7 +54,7 @@ after_success:
|
|||||||
echo "Uploaded documentation"
|
echo "Uploaded documentation"
|
||||||
fi
|
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
|
taskset -c 0 cargo tarpaulin --out Xml --all --all-features
|
||||||
bash <(curl -s https://codecov.io/bash)
|
bash <(curl -s https://codecov.io/bash)
|
||||||
echo "Uploaded code coverage"
|
echo "Uploaded code coverage"
|
||||||
|
15
Cargo.toml
15
Cargo.toml
@ -66,7 +66,7 @@ fail = ["actix-http/fail"]
|
|||||||
openssl = ["open-ssl", "actix-server/openssl", "awc/openssl"]
|
openssl = ["open-ssl", "actix-server/openssl", "awc/openssl"]
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
# rustls = ["rust-tls", "actix-server/rustls", "awc/rustls"]
|
rustls = ["rust-tls", "actix-server/rustls", "awc/rustls"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-codec = "0.2.0-alpha.1"
|
actix-codec = "0.2.0-alpha.1"
|
||||||
@ -110,7 +110,6 @@ actix-http-test = "0.3.0-alpha.1"
|
|||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
tokio-timer = "0.3.0-alpha.6"
|
|
||||||
brotli2 = "0.3.2"
|
brotli2 = "0.3.2"
|
||||||
flate2 = "1.0.2"
|
flate2 = "1.0.2"
|
||||||
|
|
||||||
@ -135,19 +134,9 @@ awc = { path = "awc" }
|
|||||||
actix-codec = { git = "https://github.com/actix/actix-net.git" }
|
actix-codec = { git = "https://github.com/actix/actix-net.git" }
|
||||||
actix-connect = { 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-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 = { git = "https://github.com/actix/actix-net.git" }
|
||||||
actix-server-config = { 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-service = { git = "https://github.com/actix/actix-net.git" }
|
||||||
actix-testing = { 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-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" }
|
|
||||||
|
@ -21,3 +21,6 @@ actix-web = "2.0.0-alpha.1"
|
|||||||
actix-service = "1.0.0-alpha.1"
|
actix-service = "1.0.0-alpha.1"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.2"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
actix-rt = "1.0.0-alpha.1"
|
||||||
|
@ -814,142 +814,136 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use actix_service::{service_fn2, Transform};
|
use actix_service::{service_fn2, Transform};
|
||||||
use actix_web::test::{self, block_on, TestRequest};
|
use actix_web::test::{self, TestRequest};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
#[should_panic(expected = "Credentials are allowed, but the Origin is set to")]
|
#[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();
|
let _cors = Cors::new().supports_credentials().send_wildcard().finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn validate_origin_allows_all_origins() {
|
async fn validate_origin_allows_all_origins() {
|
||||||
block_on(async {
|
let mut cors = Cors::new()
|
||||||
let mut cors = Cors::new()
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
.to_srv_request();
|
||||||
.to_srv_request();
|
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn default() {
|
async fn default() {
|
||||||
block_on(async {
|
let mut cors = Cors::default()
|
||||||
let mut cors = Cors::default()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
.to_srv_request();
|
||||||
.to_srv_request();
|
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_preflight() {
|
async fn test_preflight() {
|
||||||
block_on(async {
|
let mut cors = Cors::new()
|
||||||
let mut cors = Cors::new()
|
.send_wildcard()
|
||||||
.send_wildcard()
|
.max_age(3600)
|
||||||
.max_age(3600)
|
.allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST])
|
||||||
.allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST])
|
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
|
||||||
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
|
.allowed_header(header::CONTENT_TYPE)
|
||||||
.allowed_header(header::CONTENT_TYPE)
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
.method(Method::OPTIONS)
|
.method(Method::OPTIONS)
|
||||||
.header(header::ACCESS_CONTROL_REQUEST_HEADERS, "X-Not-Allowed")
|
.header(header::ACCESS_CONTROL_REQUEST_HEADERS, "X-Not-Allowed")
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
assert!(cors.inner.validate_allowed_method(req.head()).is_err());
|
assert!(cors.inner.validate_allowed_method(req.head()).is_err());
|
||||||
assert!(cors.inner.validate_allowed_headers(req.head()).is_err());
|
assert!(cors.inner.validate_allowed_headers(req.head()).is_err());
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "put")
|
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "put")
|
||||||
.method(Method::OPTIONS)
|
.method(Method::OPTIONS)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
assert!(cors.inner.validate_allowed_method(req.head()).is_err());
|
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_headers(req.head()).is_ok());
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
|
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
|
||||||
.header(
|
.header(
|
||||||
header::ACCESS_CONTROL_REQUEST_HEADERS,
|
header::ACCESS_CONTROL_REQUEST_HEADERS,
|
||||||
"AUTHORIZATION,ACCEPT",
|
"AUTHORIZATION,ACCEPT",
|
||||||
)
|
)
|
||||||
.method(Method::OPTIONS)
|
.method(Method::OPTIONS)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&b"*"[..],
|
&b"*"[..],
|
||||||
resp.headers()
|
resp.headers()
|
||||||
.get(&header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
.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)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_str()
|
.as_bytes()
|
||||||
.unwrap();
|
);
|
||||||
assert!(hdr.contains("authorization"));
|
assert_eq!(
|
||||||
assert!(hdr.contains("accept"));
|
&b"3600"[..],
|
||||||
assert!(hdr.contains("content-type"));
|
resp.headers()
|
||||||
|
.get(&header::ACCESS_CONTROL_MAX_AGE)
|
||||||
let methods = resp
|
|
||||||
.headers()
|
|
||||||
.get(header::ACCESS_CONTROL_ALLOW_METHODS)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_str()
|
.as_bytes()
|
||||||
.unwrap();
|
);
|
||||||
assert!(methods.contains("POST"));
|
let hdr = resp
|
||||||
assert!(methods.contains("GET"));
|
.headers()
|
||||||
assert!(methods.contains("OPTIONS"));
|
.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")
|
Rc::get_mut(&mut cors.inner).unwrap().preflight = false;
|
||||||
.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;
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
.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")]
|
// #[should_panic(expected = "MissingOrigin")]
|
||||||
// fn test_validate_missing_origin() {
|
// async fn test_validate_missing_origin() {
|
||||||
// let cors = Cors::build()
|
// let cors = Cors::build()
|
||||||
// .allowed_origin("https://www.example.com")
|
// .allowed_origin("https://www.example.com")
|
||||||
// .finish();
|
// .finish();
|
||||||
@ -957,257 +951,245 @@ mod tests {
|
|||||||
// cors.start(&req).unwrap();
|
// cors.start(&req).unwrap();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
#[should_panic(expected = "OriginNotAllowed")]
|
#[should_panic(expected = "OriginNotAllowed")]
|
||||||
fn test_validate_not_allowed_origin() {
|
async fn test_validate_not_allowed_origin() {
|
||||||
block_on(async {
|
let cors = Cors::new()
|
||||||
let cors = Cors::new()
|
.allowed_origin("https://www.example.com")
|
||||||
.allowed_origin("https://www.example.com")
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://www.unknown.com")
|
let req = TestRequest::with_header("Origin", "https://www.unknown.com")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
cors.inner.validate_origin(req.head()).unwrap();
|
cors.inner.validate_origin(req.head()).unwrap();
|
||||||
cors.inner.validate_allowed_method(req.head()).unwrap();
|
cors.inner.validate_allowed_method(req.head()).unwrap();
|
||||||
cors.inner.validate_allowed_headers(req.head()).unwrap();
|
cors.inner.validate_allowed_headers(req.head()).unwrap();
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_validate_origin() {
|
async fn test_validate_origin() {
|
||||||
block_on(async {
|
let mut cors = Cors::new()
|
||||||
let mut cors = Cors::new()
|
.allowed_origin("https://www.example.com")
|
||||||
.allowed_origin("https://www.example.com")
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_no_origin_response() {
|
async fn test_no_origin_response() {
|
||||||
block_on(async {
|
let mut cors = Cors::new()
|
||||||
let mut cors = Cors::new()
|
.disable_preflight()
|
||||||
.disable_preflight()
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::default().method(Method::GET).to_srv_request();
|
let req = TestRequest::default().method(Method::GET).to_srv_request();
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert!(resp
|
assert!(resp
|
||||||
.headers()
|
.headers()
|
||||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||||
.method(Method::OPTIONS)
|
.method(Method::OPTIONS)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&b"https://www.example.com"[..],
|
&b"https://www.example.com"[..],
|
||||||
resp.headers()
|
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::<Vec<&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)
|
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
.unwrap()
|
.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()
|
.to_str()
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.split(',')
|
||||||
|
.map(|s| s.trim())
|
||||||
|
.collect::<Vec<&str>>();
|
||||||
|
|
||||||
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]
|
#[actix_rt::test]
|
||||||
fn test_multiple_origins() {
|
async fn test_multiple_origins() {
|
||||||
block_on(async {
|
let mut cors = Cors::new()
|
||||||
let mut cors = Cors::new()
|
.allowed_origin("https://example.com")
|
||||||
.allowed_origin("https://example.com")
|
.allowed_origin("https://example.org")
|
||||||
.allowed_origin("https://example.org")
|
.allowed_methods(vec![Method::GET])
|
||||||
.allowed_methods(vec![Method::GET])
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://example.com")
|
let req = TestRequest::with_header("Origin", "https://example.com")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&b"https://example.com"[..],
|
&b"https://example.com"[..],
|
||||||
resp.headers()
|
resp.headers()
|
||||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
);
|
);
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://example.org")
|
let req = TestRequest::with_header("Origin", "https://example.org")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&b"https://example.org"[..],
|
&b"https://example.org"[..],
|
||||||
resp.headers()
|
resp.headers()
|
||||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_multiple_origins_preflight() {
|
async fn test_multiple_origins_preflight() {
|
||||||
block_on(async {
|
let mut cors = Cors::new()
|
||||||
let mut cors = Cors::new()
|
.allowed_origin("https://example.com")
|
||||||
.allowed_origin("https://example.com")
|
.allowed_origin("https://example.org")
|
||||||
.allowed_origin("https://example.org")
|
.allowed_methods(vec![Method::GET])
|
||||||
.allowed_methods(vec![Method::GET])
|
.finish()
|
||||||
.finish()
|
.new_transform(test::ok_service())
|
||||||
.new_transform(test::ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://example.com")
|
let req = TestRequest::with_header("Origin", "https://example.com")
|
||||||
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET")
|
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET")
|
||||||
.method(Method::OPTIONS)
|
.method(Method::OPTIONS)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&b"https://example.com"[..],
|
&b"https://example.com"[..],
|
||||||
resp.headers()
|
resp.headers()
|
||||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
);
|
);
|
||||||
|
|
||||||
let req = TestRequest::with_header("Origin", "https://example.org")
|
let req = TestRequest::with_header("Origin", "https://example.org")
|
||||||
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET")
|
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "GET")
|
||||||
.method(Method::OPTIONS)
|
.method(Method::OPTIONS)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
|
|
||||||
let resp = test::call_service(&mut cors, req).await;
|
let resp = test::call_service(&mut cors, req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&b"https://example.org"[..],
|
&b"https://example.org"[..],
|
||||||
resp.headers()
|
resp.headers()
|
||||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,4 +32,5 @@ percent-encoding = "2.1"
|
|||||||
v_htmlescape = "0.4"
|
v_htmlescape = "0.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
actix-rt = "1.0.0-alpha.1"
|
||||||
actix-web = { version = "2.0.0-alpha.1", features=["openssl"] }
|
actix-web = { version = "2.0.0-alpha.1", features=["openssl"] }
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,6 @@ use actix_http::http::header::{Header, HeaderName, IntoHeaderValue};
|
|||||||
use actix_http::http::{HttpTryFrom, Method, Uri, Version};
|
use actix_http::http::{HttpTryFrom, Method, Uri, Version};
|
||||||
use actix_http::test::{TestBuffer, TestRequest as HttpTestRequest};
|
use actix_http::test::{TestBuffer, TestRequest as HttpTestRequest};
|
||||||
use actix_router::{Path, Url};
|
use actix_router::{Path, Url};
|
||||||
use actix_rt::Runtime;
|
|
||||||
|
|
||||||
use crate::{FramedRequest, State};
|
use crate::{FramedRequest, State};
|
||||||
|
|
||||||
@ -119,13 +118,12 @@ impl<S> TestRequest<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This method generates `FramedRequest` instance and executes async handler
|
/// 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
|
where
|
||||||
F: FnOnce(FramedRequest<TestBuffer, S>) -> R,
|
F: FnOnce(FramedRequest<TestBuffer, S>) -> R,
|
||||||
R: Future<Output = Result<I, E>>,
|
R: Future<Output = Result<I, E>>,
|
||||||
{
|
{
|
||||||
let mut rt = Runtime::new().unwrap();
|
f(self.finish()).await
|
||||||
rt.block_on(f(self.finish()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
use actix_http::{body, http::StatusCode, ws, Error, HttpService, Response};
|
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_service::{pipeline_factory, IntoServiceFactory, ServiceFactory};
|
||||||
use actix_utils::framed::FramedTransport;
|
use actix_utils::framed::FramedTransport;
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
@ -38,126 +38,121 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
|||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_simple() {
|
async fn test_simple() {
|
||||||
block_on(async {
|
let mut srv = TestServer::start(|| {
|
||||||
let mut srv = TestServer::start(|| {
|
HttpService::build()
|
||||||
HttpService::build()
|
.upgrade(
|
||||||
.upgrade(
|
FramedApp::new().service(FramedRoute::get("/index.html").to(ws_service)),
|
||||||
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(|_| ()),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
});
|
.finish(|_| future::ok::<_, Error>(Response::NotFound()))
|
||||||
|
});
|
||||||
|
|
||||||
// non ws request
|
assert!(srv.ws_at("/test").await.is_err());
|
||||||
let res = srv.get("/index.html").send().await.unwrap();
|
|
||||||
assert_eq!(res.status(), StatusCode::BAD_REQUEST);
|
|
||||||
|
|
||||||
// not found
|
// client service
|
||||||
assert!(srv.ws_at("/test").await.is_err());
|
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
|
framed
|
||||||
let mut framed = srv.ws_at("/index.html").await.unwrap();
|
.send(ws::Message::Binary("text".into()))
|
||||||
framed
|
.await
|
||||||
.send(ws::Message::Text("text".to_string()))
|
.unwrap();
|
||||||
.await
|
let (item, mut framed) = framed.into_future().await;
|
||||||
.unwrap();
|
assert_eq!(
|
||||||
let (item, mut framed) = framed.into_future().await;
|
item.unwrap().unwrap(),
|
||||||
assert_eq!(
|
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
|
||||||
item.unwrap().unwrap(),
|
);
|
||||||
ws::Frame::Text(Some(BytesMut::from("text")))
|
|
||||||
);
|
|
||||||
|
|
||||||
framed
|
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||||
.send(ws::Message::Binary("text".into()))
|
let (item, mut framed) = framed.into_future().await;
|
||||||
.await
|
assert_eq!(
|
||||||
.unwrap();
|
item.unwrap().unwrap(),
|
||||||
let (item, mut framed) = framed.into_future().await;
|
ws::Frame::Pong("text".to_string().into())
|
||||||
assert_eq!(
|
);
|
||||||
item.unwrap().unwrap(),
|
|
||||||
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
|
|
||||||
);
|
|
||||||
|
|
||||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
framed
|
||||||
let (item, mut framed) = framed.into_future().await;
|
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
||||||
assert_eq!(
|
.await
|
||||||
item.unwrap().unwrap(),
|
.unwrap();
|
||||||
ws::Frame::Pong("text".to_string().into())
|
|
||||||
);
|
|
||||||
|
|
||||||
framed
|
let (item, _) = framed.into_future().await;
|
||||||
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
assert_eq!(
|
||||||
.await
|
item.unwrap().unwrap(),
|
||||||
.unwrap();
|
ws::Frame::Close(Some(ws::CloseCode::Normal.into()))
|
||||||
|
);
|
||||||
let (item, _) = framed.into_future().await;
|
}
|
||||||
assert_eq!(
|
|
||||||
item.unwrap().unwrap(),
|
#[actix_rt::test]
|
||||||
ws::Frame::Close(Some(ws::CloseCode::Normal.into()))
|
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()))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ default = []
|
|||||||
openssl = ["open-ssl", "actix-connect/openssl", "tokio-openssl"]
|
openssl = ["open-ssl", "actix-connect/openssl", "tokio-openssl"]
|
||||||
|
|
||||||
# rustls support
|
# rustls support
|
||||||
# rustls = ["rust-tls", "webpki-roots", "actix-connect/rustls"]
|
rustls = ["rust-tls", "webpki-roots", "actix-connect/rustls"]
|
||||||
|
|
||||||
# brotli encoding, requires c compiler
|
# brotli encoding, requires c compiler
|
||||||
brotli = ["brotli2"]
|
brotli = ["brotli2"]
|
||||||
@ -52,6 +52,7 @@ actix-codec = "0.2.0-alpha.1"
|
|||||||
actix-connect = "1.0.0-alpha.1"
|
actix-connect = "1.0.0-alpha.1"
|
||||||
actix-utils = "0.5.0-alpha.1"
|
actix-utils = "0.5.0-alpha.1"
|
||||||
actix-server-config = "0.3.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"
|
actix-threadpool = "0.2.0-alpha.1"
|
||||||
|
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
@ -83,11 +84,7 @@ slab = "0.4"
|
|||||||
serde_urlencoded = "0.6.1"
|
serde_urlencoded = "0.6.1"
|
||||||
time = "0.1.42"
|
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-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 }
|
trust-dns-resolver = { version="0.18.0-alpha.1", default-features = false }
|
||||||
|
|
||||||
# for secure cookie
|
# for secure cookie
|
||||||
@ -106,8 +103,7 @@ rust-tls = { version = "0.16.0", package="rustls", optional = true }
|
|||||||
webpki-roots = { version = "0.18", optional = true }
|
webpki-roots = { version = "0.18", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "1.0.0-alpha.1"
|
actix-server = { version = "0.8.0-alpha.1", features=["openssl", "rustls"] }
|
||||||
actix-server = { version = "0.8.0-alpha.1", features=["openssl"] }
|
|
||||||
actix-connect = { version = "1.0.0-alpha.1", features=["openssl"] }
|
actix-connect = { version = "1.0.0-alpha.1", features=["openssl"] }
|
||||||
actix-http-test = { version = "0.3.0-alpha.1", features=["openssl"] }
|
actix-http-test = { version = "0.3.0-alpha.1", features=["openssl"] }
|
||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
|
@ -432,8 +432,7 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_http_test::block_on;
|
use futures::future::poll_fn;
|
||||||
use futures::future::{lazy, poll_fn};
|
|
||||||
|
|
||||||
impl Body {
|
impl Body {
|
||||||
pub(crate) fn get_ref(&self) -> &[u8] {
|
pub(crate) fn get_ref(&self) -> &[u8] {
|
||||||
@ -453,21 +452,21 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_static_str() {
|
async fn test_static_str() {
|
||||||
assert_eq!(Body::from("").size(), BodySize::Sized(0));
|
assert_eq!(Body::from("").size(), BodySize::Sized(0));
|
||||||
assert_eq!(Body::from("test").size(), BodySize::Sized(4));
|
assert_eq!(Body::from("test").size(), BodySize::Sized(4));
|
||||||
assert_eq!(Body::from("test").get_ref(), b"test");
|
assert_eq!(Body::from("test").get_ref(), b"test");
|
||||||
|
|
||||||
assert_eq!("test".size(), BodySize::Sized(4));
|
assert_eq!("test".size(), BodySize::Sized(4));
|
||||||
assert_eq!(
|
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"))
|
Some(Bytes::from("test"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_static_bytes() {
|
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()).size(), BodySize::Sized(4));
|
||||||
assert_eq!(Body::from(b"test".as_ref()).get_ref(), b"test");
|
assert_eq!(Body::from(b"test".as_ref()).get_ref(), b"test");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -478,55 +477,57 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!((&b"test"[..]).size(), BodySize::Sized(4));
|
assert_eq!((&b"test"[..]).size(), BodySize::Sized(4));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
block_on(poll_fn(|cx| (&b"test"[..]).poll_next(cx)))
|
poll_fn(|cx| (&b"test"[..]).poll_next(cx))
|
||||||
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.ok(),
|
.ok(),
|
||||||
Some(Bytes::from("test"))
|
Some(Bytes::from("test"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_vec() {
|
async fn test_vec() {
|
||||||
assert_eq!(Body::from(Vec::from("test")).size(), BodySize::Sized(4));
|
assert_eq!(Body::from(Vec::from("test")).size(), BodySize::Sized(4));
|
||||||
assert_eq!(Body::from(Vec::from("test")).get_ref(), b"test");
|
assert_eq!(Body::from(Vec::from("test")).get_ref(), b"test");
|
||||||
|
|
||||||
assert_eq!(Vec::from("test").size(), BodySize::Sized(4));
|
assert_eq!(Vec::from("test").size(), BodySize::Sized(4));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
block_on(poll_fn(|cx| Vec::from("test").poll_next(cx)))
|
poll_fn(|cx| Vec::from("test").poll_next(cx))
|
||||||
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.ok(),
|
.ok(),
|
||||||
Some(Bytes::from("test"))
|
Some(Bytes::from("test"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_bytes() {
|
async fn test_bytes() {
|
||||||
let mut b = Bytes::from("test");
|
let mut b = Bytes::from("test");
|
||||||
assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4));
|
assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4));
|
||||||
assert_eq!(Body::from(b.clone()).get_ref(), b"test");
|
assert_eq!(Body::from(b.clone()).get_ref(), b"test");
|
||||||
|
|
||||||
assert_eq!(b.size(), BodySize::Sized(4));
|
assert_eq!(b.size(), BodySize::Sized(4));
|
||||||
assert_eq!(
|
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"))
|
Some(Bytes::from("test"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_bytes_mut() {
|
async fn test_bytes_mut() {
|
||||||
let mut b = BytesMut::from("test");
|
let mut b = BytesMut::from("test");
|
||||||
assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4));
|
assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4));
|
||||||
assert_eq!(Body::from(b.clone()).get_ref(), b"test");
|
assert_eq!(Body::from(b.clone()).get_ref(), b"test");
|
||||||
|
|
||||||
assert_eq!(b.size(), BodySize::Sized(4));
|
assert_eq!(b.size(), BodySize::Sized(4));
|
||||||
assert_eq!(
|
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"))
|
Some(Bytes::from("test"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_string() {
|
async fn test_string() {
|
||||||
let mut b = "test".to_owned();
|
let mut b = "test".to_owned();
|
||||||
assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4));
|
assert_eq!(Body::from(b.clone()).size(), BodySize::Sized(4));
|
||||||
assert_eq!(Body::from(b.clone()).get_ref(), b"test");
|
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!(b.size(), BodySize::Sized(4));
|
||||||
assert_eq!(
|
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"))
|
Some(Bytes::from("test"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_unit() {
|
async fn test_unit() {
|
||||||
assert_eq!(().size(), BodySize::Empty);
|
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]
|
#[actix_rt::test]
|
||||||
fn test_box() {
|
async fn test_box() {
|
||||||
let mut val = Box::new(());
|
let mut val = Box::new(());
|
||||||
assert_eq!(val.size(), BodySize::Empty);
|
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]
|
#[actix_rt::test]
|
||||||
fn test_body_eq() {
|
async fn test_body_eq() {
|
||||||
assert!(Body::None == Body::None);
|
assert!(Body::None == Body::None);
|
||||||
assert!(Body::None != Body::Empty);
|
assert!(Body::None != Body::Empty);
|
||||||
assert!(Body::Empty == Body::Empty);
|
assert!(Body::Empty == Body::Empty);
|
||||||
@ -566,15 +567,15 @@ mod tests {
|
|||||||
assert!(Body::Bytes(Bytes::from_static(b"1")) != Body::None);
|
assert!(Body::Bytes(Bytes::from_static(b"1")) != Body::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_body_debug() {
|
async fn test_body_debug() {
|
||||||
assert!(format!("{:?}", Body::None).contains("Body::None"));
|
assert!(format!("{:?}", Body::None).contains("Body::None"));
|
||||||
assert!(format!("{:?}", Body::Empty).contains("Body::Empty"));
|
assert!(format!("{:?}", Body::Empty).contains("Body::Empty"));
|
||||||
assert!(format!("{:?}", Body::Bytes(Bytes::from_static(b"1"))).contains("1"));
|
assert!(format!("{:?}", Body::Bytes(Bytes::from_static(b"1"))).contains("1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_serde_json() {
|
async fn test_serde_json() {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Body::from(serde_json::Value::String("test".into())).size(),
|
Body::from(serde_json::Value::String("test".into())).size(),
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::future::Future;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
|
||||||
use std::task::{Context, Poll};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
@ -11,7 +8,6 @@ use actix_connect::{
|
|||||||
};
|
};
|
||||||
use actix_service::{apply_fn, Service};
|
use actix_service::{apply_fn, Service};
|
||||||
use actix_utils::timeout::{TimeoutError, TimeoutService};
|
use actix_utils::timeout::{TimeoutError, TimeoutService};
|
||||||
use futures::future::Ready;
|
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
use tokio_net::tcp::TcpStream;
|
use tokio_net::tcp::TcpStream;
|
||||||
|
|
||||||
@ -344,7 +340,6 @@ mod connect_impl {
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use futures::future::{err, Either, Ready};
|
use futures::future::{err, Either, Ready};
|
||||||
use futures::ready;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::client::connection::IoConnection;
|
use crate::client::connection::IoConnection;
|
||||||
@ -402,7 +397,10 @@ mod connect_impl {
|
|||||||
|
|
||||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||||
mod connect_impl {
|
mod connect_impl {
|
||||||
|
use std::future::Future;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use futures::future::Either;
|
use futures::future::Either;
|
||||||
use futures::ready;
|
use futures::ready;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@ -6,8 +5,8 @@ use std::{io, time};
|
|||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
use futures::future::{ok, poll_fn, Either};
|
use futures::future::poll_fn;
|
||||||
use futures::{Sink, SinkExt, Stream, StreamExt};
|
use futures::{SinkExt, Stream, StreamExt};
|
||||||
|
|
||||||
use crate::error::PayloadError;
|
use crate::error::PayloadError;
|
||||||
use crate::h1;
|
use crate::h1;
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::task::{Context, Poll};
|
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::future::{err, poll_fn, Either};
|
use futures::future::poll_fn;
|
||||||
use h2::{client::SendRequest, SendStream};
|
use h2::{client::SendRequest, SendStream};
|
||||||
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING};
|
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING};
|
||||||
use http::{request::Request, HttpTryFrom, Method, Version};
|
use http::{request::Request, HttpTryFrom, Method, Version};
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
|
use actix_rt::time::{delay_for, Delay};
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
use actix_utils::{oneshot, task::LocalWaker};
|
use actix_utils::{oneshot, task::LocalWaker};
|
||||||
use bytes::Bytes;
|
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 h2::client::{handshake, Connection, SendRequest};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use http::uri::Authority;
|
use http::uri::Authority;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
use tokio_timer::{delay_for, Delay};
|
|
||||||
|
|
||||||
use super::connection::{ConnectionType, IoConnection};
|
use super::connection::{ConnectionType, IoConnection};
|
||||||
use super::error::ConnectError;
|
use super::error::ConnectError;
|
||||||
@ -100,7 +99,7 @@ where
|
|||||||
|
|
||||||
fn call(&mut self, req: Connect) -> Self::Future {
|
fn call(&mut self, req: Connect) -> Self::Future {
|
||||||
// start support future
|
// start support future
|
||||||
tokio_executor::current_thread::spawn(ConnectorPoolSupport {
|
actix_rt::spawn(ConnectorPoolSupport {
|
||||||
connector: self.0.clone(),
|
connector: self.0.clone(),
|
||||||
inner: self.1.clone(),
|
inner: self.1.clone(),
|
||||||
});
|
});
|
||||||
@ -139,7 +138,7 @@ where
|
|||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let (snd, connection) = handshake(io).await?;
|
let (snd, connection) = handshake(io).await?;
|
||||||
tokio_executor::current_thread::spawn(connection.map(|_| ()));
|
actix_rt::spawn(connection.map(|_| ()));
|
||||||
Ok(IoConnection::new(
|
Ok(IoConnection::new(
|
||||||
ConnectionType::H2(snd),
|
ConnectionType::H2(snd),
|
||||||
Instant::now(),
|
Instant::now(),
|
||||||
@ -328,9 +327,7 @@ where
|
|||||||
{
|
{
|
||||||
if let Some(timeout) = self.disconnect_timeout {
|
if let Some(timeout) = self.disconnect_timeout {
|
||||||
if let ConnectionType::H1(io) = conn.io {
|
if let ConnectionType::H1(io) = conn.io {
|
||||||
tokio_executor::current_thread::spawn(CloseConnection::new(
|
actix_rt::spawn(CloseConnection::new(io, timeout))
|
||||||
io, timeout,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -342,9 +339,9 @@ where
|
|||||||
Poll::Ready(Ok(n)) if n > 0 => {
|
Poll::Ready(Ok(n)) if n > 0 => {
|
||||||
if let Some(timeout) = self.disconnect_timeout {
|
if let Some(timeout) = self.disconnect_timeout {
|
||||||
if let ConnectionType::H1(io) = io {
|
if let ConnectionType::H1(io) = io {
|
||||||
tokio_executor::current_thread::spawn(
|
actix_rt::spawn(CloseConnection::new(
|
||||||
CloseConnection::new(io, timeout),
|
io, timeout,
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -376,7 +373,7 @@ where
|
|||||||
self.acquired -= 1;
|
self.acquired -= 1;
|
||||||
if let Some(timeout) = self.disconnect_timeout {
|
if let Some(timeout) = self.disconnect_timeout {
|
||||||
if let ConnectionType::H1(io) = io {
|
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();
|
self.check_availibility();
|
||||||
@ -518,7 +515,7 @@ where
|
|||||||
inner: Rc<RefCell<Inner<Io>>>,
|
inner: Rc<RefCell<Inner<Io>>>,
|
||||||
fut: F,
|
fut: F,
|
||||||
) {
|
) {
|
||||||
tokio_executor::current_thread::spawn(OpenWaitingConnection {
|
actix_rt::spawn(OpenWaitingConnection {
|
||||||
key,
|
key,
|
||||||
fut,
|
fut,
|
||||||
h2: None,
|
h2: None,
|
||||||
@ -554,7 +551,7 @@ where
|
|||||||
if let Some(ref mut h2) = this.h2 {
|
if let Some(ref mut h2) = this.h2 {
|
||||||
return match Pin::new(h2).poll(cx) {
|
return match Pin::new(h2).poll(cx) {
|
||||||
Poll::Ready(Ok((snd, connection))) => {
|
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 = this.rx.take().unwrap();
|
||||||
let _ = rx.send(Ok(IoConnection::new(
|
let _ = rx.send(Ok(IoConnection::new(
|
||||||
ConnectionType::H2(snd),
|
ConnectionType::H2(snd),
|
||||||
|
@ -4,10 +4,10 @@ use std::fmt::Write;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use actix_rt::time::{delay, delay_for, Delay};
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use futures::{future, Future, FutureExt};
|
use futures::{future, FutureExt};
|
||||||
use time;
|
use time;
|
||||||
use tokio_timer::{delay, delay_for, Delay};
|
|
||||||
|
|
||||||
// "Sun, 06 Nov 1994 08:49:37 GMT".len()
|
// "Sun, 06 Nov 1994 08:49:37 GMT".len()
|
||||||
const DATE_VALUE_LENGTH: usize = 29;
|
const DATE_VALUE_LENGTH: usize = 29;
|
||||||
@ -242,12 +242,10 @@ impl DateService {
|
|||||||
|
|
||||||
// periodic date update
|
// periodic date update
|
||||||
let s = self.clone();
|
let s = self.clone();
|
||||||
tokio_executor::current_thread::spawn(
|
actix_rt::spawn(delay_for(Duration::from_millis(500)).then(move |_| {
|
||||||
delay_for(Duration::from_millis(500)).then(move |_| {
|
s.0.reset();
|
||||||
s.0.reset();
|
future::ready(())
|
||||||
future::ready(())
|
}));
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,26 +263,19 @@ impl DateService {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_rt::System;
|
|
||||||
use futures::future;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_date_len() {
|
fn test_date_len() {
|
||||||
assert_eq!(DATE_VALUE_LENGTH, "Sun, 06 Nov 1994 08:49:37 GMT".len());
|
assert_eq!(DATE_VALUE_LENGTH, "Sun, 06 Nov 1994 08:49:37 GMT".len());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_date() {
|
async fn test_date() {
|
||||||
let mut rt = System::new("test");
|
let settings = ServiceConfig::new(KeepAlive::Os, 0, 0);
|
||||||
|
let mut buf1 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
|
||||||
let _ = rt.block_on(future::lazy(|_| {
|
settings.set_date(&mut buf1);
|
||||||
let settings = ServiceConfig::new(KeepAlive::Os, 0, 0);
|
let mut buf2 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
|
||||||
let mut buf1 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
|
settings.set_date(&mut buf2);
|
||||||
settings.set_date(&mut buf1);
|
assert_eq!(buf1, buf2);
|
||||||
let mut buf2 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
|
|
||||||
settings.set_date(&mut buf2);
|
|
||||||
assert_eq!(buf1, buf2);
|
|
||||||
future::ok::<_, ()>(())
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use ring::hkdf::{Algorithm, KeyType, Prk, HKDF_SHA256};
|
use ring::hkdf::{Algorithm, KeyType, Prk, HKDF_SHA256};
|
||||||
use ring::hmac;
|
|
||||||
use ring::rand::{SecureRandom, SystemRandom};
|
use ring::rand::{SecureRandom, SystemRandom};
|
||||||
|
|
||||||
use super::private::KEY_LEN as PRIVATE_KEY_LEN;
|
use super::private::KEY_LEN as PRIVATE_KEY_LEN;
|
||||||
|
@ -16,7 +16,6 @@ use httparse;
|
|||||||
use serde::de::value::Error as DeError;
|
use serde::de::value::Error as DeError;
|
||||||
use serde_json::error::Error as JsonError;
|
use serde_json::error::Error as JsonError;
|
||||||
use serde_urlencoded::ser::Error as FormError;
|
use serde_urlencoded::ser::Error as FormError;
|
||||||
use tokio_timer::Error as TimerError;
|
|
||||||
|
|
||||||
// re-export for convinience
|
// re-export for convinience
|
||||||
use crate::body::Body;
|
use crate::body::Body;
|
||||||
@ -178,9 +177,6 @@ impl ResponseError for JsonError {}
|
|||||||
/// `InternalServerError` for `FormError`
|
/// `InternalServerError` for `FormError`
|
||||||
impl ResponseError for FormError {}
|
impl ResponseError for FormError {}
|
||||||
|
|
||||||
/// `InternalServerError` for `TimerError`
|
|
||||||
impl ResponseError for TimerError {}
|
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
/// `InternalServerError` for `openssl::ssl::Error`
|
/// `InternalServerError` for `openssl::ssl::Error`
|
||||||
impl ResponseError for open_ssl::ssl::Error {}
|
impl ResponseError for open_ssl::ssl::Error {}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::pin::Pin;
|
use std::task::Poll;
|
||||||
use std::task::{Context, Poll};
|
|
||||||
|
|
||||||
use actix_codec::Decoder;
|
use actix_codec::Decoder;
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
@ -3,15 +3,15 @@ use std::future::Future;
|
|||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::Instant;
|
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_server_config::IoStream;
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use bytes::{BufMut, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
use log::{error, trace};
|
use log::{error, trace};
|
||||||
use tokio_timer::{delay, Delay};
|
|
||||||
|
|
||||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||||
use crate::cloneable::CloneableService;
|
use crate::cloneable::CloneableService;
|
||||||
@ -893,10 +893,9 @@ mod tests {
|
|||||||
use crate::h1::{ExpectHandler, UpgradeHandler};
|
use crate::h1::{ExpectHandler, UpgradeHandler};
|
||||||
use crate::test::TestBuffer;
|
use crate::test::TestBuffer;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_req_parse_err() {
|
async fn test_req_parse_err() {
|
||||||
let mut sys = actix_rt::System::new("test");
|
lazy(|cx| {
|
||||||
let _ = sys.block_on(lazy(|cx| {
|
|
||||||
let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n");
|
let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n");
|
||||||
|
|
||||||
let mut h1 = Dispatcher::<_, _, _, _, UpgradeHandler<TestBuffer>>::new(
|
let mut h1 = Dispatcher::<_, _, _, _, UpgradeHandler<TestBuffer>>::new(
|
||||||
@ -918,7 +917,7 @@ mod tests {
|
|||||||
assert!(inner.flags.contains(Flags::READ_DISCONNECT));
|
assert!(inner.flags.contains(Flags::READ_DISCONNECT));
|
||||||
assert_eq!(&inner.io.write_buf[..26], b"HTTP/1.1 400 Bad Request\r\n");
|
assert_eq!(&inner.io.write_buf[..26], b"HTTP/1.1 400 Bad Request\r\n");
|
||||||
}
|
}
|
||||||
ok::<_, ()>(())
|
})
|
||||||
}));
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_server_config::ServerConfig;
|
use actix_server_config::ServerConfig;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! Payload stream
|
//! Payload stream
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@ -227,24 +226,19 @@ impl Inner {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_rt::Runtime;
|
use futures::future::poll_fn;
|
||||||
use futures::future::{poll_fn, ready};
|
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_unread_data() {
|
async fn test_unread_data() {
|
||||||
Runtime::new().unwrap().block_on(async {
|
let (_, mut payload) = Payload::create(false);
|
||||||
let (_, mut payload) = Payload::create(false);
|
|
||||||
|
|
||||||
payload.unread_data(Bytes::from("data"));
|
payload.unread_data(Bytes::from("data"));
|
||||||
assert!(!payload.is_empty());
|
assert!(!payload.is_empty());
|
||||||
assert_eq!(payload.len(), 4);
|
assert_eq!(payload.len(), 4);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bytes::from("data"),
|
Bytes::from("data"),
|
||||||
poll_fn(|cx| payload.readany(cx)).await.unwrap().unwrap()
|
poll_fn(|cx| payload.readany(cx)).await.unwrap().unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
ready(())
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use actix_codec::Framed;
|
|||||||
use actix_server_config::{Io, IoStream, ServerConfig as SrvConfig};
|
use actix_server_config::{Io, IoStream, ServerConfig as SrvConfig};
|
||||||
use actix_service::{IntoServiceFactory, Service, ServiceFactory};
|
use actix_service::{IntoServiceFactory, Service, ServiceFactory};
|
||||||
use futures::future::{ok, Ready};
|
use futures::future::{ok, Ready};
|
||||||
use futures::{ready, Stream};
|
use futures::ready;
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use crate::body::MessageBody;
|
||||||
use crate::cloneable::CloneableService;
|
use crate::cloneable::CloneableService;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_codec::Framed;
|
use actix_codec::Framed;
|
||||||
|
@ -3,7 +3,6 @@ use std::pin::Pin;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||||
use futures::Sink;
|
|
||||||
|
|
||||||
use crate::body::{BodySize, MessageBody, ResponseBody};
|
use crate::body::{BodySize, MessageBody, ResponseBody};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
@ -7,6 +7,7 @@ use std::time::Instant;
|
|||||||
use std::{fmt, mem, net};
|
use std::{fmt, mem, net};
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
|
use actix_rt::time::Delay;
|
||||||
use actix_server_config::IoStream;
|
use actix_server_config::IoStream;
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
@ -19,7 +20,6 @@ use http::header::{
|
|||||||
};
|
};
|
||||||
use http::HttpTryFrom;
|
use http::HttpTryFrom;
|
||||||
use log::{debug, error, trace};
|
use log::{debug, error, trace};
|
||||||
use tokio_timer::Delay;
|
|
||||||
|
|
||||||
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
use crate::body::{Body, BodySize, MessageBody, ResponseBody};
|
||||||
use crate::cloneable::CloneableService;
|
use crate::cloneable::CloneableService;
|
||||||
@ -139,7 +139,7 @@ where
|
|||||||
on_connect.set(&mut req.extensions_mut());
|
on_connect.set(&mut req.extensions_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio_executor::current_thread::spawn(ServiceResponse::<
|
actix_rt::spawn(ServiceResponse::<
|
||||||
S::Future,
|
S::Future,
|
||||||
S::Response,
|
S::Response,
|
||||||
S::Error,
|
S::Error,
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
clippy::too_many_arguments,
|
clippy::too_many_arguments,
|
||||||
clippy::new_without_default,
|
clippy::new_without_default,
|
||||||
clippy::borrow_interior_mutable_const,
|
clippy::borrow_interior_mutable_const,
|
||||||
clippy::write_with_newline,
|
clippy::write_with_newline
|
||||||
unused_imports
|
|
||||||
)]
|
)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ use std::task::{Context, Poll};
|
|||||||
use std::{fmt, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
use futures::future::{ok, Ready};
|
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
@ -8,7 +8,7 @@ use actix_server_config::{
|
|||||||
Io as ServerIo, IoStream, Protocol, ServerConfig as SrvConfig,
|
Io as ServerIo, IoStream, Protocol, ServerConfig as SrvConfig,
|
||||||
};
|
};
|
||||||
use actix_service::{IntoServiceFactory, Service, ServiceFactory};
|
use actix_service::{IntoServiceFactory, Service, ServiceFactory};
|
||||||
use bytes::{Buf, BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
use futures::{ready, Future};
|
use futures::{ready, Future};
|
||||||
use h2::server::{self, Handshake};
|
use h2::server::{self, Handshake};
|
||||||
use pin_project::{pin_project, project};
|
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(
|
fn poll_write(
|
||||||
self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
|
@ -7,7 +7,7 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
use actix_server_config::IoStream;
|
use actix_server_config::IoStream;
|
||||||
use bytes::{Buf, Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use http::header::{self, HeaderName, HeaderValue};
|
use http::header::{self, HeaderName, HeaderValue};
|
||||||
use http::{HttpTryFrom, Method, Uri, Version};
|
use http::{HttpTryFrom, Method, Uri, Version};
|
||||||
use percent_encoding::percent_encode;
|
use percent_encoding::percent_encode;
|
||||||
|
@ -3,7 +3,7 @@ use bytes::Bytes;
|
|||||||
use futures::future::{self, ok};
|
use futures::future::{self, ok};
|
||||||
|
|
||||||
use actix_http::{http, HttpService, Request, Response};
|
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 \
|
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 \
|
||||||
@ -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 \
|
||||||
Hello World Hello World Hello World Hello World Hello World";
|
Hello World Hello World Hello World Hello World Hello World";
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h1_v2() {
|
async fn test_h1_v2() {
|
||||||
block_on(async {
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
HttpService::build().finish(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
HttpService::build()
|
});
|
||||||
.finish(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.get("/").send().await.unwrap();
|
let response = srv.get("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let request = srv.get("/").header("x-test", "111").send();
|
let request = srv.get("/").header("x-test", "111").send();
|
||||||
let mut response = request.await.unwrap();
|
let mut response = request.await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = response.body().await.unwrap();
|
let bytes = response.body().await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||||
|
|
||||||
let mut response = srv.post("/").send().await.unwrap();
|
let mut response = srv.post("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = response.body().await.unwrap();
|
let bytes = response.body().await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_connection_close() {
|
async fn test_connection_close() {
|
||||||
block_on(async {
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
HttpService::build()
|
||||||
HttpService::build()
|
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
.map(|_| ())
|
||||||
.map(|_| ())
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.get("/").force_close().send().await.unwrap();
|
let response = srv.get("/").force_close().send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_with_query_parameter() {
|
async fn test_with_query_parameter() {
|
||||||
block_on(async {
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
HttpService::build()
|
||||||
HttpService::build()
|
.finish(|req: Request| {
|
||||||
.finish(|req: Request| {
|
if req.uri().query().unwrap().contains("qp=") {
|
||||||
if req.uri().query().unwrap().contains("qp=") {
|
ok::<_, ()>(Response::Ok().finish())
|
||||||
ok::<_, ()>(Response::Ok().finish())
|
} else {
|
||||||
} else {
|
ok::<_, ()>(Response::BadRequest().finish())
|
||||||
ok::<_, ()>(Response::BadRequest().finish())
|
}
|
||||||
}
|
})
|
||||||
})
|
.map(|_| ())
|
||||||
.map(|_| ())
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let request = srv.request(http::Method::GET, srv.url("/?qp=5"));
|
let request = srv.request(http::Method::GET, srv.url("/?qp=5"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
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::ssl::OpensslAcceptor;
|
||||||
use actix_server_config::ServerConfig;
|
use actix_server_config::ServerConfig;
|
||||||
use actix_service::{factory_fn_cfg, pipeline_factory, service_fn2, ServiceFactory};
|
use actix_service::{factory_fn_cfg, pipeline_factory, service_fn2, ServiceFactory};
|
||||||
@ -57,156 +57,147 @@ fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> io::Result<OpensslAcceptor<T, ()
|
|||||||
Ok(OpensslAcceptor::new(builder.build()))
|
Ok(OpensslAcceptor::new(builder.build()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2() -> io::Result<()> {
|
async fn test_h2() -> io::Result<()> {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor()?;
|
||||||
let openssl = ssl_acceptor()?;
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| ok::<_, Error>(Response::Ok().finish()))
|
||||||
.h2(|_| ok::<_, Error>(Response::Ok().finish()))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_1() -> io::Result<()> {
|
async fn test_h2_1() -> io::Result<()> {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor()?;
|
||||||
let openssl = ssl_acceptor()?;
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.finish(|req: Request| {
|
||||||
.finish(|req: Request| {
|
assert!(req.peer_addr().is_some());
|
||||||
assert!(req.peer_addr().is_some());
|
assert_eq!(req.version(), Version::HTTP_2);
|
||||||
assert_eq!(req.version(), Version::HTTP_2);
|
ok::<_, Error>(Response::Ok().finish())
|
||||||
ok::<_, Error>(Response::Ok().finish())
|
})
|
||||||
})
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_body() -> io::Result<()> {
|
async fn test_h2_body() -> io::Result<()> {
|
||||||
block_on(async {
|
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
||||||
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
let openssl = ssl_acceptor()?;
|
||||||
let openssl = ssl_acceptor()?;
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|mut req: Request<_>| {
|
||||||
.h2(|mut req: Request<_>| {
|
async move {
|
||||||
async move {
|
let body = load_body(req.take_payload()).await?;
|
||||||
let body = load_body(req.take_payload()).await?;
|
Ok::<_, Error>(Response::Ok().body(body))
|
||||||
Ok::<_, Error>(Response::Ok().body(body))
|
}
|
||||||
}
|
})
|
||||||
})
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send_body(data.clone()).await.unwrap();
|
let response = srv.sget("/").send_body(data.clone()).await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let body = srv.load_body(response).await.unwrap();
|
let body = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(&body, data.as_bytes());
|
assert_eq!(&body, data.as_bytes());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_content_length() {
|
async fn test_h2_content_length() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let srv = TestServer::start(move || {
|
let srv = TestServer::start(move || {
|
||||||
pipeline_factory(
|
pipeline_factory(
|
||||||
openssl
|
openssl
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
)
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.h2(|req: Request| {
|
.h2(|req: Request| {
|
||||||
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||||
let statuses = [
|
let statuses = [
|
||||||
StatusCode::NO_CONTENT,
|
StatusCode::NO_CONTENT,
|
||||||
StatusCode::CONTINUE,
|
StatusCode::CONTINUE,
|
||||||
StatusCode::SWITCHING_PROTOCOLS,
|
StatusCode::SWITCHING_PROTOCOLS,
|
||||||
StatusCode::PROCESSING,
|
StatusCode::PROCESSING,
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
StatusCode::NOT_FOUND,
|
StatusCode::NOT_FOUND,
|
||||||
];
|
];
|
||||||
ok::<_, ()>(Response::new(statuses[indx]))
|
ok::<_, ()>(Response::new(statuses[indx]))
|
||||||
})
|
})
|
||||||
.map_err(|_| ()),
|
.map_err(|_| ()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let header = HeaderName::from_static("content-length");
|
let header = HeaderName::from_static("content-length");
|
||||||
let value = HeaderValue::from_static("0");
|
let value = HeaderValue::from_static("0");
|
||||||
|
|
||||||
{
|
{
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
let req = srv
|
let req = srv
|
||||||
.request(Method::GET, srv.surl(&format!("/{}", i)))
|
.request(Method::GET, srv.surl(&format!("/{}", i)))
|
||||||
.send();
|
.send();
|
||||||
let response = req.await.unwrap();
|
let response = req.await.unwrap();
|
||||||
assert_eq!(response.headers().get(&header), None);
|
assert_eq!(response.headers().get(&header), None);
|
||||||
|
|
||||||
let req = srv
|
let req = srv
|
||||||
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
|
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
|
||||||
.send();
|
.send();
|
||||||
let response = req.await.unwrap();
|
let response = req.await.unwrap();
|
||||||
assert_eq!(response.headers().get(&header), None);
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
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]
|
#[actix_rt::test]
|
||||||
fn test_h2_headers() {
|
async fn test_h2_headers() {
|
||||||
block_on(async {
|
let data = STR.repeat(10);
|
||||||
let data = STR.repeat(10);
|
let data2 = data.clone();
|
||||||
let data2 = data.clone();
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let mut srv = TestServer::start(move || {
|
let mut srv = TestServer::start(move || {
|
||||||
let data = data.clone();
|
let data = data.clone();
|
||||||
pipeline_factory(openssl
|
pipeline_factory(openssl
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e)))
|
.map_err(|e| println!("Openssl error: {}", e)))
|
||||||
.and_then(
|
.and_then(
|
||||||
@ -232,15 +223,14 @@ fn test_h2_headers() {
|
|||||||
}
|
}
|
||||||
ok::<_, ()>(builder.body(data.clone()))
|
ok::<_, ()>(builder.body(data.clone()))
|
||||||
}).map_err(|_| ()))
|
}).map_err(|_| ()))
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from(data2));
|
assert_eq!(bytes, Bytes::from(data2));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
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 \
|
||||||
Hello World Hello World Hello World Hello World Hello World";
|
Hello World Hello World Hello World Hello World Hello World";
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_body2() {
|
async fn test_h2_body2() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_head_empty() {
|
async fn test_h2_head_empty() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.shead("/").send().await.unwrap();
|
let response = srv.shead("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
assert_eq!(response.version(), Version::HTTP_2);
|
assert_eq!(response.version(), Version::HTTP_2);
|
||||||
|
|
||||||
{
|
{
|
||||||
let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
|
let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
|
||||||
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert!(bytes.is_empty());
|
assert!(bytes.is_empty());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_head_binary() {
|
async fn test_h2_head_binary() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| {
|
||||||
.h2(|_| {
|
ok::<_, ()>(
|
||||||
ok::<_, ()>(
|
Response::Ok().content_length(STR.len() as u64).body(STR),
|
||||||
Response::Ok().content_length(STR.len() as u64).body(STR),
|
)
|
||||||
)
|
})
|
||||||
})
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.shead("/").send().await.unwrap();
|
let response = srv.shead("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
{
|
{
|
||||||
let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
|
let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
|
||||||
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert!(bytes.is_empty());
|
assert!(bytes.is_empty());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_head_binary2() {
|
async fn test_h2_head_binary2() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.shead("/").send().await.unwrap();
|
let response = srv.shead("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
{
|
{
|
||||||
let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
|
let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
|
||||||
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_body_length() {
|
async fn test_h2_body_length() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(
|
||||||
pipeline_factory(
|
openssl
|
||||||
openssl
|
.clone()
|
||||||
.clone()
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
)
|
||||||
)
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| {
|
||||||
.h2(|_| {
|
let body = once(ok(Bytes::from_static(STR.as_ref())));
|
||||||
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::<_, ()>(
|
ok::<_, ()>(
|
||||||
Response::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();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_service_error() {
|
async fn test_h2_service_error() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let mut srv = TestServer::start(move || {
|
let mut srv = TestServer::start(move || {
|
||||||
pipeline_factory(
|
pipeline_factory(
|
||||||
openssl
|
openssl
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
)
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.h2(|_| err::<Response, Error>(ErrorBadRequest("error")))
|
.h2(|_| err::<Response, Error>(ErrorBadRequest("error")))
|
||||||
.map_err(|_| ()),
|
.map_err(|_| ()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(b"error"));
|
assert_eq!(bytes, Bytes::from_static(b"error"));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_on_connect() {
|
async fn test_h2_on_connect() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let srv = TestServer::start(move || {
|
let srv = TestServer::start(move || {
|
||||||
pipeline_factory(
|
pipeline_factory(
|
||||||
openssl
|
openssl
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
)
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.on_connect(|_| 10usize)
|
.on_connect(|_| 10usize)
|
||||||
.h2(|req: Request| {
|
.h2(|req: Request| {
|
||||||
assert!(req.extensions().contains::<usize>());
|
assert!(req.extensions().contains::<usize>());
|
||||||
ok::<_, ()>(Response::Ok().finish())
|
ok::<_, ()>(Response::Ok().finish())
|
||||||
})
|
})
|
||||||
.map_err(|_| ()),
|
.map_err(|_| ()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use actix_http::error::PayloadError;
|
|||||||
use actix_http::http::header::{self, HeaderName, HeaderValue};
|
use actix_http::http::header::{self, HeaderName, HeaderValue};
|
||||||
use actix_http::http::{Method, StatusCode, Version};
|
use actix_http::http::{Method, StatusCode, Version};
|
||||||
use actix_http::{body, error, Error, HttpService, Request, Response};
|
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::ssl::RustlsAcceptor;
|
||||||
use actix_server_config::ServerConfig;
|
use actix_server_config::ServerConfig;
|
||||||
use actix_service::{factory_fn_cfg, pipeline_factory, service_fn2, ServiceFactory};
|
use actix_service::{factory_fn_cfg, pipeline_factory, service_fn2, ServiceFactory};
|
||||||
@ -45,140 +45,131 @@ fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> io::Result<RustlsAcceptor<T, ()>
|
|||||||
Ok(RustlsAcceptor::new(config))
|
Ok(RustlsAcceptor::new(config))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2() -> io::Result<()> {
|
async fn test_h2() -> io::Result<()> {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor()?;
|
||||||
let rustls = ssl_acceptor()?;
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| future::ok::<_, Error>(Response::Ok().finish()))
|
||||||
.h2(|_| future::ok::<_, Error>(Response::Ok().finish()))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_1() -> io::Result<()> {
|
async fn test_h2_1() -> io::Result<()> {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor()?;
|
||||||
let rustls = ssl_acceptor()?;
|
let srv = TestServer::start(move || {
|
||||||
let srv = TestServer::start(move || {
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.finish(|req: Request| {
|
||||||
.finish(|req: Request| {
|
assert!(req.peer_addr().is_some());
|
||||||
assert!(req.peer_addr().is_some());
|
assert_eq!(req.version(), Version::HTTP_2);
|
||||||
assert_eq!(req.version(), Version::HTTP_2);
|
future::ok::<_, Error>(Response::Ok().finish())
|
||||||
future::ok::<_, Error>(Response::Ok().finish())
|
})
|
||||||
})
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_body1() -> io::Result<()> {
|
async fn test_h2_body1() -> io::Result<()> {
|
||||||
block_on(async {
|
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
||||||
let data = "HELLOWORLD".to_owned().repeat(64 * 1024);
|
let rustls = ssl_acceptor()?;
|
||||||
let rustls = ssl_acceptor()?;
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|mut req: Request<_>| {
|
||||||
.h2(|mut req: Request<_>| {
|
async move {
|
||||||
async move {
|
let body = load_body(req.take_payload()).await?;
|
||||||
let body = load_body(req.take_payload()).await?;
|
Ok::<_, Error>(Response::Ok().body(body))
|
||||||
Ok::<_, Error>(Response::Ok().body(body))
|
}
|
||||||
}
|
})
|
||||||
})
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send_body(data.clone()).await.unwrap();
|
let response = srv.sget("/").send_body(data.clone()).await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let body = srv.load_body(response).await.unwrap();
|
let body = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(&body, data.as_bytes());
|
assert_eq!(&body, data.as_bytes());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_content_length() {
|
async fn test_h2_content_length() {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor().unwrap();
|
||||||
let rustls = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let srv = TestServer::start(move || {
|
let srv = TestServer::start(move || {
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.h2(|req: Request| {
|
.h2(|req: Request| {
|
||||||
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
let indx: usize = req.uri().path()[1..].parse().unwrap();
|
||||||
let statuses = [
|
let statuses = [
|
||||||
StatusCode::NO_CONTENT,
|
StatusCode::NO_CONTENT,
|
||||||
StatusCode::CONTINUE,
|
StatusCode::CONTINUE,
|
||||||
StatusCode::SWITCHING_PROTOCOLS,
|
StatusCode::SWITCHING_PROTOCOLS,
|
||||||
StatusCode::PROCESSING,
|
StatusCode::PROCESSING,
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
StatusCode::NOT_FOUND,
|
StatusCode::NOT_FOUND,
|
||||||
];
|
];
|
||||||
future::ok::<_, ()>(Response::new(statuses[indx]))
|
future::ok::<_, ()>(Response::new(statuses[indx]))
|
||||||
})
|
})
|
||||||
.map_err(|_| ()),
|
.map_err(|_| ()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let header = HeaderName::from_static("content-length");
|
let header = HeaderName::from_static("content-length");
|
||||||
let value = HeaderValue::from_static("0");
|
let value = HeaderValue::from_static("0");
|
||||||
|
|
||||||
{
|
{
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
let req = srv
|
let req = srv
|
||||||
.request(Method::GET, srv.surl(&format!("/{}", i)))
|
.request(Method::GET, srv.surl(&format!("/{}", i)))
|
||||||
.send();
|
.send();
|
||||||
let response = req.await.unwrap();
|
let response = req.await.unwrap();
|
||||||
assert_eq!(response.headers().get(&header), None);
|
assert_eq!(response.headers().get(&header), None);
|
||||||
|
|
||||||
let req = srv
|
let req = srv
|
||||||
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
|
.request(Method::HEAD, srv.surl(&format!("/{}", i)))
|
||||||
.send();
|
.send();
|
||||||
let response = req.await.unwrap();
|
let response = req.await.unwrap();
|
||||||
assert_eq!(response.headers().get(&header), None);
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
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]
|
#[actix_rt::test]
|
||||||
fn test_h2_headers() {
|
async fn test_h2_headers() {
|
||||||
block_on(async {
|
let data = STR.repeat(10);
|
||||||
let data = STR.repeat(10);
|
let data2 = data.clone();
|
||||||
let data2 = data.clone();
|
let rustls = ssl_acceptor().unwrap();
|
||||||
let rustls = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let mut srv = TestServer::start(move || {
|
let mut srv = TestServer::start(move || {
|
||||||
let data = data.clone();
|
let data = data.clone();
|
||||||
pipeline_factory(rustls
|
pipeline_factory(rustls
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Rustls error: {}", e)))
|
.map_err(|e| println!("Rustls error: {}", e)))
|
||||||
.and_then(
|
.and_then(
|
||||||
@ -204,15 +195,14 @@ fn test_h2_headers() {
|
|||||||
}
|
}
|
||||||
future::ok::<_, ()>(config.body(data.clone()))
|
future::ok::<_, ()>(config.body(data.clone()))
|
||||||
}).map_err(|_| ()))
|
}).map_err(|_| ()))
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from(data2));
|
assert_eq!(bytes, Bytes::from(data2));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
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 \
|
||||||
Hello World Hello World Hello World Hello World Hello World";
|
Hello World Hello World Hello World Hello World Hello World";
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_body2() {
|
async fn test_h2_body2() {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor().unwrap();
|
||||||
let rustls = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.h2(|_| future::ok::<_, ()>(Response::Ok().body(STR)))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_head_empty() {
|
async fn test_h2_head_empty() {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor().unwrap();
|
||||||
let rustls = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
||||||
.finish(|_| ok::<_, ()>(Response::Ok().body(STR)))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let response = srv.shead("/").send().await.unwrap();
|
let response = srv.shead("/").send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
assert_eq!(response.version(), Version::HTTP_2);
|
assert_eq!(response.version(), Version::HTTP_2);
|
||||||
|
|
||||||
{
|
{
|
||||||
let len = response
|
let len = response
|
||||||
.headers()
|
.headers()
|
||||||
.get(http::header::CONTENT_LENGTH)
|
.get(http::header::CONTENT_LENGTH)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert!(bytes.is_empty());
|
assert!(bytes.is_empty());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_head_binary() {
|
async fn test_h2_head_binary() {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor().unwrap();
|
||||||
let rustls = ssl_acceptor().unwrap();
|
let mut srv = TestServer::start(move || {
|
||||||
let mut srv = TestServer::start(move || {
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
.and_then(
|
||||||
.and_then(
|
HttpService::build()
|
||||||
HttpService::build()
|
.h2(|_| {
|
||||||
.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::<_, ()>(
|
ok::<_, ()>(
|
||||||
Response::Ok()
|
Response::Ok()
|
||||||
.content_length(STR.len() as u64)
|
.header(http::header::CONTENT_TYPE, broken_header)
|
||||||
.body(STR),
|
.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();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR);
|
assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
assert_eq!(bytes, Bytes::from_static(b"failed to parse header value"));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_h2_service_error() {
|
async fn test_h2_service_error() {
|
||||||
block_on(async {
|
let rustls = ssl_acceptor().unwrap();
|
||||||
let rustls = ssl_acceptor().unwrap();
|
|
||||||
|
|
||||||
let mut srv = TestServer::start(move || {
|
let mut srv = TestServer::start(move || {
|
||||||
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
pipeline_factory(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.h2(|_| err::<Response, Error>(error::ErrorBadRequest("error")))
|
.h2(|_| err::<Response, Error>(error::ErrorBadRequest("error")))
|
||||||
.map_err(|_| ()),
|
.map_err(|_| ()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = srv.sget("/").send().await.unwrap();
|
let response = srv.sget("/").send().await.unwrap();
|
||||||
assert_eq!(response.status(), http::StatusCode::BAD_REQUEST);
|
assert_eq!(response.status(), http::StatusCode::BAD_REQUEST);
|
||||||
|
|
||||||
// read response
|
// read response
|
||||||
let bytes = srv.load_body(response).await.unwrap();
|
let bytes = srv.load_body(response).await.unwrap();
|
||||||
assert_eq!(bytes, Bytes::from_static(b"error"));
|
assert_eq!(bytes, Bytes::from_static(b"error"));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||||
use actix_http::{body, h1, ws, Error, HttpService, Request, Response};
|
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 actix_utils::framed::FramedTransport;
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures::future;
|
use futures::future;
|
||||||
@ -34,53 +34,51 @@ async fn service(msg: ws::Frame) -> Result<ws::Message, Error> {
|
|||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_simple() {
|
async fn test_simple() {
|
||||||
block_on(async {
|
let mut srv = TestServer::start(|| {
|
||||||
let mut srv = TestServer::start(|| {
|
HttpService::build()
|
||||||
HttpService::build()
|
.upgrade(actix_service::service_fn(ws_service))
|
||||||
.upgrade(actix_service::service_fn(ws_service))
|
.finish(|_| future::ok::<_, ()>(Response::NotFound()))
|
||||||
.finish(|_| future::ok::<_, ()>(Response::NotFound()))
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// client service
|
// client service
|
||||||
let mut framed = srv.ws().await.unwrap();
|
let mut framed = srv.ws().await.unwrap();
|
||||||
framed
|
framed
|
||||||
.send(ws::Message::Text("text".to_string()))
|
.send(ws::Message::Text("text".to_string()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (item, mut framed) = framed.into_future().await;
|
let (item, mut framed) = framed.into_future().await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
item.unwrap().unwrap(),
|
item.unwrap().unwrap(),
|
||||||
ws::Frame::Text(Some(BytesMut::from("text")))
|
ws::Frame::Text(Some(BytesMut::from("text")))
|
||||||
);
|
);
|
||||||
|
|
||||||
framed
|
framed
|
||||||
.send(ws::Message::Binary("text".into()))
|
.send(ws::Message::Binary("text".into()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (item, mut framed) = framed.into_future().await;
|
let (item, mut framed) = framed.into_future().await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
item.unwrap().unwrap(),
|
item.unwrap().unwrap(),
|
||||||
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
|
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
|
||||||
);
|
);
|
||||||
|
|
||||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||||
let (item, mut framed) = framed.into_future().await;
|
let (item, mut framed) = framed.into_future().await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
item.unwrap().unwrap(),
|
item.unwrap().unwrap(),
|
||||||
ws::Frame::Pong("text".to_string().into())
|
ws::Frame::Pong("text".to_string().into())
|
||||||
);
|
);
|
||||||
|
|
||||||
framed
|
framed
|
||||||
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (item, _framed) = framed.into_future().await;
|
let (item, _framed) = framed.into_future().await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
item.unwrap().unwrap(),
|
item.unwrap().unwrap(),
|
||||||
ws::Frame::Close(Some(ws::CloseCode::Normal.into()))
|
ws::Frame::Close(Some(ws::CloseCode::Normal.into()))
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -607,144 +607,130 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_web::http::StatusCode;
|
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};
|
use actix_web::{web, App, Error, HttpResponse};
|
||||||
|
|
||||||
const COOKIE_KEY_MASTER: [u8; 32] = [0; 32];
|
const COOKIE_KEY_MASTER: [u8; 32] = [0; 32];
|
||||||
const COOKIE_NAME: &'static str = "actix_auth";
|
const COOKIE_NAME: &'static str = "actix_auth";
|
||||||
const COOKIE_LOGIN: &'static str = "test";
|
const COOKIE_LOGIN: &'static str = "test";
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity() {
|
async fn test_identity() {
|
||||||
block_on(async {
|
let mut srv = test::init_service(
|
||||||
let mut srv = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(IdentityService::new(
|
||||||
.wrap(IdentityService::new(
|
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
||||||
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
.domain("www.rust-lang.org")
|
||||||
.domain("www.rust-lang.org")
|
.name(COOKIE_NAME)
|
||||||
.name(COOKIE_NAME)
|
.path("/")
|
||||||
.path("/")
|
.secure(true),
|
||||||
.secure(true),
|
))
|
||||||
))
|
.service(web::resource("/index").to(|id: Identity| {
|
||||||
.service(web::resource("/index").to(|id: Identity| {
|
if id.identity().is_some() {
|
||||||
if id.identity().is_some() {
|
HttpResponse::Created()
|
||||||
HttpResponse::Created()
|
} else {
|
||||||
} else {
|
|
||||||
HttpResponse::Ok()
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.service(web::resource("/login").to(|id: Identity| {
|
|
||||||
id.remember(COOKIE_LOGIN.to_string());
|
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
}))
|
}
|
||||||
.service(web::resource("/logout").to(|id: Identity| {
|
}))
|
||||||
if id.identity().is_some() {
|
.service(web::resource("/login").to(|id: Identity| {
|
||||||
id.forget();
|
id.remember(COOKIE_LOGIN.to_string());
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
} else {
|
}))
|
||||||
HttpResponse::BadRequest()
|
.service(web::resource("/logout").to(|id: Identity| {
|
||||||
}
|
if id.identity().is_some() {
|
||||||
})),
|
id.forget();
|
||||||
)
|
HttpResponse::Ok()
|
||||||
.await;
|
} else {
|
||||||
let resp = test::call_service(
|
HttpResponse::BadRequest()
|
||||||
&mut srv,
|
}
|
||||||
TestRequest::with_uri("/index").to_request(),
|
})),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
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(
|
let resp =
|
||||||
&mut srv,
|
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request())
|
||||||
TestRequest::with_uri("/login").to_request(),
|
.await;
|
||||||
)
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
.await;
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
|
||||||
let c = resp.response().cookies().next().unwrap().to_owned();
|
|
||||||
|
|
||||||
let resp = test::call_service(
|
let resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/index")
|
TestRequest::with_uri("/index")
|
||||||
.cookie(c.clone())
|
.cookie(c.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::CREATED);
|
assert_eq!(resp.status(), StatusCode::CREATED);
|
||||||
|
|
||||||
let resp = test::call_service(
|
let resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/logout")
|
TestRequest::with_uri("/logout")
|
||||||
.cookie(c.clone())
|
.cookie(c.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert!(resp.headers().contains_key(header::SET_COOKIE))
|
assert!(resp.headers().contains_key(header::SET_COOKIE))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_max_age_time() {
|
async fn test_identity_max_age_time() {
|
||||||
block_on(async {
|
let duration = Duration::days(1);
|
||||||
let duration = Duration::days(1);
|
let mut srv = test::init_service(
|
||||||
let mut srv = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(IdentityService::new(
|
||||||
.wrap(IdentityService::new(
|
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
||||||
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
.domain("www.rust-lang.org")
|
||||||
.domain("www.rust-lang.org")
|
.name(COOKIE_NAME)
|
||||||
.name(COOKIE_NAME)
|
.path("/")
|
||||||
.path("/")
|
.max_age_time(duration)
|
||||||
.max_age_time(duration)
|
.secure(true),
|
||||||
.secure(true),
|
))
|
||||||
))
|
.service(web::resource("/login").to(|id: Identity| {
|
||||||
.service(web::resource("/login").to(|id: Identity| {
|
id.remember("test".to_string());
|
||||||
id.remember("test".to_string());
|
HttpResponse::Ok()
|
||||||
HttpResponse::Ok()
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
let resp =
|
||||||
let resp = test::call_service(
|
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request())
|
||||||
&mut srv,
|
.await;
|
||||||
TestRequest::with_uri("/login").to_request(),
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
)
|
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
||||||
.await;
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(duration, c.max_age().unwrap());
|
||||||
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]
|
#[actix_rt::test]
|
||||||
fn test_identity_max_age() {
|
async fn test_identity_max_age() {
|
||||||
block_on(async {
|
let seconds = 60;
|
||||||
let seconds = 60;
|
let mut srv = test::init_service(
|
||||||
let mut srv = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(IdentityService::new(
|
||||||
.wrap(IdentityService::new(
|
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
||||||
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
.domain("www.rust-lang.org")
|
||||||
.domain("www.rust-lang.org")
|
.name(COOKIE_NAME)
|
||||||
.name(COOKIE_NAME)
|
.path("/")
|
||||||
.path("/")
|
.max_age(seconds)
|
||||||
.max_age(seconds)
|
.secure(true),
|
||||||
.secure(true),
|
))
|
||||||
))
|
.service(web::resource("/login").to(|id: Identity| {
|
||||||
.service(web::resource("/login").to(|id: Identity| {
|
id.remember("test".to_string());
|
||||||
id.remember("test".to_string());
|
HttpResponse::Ok()
|
||||||
HttpResponse::Ok()
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
let resp =
|
||||||
let resp = test::call_service(
|
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request())
|
||||||
&mut srv,
|
.await;
|
||||||
TestRequest::with_uri("/login").to_request(),
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
)
|
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
||||||
.await;
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap());
|
||||||
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<
|
async fn create_identity_server<
|
||||||
@ -885,223 +871,202 @@ mod tests {
|
|||||||
assert!(cookies.get(COOKIE_NAME).is_none());
|
assert!(cookies.get(COOKIE_NAME).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_legacy_cookie_is_set() {
|
async fn test_identity_legacy_cookie_is_set() {
|
||||||
block_on(async {
|
let mut srv = create_identity_server(|c| c).await;
|
||||||
let mut srv = create_identity_server(|c| c).await;
|
let mut resp =
|
||||||
let mut resp =
|
test::call_service(&mut srv, TestRequest::with_uri("/").to_request()).await;
|
||||||
test::call_service(&mut srv, TestRequest::with_uri("/").to_request())
|
assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN);
|
||||||
.await;
|
assert_logged_in(resp, None).await;
|
||||||
assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN);
|
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_legacy_cookie_works() {
|
async fn test_identity_legacy_cookie_works() {
|
||||||
block_on(async {
|
let mut srv = create_identity_server(|c| c).await;
|
||||||
let mut srv = create_identity_server(|c| c).await;
|
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
||||||
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_no_login_cookie(&mut resp);
|
||||||
assert_no_login_cookie(&mut resp);
|
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
||||||
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() {
|
async fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
||||||
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_login_cookie(
|
||||||
assert_login_cookie(
|
&mut resp,
|
||||||
&mut resp,
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
LoginTimestampCheck::NoTimestamp,
|
||||||
LoginTimestampCheck::NoTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
);
|
||||||
);
|
assert_logged_in(resp, None).await;
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() {
|
async fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
||||||
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_login_cookie(
|
||||||
assert_login_cookie(
|
&mut resp,
|
||||||
&mut resp,
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
LoginTimestampCheck::NewTimestamp,
|
||||||
LoginTimestampCheck::NewTimestamp,
|
VisitTimeStampCheck::NoTimestamp,
|
||||||
VisitTimeStampCheck::NoTimestamp,
|
);
|
||||||
);
|
assert_logged_in(resp, None).await;
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_cookie_rejected_if_login_timestamp_needed() {
|
async fn test_identity_cookie_rejected_if_login_timestamp_needed() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
let cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now()));
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now()));
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_login_cookie(
|
||||||
assert_login_cookie(
|
&mut resp,
|
||||||
&mut resp,
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
LoginTimestampCheck::NewTimestamp,
|
||||||
LoginTimestampCheck::NewTimestamp,
|
VisitTimeStampCheck::NoTimestamp,
|
||||||
VisitTimeStampCheck::NoTimestamp,
|
);
|
||||||
);
|
assert_logged_in(resp, None).await;
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_cookie_rejected_if_visit_timestamp_needed() {
|
async fn test_identity_cookie_rejected_if_visit_timestamp_needed() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_login_cookie(
|
||||||
assert_login_cookie(
|
&mut resp,
|
||||||
&mut resp,
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
LoginTimestampCheck::NoTimestamp,
|
||||||
LoginTimestampCheck::NoTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
);
|
||||||
);
|
assert_logged_in(resp, None).await;
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_cookie_rejected_if_login_timestamp_too_old() {
|
async fn test_identity_cookie_rejected_if_login_timestamp_too_old() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
let cookie = login_cookie(
|
||||||
let cookie = login_cookie(
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
Some(SystemTime::now() - Duration::days(180).to_std().unwrap()),
|
||||||
Some(SystemTime::now() - Duration::days(180).to_std().unwrap()),
|
None,
|
||||||
None,
|
);
|
||||||
);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_login_cookie(
|
||||||
assert_login_cookie(
|
&mut resp,
|
||||||
&mut resp,
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
LoginTimestampCheck::NewTimestamp,
|
||||||
LoginTimestampCheck::NewTimestamp,
|
VisitTimeStampCheck::NoTimestamp,
|
||||||
VisitTimeStampCheck::NoTimestamp,
|
);
|
||||||
);
|
assert_logged_in(resp, None).await;
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_cookie_rejected_if_visit_timestamp_too_old() {
|
async fn test_identity_cookie_rejected_if_visit_timestamp_too_old() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
let cookie = login_cookie(
|
||||||
let cookie = login_cookie(
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
None,
|
||||||
None,
|
Some(SystemTime::now() - Duration::days(180).to_std().unwrap()),
|
||||||
Some(SystemTime::now() - Duration::days(180).to_std().unwrap()),
|
);
|
||||||
);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_login_cookie(
|
||||||
assert_login_cookie(
|
&mut resp,
|
||||||
&mut resp,
|
COOKIE_LOGIN,
|
||||||
COOKIE_LOGIN,
|
LoginTimestampCheck::NoTimestamp,
|
||||||
LoginTimestampCheck::NoTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
);
|
||||||
);
|
assert_logged_in(resp, None).await;
|
||||||
assert_logged_in(resp, None).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_cookie_not_updated_on_login_deadline() {
|
async fn test_identity_cookie_not_updated_on_login_deadline() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
let mut resp = test::call_service(
|
||||||
let mut resp = test::call_service(
|
&mut srv,
|
||||||
&mut srv,
|
TestRequest::with_uri("/")
|
||||||
TestRequest::with_uri("/")
|
.cookie(cookie.clone())
|
||||||
.cookie(cookie.clone())
|
.to_request(),
|
||||||
.to_request(),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
assert_no_login_cookie(&mut resp);
|
||||||
assert_no_login_cookie(&mut resp);
|
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
||||||
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_identity_cookie_updated_on_visit_deadline() {
|
async fn test_identity_cookie_updated_on_visit_deadline() {
|
||||||
block_on(async {
|
let mut srv = create_identity_server(|c| {
|
||||||
let mut srv = create_identity_server(|c| {
|
c.visit_deadline(Duration::days(90))
|
||||||
c.visit_deadline(Duration::days(90))
|
.login_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;
|
|
||||||
})
|
})
|
||||||
|
.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,12 +813,11 @@ mod tests {
|
|||||||
use actix_http::h1::Payload;
|
use actix_http::h1::Payload;
|
||||||
use actix_utils::mpsc;
|
use actix_utils::mpsc;
|
||||||
use actix_web::http::header::{DispositionParam, DispositionType};
|
use actix_web::http::header::{DispositionParam, DispositionType};
|
||||||
use actix_web::test::block_on;
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::future::lazy;
|
use futures::future::lazy;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_boundary() {
|
async fn test_boundary() {
|
||||||
let headers = HeaderMap::new();
|
let headers = HeaderMap::new();
|
||||||
match Multipart::boundary(&headers) {
|
match Multipart::boundary(&headers) {
|
||||||
Err(MultipartError::NoContentType) => (),
|
Err(MultipartError::NoContentType) => (),
|
||||||
@ -891,246 +890,228 @@ mod tests {
|
|||||||
(bytes, headers)
|
(bytes, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_multipart_no_end_crlf() {
|
async fn test_multipart_no_end_crlf() {
|
||||||
block_on(async {
|
let (sender, payload) = create_stream();
|
||||||
let (sender, payload) = create_stream();
|
let (bytes, headers) = create_simple_request_with_header();
|
||||||
let (bytes, headers) = create_simple_request_with_header();
|
let bytes_stripped = bytes.slice_to(bytes.len()); // strip crlf
|
||||||
let bytes_stripped = bytes.slice_to(bytes.len()); // strip crlf
|
|
||||||
|
|
||||||
sender.send(Ok(bytes_stripped)).unwrap();
|
sender.send(Ok(bytes_stripped)).unwrap();
|
||||||
drop(sender); // eof
|
drop(sender); // eof
|
||||||
|
|
||||||
let mut multipart = Multipart::new(&headers, payload);
|
let mut multipart = Multipart::new(&headers, payload);
|
||||||
|
|
||||||
match multipart.next().await.unwrap() {
|
match multipart.next().await.unwrap() {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match multipart.next().await.unwrap() {
|
match multipart.next().await.unwrap() {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match multipart.next().await {
|
match multipart.next().await {
|
||||||
None => (),
|
None => (),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_multipart() {
|
async fn test_multipart() {
|
||||||
block_on(async {
|
let (sender, payload) = create_stream();
|
||||||
let (sender, payload) = create_stream();
|
let (bytes, headers) = create_simple_request_with_header();
|
||||||
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);
|
let mut multipart = Multipart::new(&headers, payload);
|
||||||
match multipart.next().await {
|
match multipart.next().await {
|
||||||
Some(Ok(mut field)) => {
|
Some(Ok(mut field)) => {
|
||||||
let cd = field.content_disposition().unwrap();
|
let cd = field.content_disposition().unwrap();
|
||||||
assert_eq!(cd.disposition, DispositionType::FormData);
|
assert_eq!(cd.disposition, DispositionType::FormData);
|
||||||
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
|
||||||
|
|
||||||
assert_eq!(field.content_type().type_(), mime::TEXT);
|
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||||
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||||
|
|
||||||
match field.next().await.unwrap() {
|
match field.next().await.unwrap() {
|
||||||
Ok(chunk) => assert_eq!(chunk, "test"),
|
Ok(chunk) => assert_eq!(chunk, "test"),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
|
||||||
match field.next().await {
|
|
||||||
None => (),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
match field.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);
|
|
||||||
|
|
||||||
match field.next().await {
|
|
||||||
Some(Ok(chunk)) => assert_eq!(chunk, "data"),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
match field.next().await {
|
|
||||||
None => (),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
match multipart.next().await {
|
match multipart.next().await.unwrap() {
|
||||||
None => (),
|
Ok(mut field) => {
|
||||||
_ => unreachable!(),
|
assert_eq!(field.content_type().type_(), mime::TEXT);
|
||||||
}
|
assert_eq!(field.content_type().subtype(), mime::PLAIN);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
match field.next().await {
|
||||||
fn test_stream() {
|
Some(Ok(chunk)) => assert_eq!(chunk, "data"),
|
||||||
block_on(async {
|
_ => unreachable!(),
|
||||||
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 field.next().await {
|
||||||
}
|
None => (),
|
||||||
|
_ => 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!(),
|
|
||||||
}
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
match multipart.next().await {
|
match multipart.next().await {
|
||||||
None => (),
|
None => (),
|
||||||
_ => unreachable!(),
|
_ => 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]
|
#[actix_rt::test]
|
||||||
fn test_basic() {
|
async fn test_basic() {
|
||||||
block_on(async {
|
let (_, payload) = Payload::create(false);
|
||||||
let (_, payload) = Payload::create(false);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
|
||||||
|
|
||||||
assert_eq!(payload.buf.len(), 0);
|
assert_eq!(payload.buf.len(), 0);
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
||||||
assert_eq!(None, payload.read_max(1).unwrap());
|
assert_eq!(None, payload.read_max(1).unwrap());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_eof() {
|
async fn test_eof() {
|
||||||
block_on(async {
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
|
||||||
|
|
||||||
assert_eq!(None, payload.read_max(4).unwrap());
|
assert_eq!(None, payload.read_max(4).unwrap());
|
||||||
sender.feed_data(Bytes::from("data"));
|
sender.feed_data(Bytes::from("data"));
|
||||||
sender.feed_eof();
|
sender.feed_eof();
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap());
|
assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap());
|
||||||
assert_eq!(payload.buf.len(), 0);
|
assert_eq!(payload.buf.len(), 0);
|
||||||
assert!(payload.read_max(1).is_err());
|
assert!(payload.read_max(1).is_err());
|
||||||
assert!(payload.eof);
|
assert!(payload.eof);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_err() {
|
async fn test_err() {
|
||||||
block_on(async {
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
assert_eq!(None, payload.read_max(1).unwrap());
|
||||||
assert_eq!(None, payload.read_max(1).unwrap());
|
sender.set_error(PayloadError::Incomplete(None));
|
||||||
sender.set_error(PayloadError::Incomplete(None));
|
lazy(|cx| payload.poll_stream(cx)).await.err().unwrap();
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.err().unwrap();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_readmax() {
|
async fn test_readmax() {
|
||||||
block_on(async {
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
let mut payload = PayloadBuffer::new(payload);
|
|
||||||
|
|
||||||
sender.feed_data(Bytes::from("line1"));
|
sender.feed_data(Bytes::from("line1"));
|
||||||
sender.feed_data(Bytes::from("line2"));
|
sender.feed_data(Bytes::from("line2"));
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
||||||
assert_eq!(payload.buf.len(), 10);
|
assert_eq!(payload.buf.len(), 10);
|
||||||
|
|
||||||
assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap());
|
assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap());
|
||||||
assert_eq!(payload.buf.len(), 5);
|
assert_eq!(payload.buf.len(), 5);
|
||||||
|
|
||||||
assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap());
|
assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap());
|
||||||
assert_eq!(payload.buf.len(), 0);
|
assert_eq!(payload.buf.len(), 0);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_readexactly() {
|
async fn test_readexactly() {
|
||||||
block_on(async {
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
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("line1"));
|
||||||
sender.feed_data(Bytes::from("line2"));
|
sender.feed_data(Bytes::from("line2"));
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2));
|
assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2));
|
||||||
assert_eq!(payload.buf.len(), 8);
|
assert_eq!(payload.buf.len(), 8);
|
||||||
|
|
||||||
assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4));
|
assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4));
|
||||||
assert_eq!(payload.buf.len(), 4);
|
assert_eq!(payload.buf.len(), 4);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_readuntil() {
|
async fn test_readuntil() {
|
||||||
block_on(async {
|
let (mut sender, payload) = Payload::create(false);
|
||||||
let (mut sender, payload) = Payload::create(false);
|
let mut payload = PayloadBuffer::new(payload);
|
||||||
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("line1"));
|
||||||
sender.feed_data(Bytes::from("line2"));
|
sender.feed_data(Bytes::from("line2"));
|
||||||
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
lazy(|cx| payload.poll_stream(cx)).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(Bytes::from("line")),
|
Some(Bytes::from("line")),
|
||||||
payload.read_until(b"ne").unwrap()
|
payload.read_until(b"ne").unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(payload.buf.len(), 6);
|
assert_eq!(payload.buf.len(), 6);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(Bytes::from("1line2")),
|
Some(Bytes::from("1line2")),
|
||||||
payload.read_until(b"2").unwrap()
|
payload.read_until(b"2").unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(payload.buf.len(), 0);
|
assert_eq!(payload.buf.len(), 0);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,125 +364,117 @@ mod tests {
|
|||||||
use actix_web::{test, web, App};
|
use actix_web::{test, web, App};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn cookie_session() {
|
async fn cookie_session() {
|
||||||
test::block_on(async {
|
let mut app = test::init_service(
|
||||||
let mut app = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
||||||
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
.service(web::resource("/").to(|ses: Session| {
|
||||||
.service(web::resource("/").to(|ses: Session| {
|
async move {
|
||||||
async move {
|
let _ = ses.set("counter", 100);
|
||||||
let _ = ses.set("counter", 100);
|
"test"
|
||||||
"test"
|
}
|
||||||
}
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
let request = test::TestRequest::get().to_request();
|
let request = test::TestRequest::get().to_request();
|
||||||
let response = app.call(request).await.unwrap();
|
let response = app.call(request).await.unwrap();
|
||||||
assert!(response
|
assert!(response
|
||||||
.response()
|
.response()
|
||||||
.cookies()
|
.cookies()
|
||||||
.find(|c| c.name() == "actix-session")
|
.find(|c| c.name() == "actix-session")
|
||||||
.is_some());
|
.is_some());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn private_cookie() {
|
async fn private_cookie() {
|
||||||
test::block_on(async {
|
let mut app = test::init_service(
|
||||||
let mut app = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(CookieSession::private(&[0; 32]).secure(false))
|
||||||
.wrap(CookieSession::private(&[0; 32]).secure(false))
|
.service(web::resource("/").to(|ses: Session| {
|
||||||
.service(web::resource("/").to(|ses: Session| {
|
async move {
|
||||||
async move {
|
let _ = ses.set("counter", 100);
|
||||||
let _ = ses.set("counter", 100);
|
"test"
|
||||||
"test"
|
}
|
||||||
}
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
let request = test::TestRequest::get().to_request();
|
let request = test::TestRequest::get().to_request();
|
||||||
let response = app.call(request).await.unwrap();
|
let response = app.call(request).await.unwrap();
|
||||||
assert!(response
|
assert!(response
|
||||||
.response()
|
.response()
|
||||||
.cookies()
|
.cookies()
|
||||||
.find(|c| c.name() == "actix-session")
|
.find(|c| c.name() == "actix-session")
|
||||||
.is_some());
|
.is_some());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn cookie_session_extractor() {
|
async fn cookie_session_extractor() {
|
||||||
test::block_on(async {
|
let mut app = test::init_service(
|
||||||
let mut app = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
||||||
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
.service(web::resource("/").to(|ses: Session| {
|
||||||
.service(web::resource("/").to(|ses: Session| {
|
async move {
|
||||||
async move {
|
let _ = ses.set("counter", 100);
|
||||||
let _ = ses.set("counter", 100);
|
"test"
|
||||||
"test"
|
}
|
||||||
}
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
let request = test::TestRequest::get().to_request();
|
let request = test::TestRequest::get().to_request();
|
||||||
let response = app.call(request).await.unwrap();
|
let response = app.call(request).await.unwrap();
|
||||||
assert!(response
|
assert!(response
|
||||||
.response()
|
.response()
|
||||||
.cookies()
|
.cookies()
|
||||||
.find(|c| c.name() == "actix-session")
|
.find(|c| c.name() == "actix-session")
|
||||||
.is_some());
|
.is_some());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn basics() {
|
async fn basics() {
|
||||||
test::block_on(async {
|
let mut app = test::init_service(
|
||||||
let mut app = test::init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(
|
||||||
.wrap(
|
CookieSession::signed(&[0; 32])
|
||||||
CookieSession::signed(&[0; 32])
|
.path("/test/")
|
||||||
.path("/test/")
|
.name("actix-test")
|
||||||
.name("actix-test")
|
.domain("localhost")
|
||||||
.domain("localhost")
|
.http_only(true)
|
||||||
.http_only(true)
|
.same_site(SameSite::Lax)
|
||||||
.same_site(SameSite::Lax)
|
.max_age(100),
|
||||||
.max_age(100),
|
)
|
||||||
)
|
.service(web::resource("/").to(|ses: Session| {
|
||||||
.service(web::resource("/").to(|ses: Session| {
|
async move {
|
||||||
async move {
|
let _ = ses.set("counter", 100);
|
||||||
let _ = ses.set("counter", 100);
|
"test"
|
||||||
"test"
|
}
|
||||||
}
|
}))
|
||||||
}))
|
.service(web::resource("/test/").to(|ses: Session| {
|
||||||
.service(web::resource("/test/").to(|ses: Session| {
|
async move {
|
||||||
async move {
|
let val: usize = ses.get("counter").unwrap().unwrap();
|
||||||
let val: usize = ses.get("counter").unwrap().unwrap();
|
format!("counter: {}", val)
|
||||||
format!("counter: {}", val)
|
}
|
||||||
}
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
let request = test::TestRequest::get().to_request();
|
let request = test::TestRequest::get().to_request();
|
||||||
let response = app.call(request).await.unwrap();
|
let response = app.call(request).await.unwrap();
|
||||||
let cookie = response
|
let cookie = response
|
||||||
.response()
|
.response()
|
||||||
.cookies()
|
.cookies()
|
||||||
.find(|c| c.name() == "actix-test")
|
.find(|c| c.name() == "actix-test")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
assert_eq!(cookie.path().unwrap(), "/test/");
|
assert_eq!(cookie.path().unwrap(), "/test/");
|
||||||
|
|
||||||
let request = test::TestRequest::with_uri("/test/")
|
let request = test::TestRequest::with_uri("/test/")
|
||||||
.cookie(cookie)
|
.cookie(cookie)
|
||||||
.to_request();
|
.to_request();
|
||||||
let body = test::read_response(&mut app, request).await;
|
let body = test::read_response(&mut app, request).await;
|
||||||
assert_eq!(body, Bytes::from_static(b"counter: 100"));
|
assert_eq!(body, Bytes::from_static(b"counter: 100"));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ syn = { version = "^1", features = ["full", "parsing"] }
|
|||||||
proc-macro2 = "^1"
|
proc-macro2 = "^1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
actix-rt = { version = "1.0.0-alpha.1" }
|
||||||
actix-web = { version = "2.0.0-alpha.1" }
|
actix-web = { version = "2.0.0-alpha.1" }
|
||||||
actix-http = { version = "0.3.0-alpha.1", features=["openssl"] }
|
actix-http = { version = "0.3.0-alpha.1", features=["openssl"] }
|
||||||
actix-http-test = { version = "0.3.0-alpha.1", features=["openssl"] }
|
actix-http-test = { version = "0.3.0-alpha.1", features=["openssl"] }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use actix_http::HttpService;
|
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::{http, web::Path, App, HttpResponse, Responder};
|
||||||
use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, trace};
|
use actix_web_codegen::{connect, delete, get, head, options, patch, post, put, trace};
|
||||||
use futures::{future, Future};
|
use futures::{future, Future};
|
||||||
@ -69,95 +69,89 @@ async fn get_param_test(_: Path<String>) -> impl Responder {
|
|||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_params() {
|
async fn test_params() {
|
||||||
block_on(async {
|
let srv = TestServer::start(|| {
|
||||||
let srv = TestServer::start(|| {
|
HttpService::new(
|
||||||
HttpService::new(
|
App::new()
|
||||||
App::new()
|
.service(get_param_test)
|
||||||
.service(get_param_test)
|
.service(put_param_test)
|
||||||
.service(put_param_test)
|
.service(delete_param_test),
|
||||||
.service(delete_param_test),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let request = srv.request(http::Method::GET, srv.url("/test/it"));
|
let request = srv.request(http::Method::GET, srv.url("/test/it"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert_eq!(response.status(), http::StatusCode::OK);
|
assert_eq!(response.status(), http::StatusCode::OK);
|
||||||
|
|
||||||
let request = srv.request(http::Method::PUT, srv.url("/test/it"));
|
let request = srv.request(http::Method::PUT, srv.url("/test/it"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert_eq!(response.status(), http::StatusCode::CREATED);
|
assert_eq!(response.status(), http::StatusCode::CREATED);
|
||||||
|
|
||||||
let request = srv.request(http::Method::DELETE, srv.url("/test/it"));
|
let request = srv.request(http::Method::DELETE, srv.url("/test/it"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_body() {
|
async fn test_body() {
|
||||||
block_on(async {
|
let srv = TestServer::start(|| {
|
||||||
let srv = TestServer::start(|| {
|
HttpService::new(
|
||||||
HttpService::new(
|
App::new()
|
||||||
App::new()
|
.service(post_test)
|
||||||
.service(post_test)
|
.service(put_test)
|
||||||
.service(put_test)
|
.service(head_test)
|
||||||
.service(head_test)
|
.service(connect_test)
|
||||||
.service(connect_test)
|
.service(options_test)
|
||||||
.service(options_test)
|
.service(trace_test)
|
||||||
.service(trace_test)
|
.service(patch_test)
|
||||||
.service(patch_test)
|
.service(test),
|
||||||
.service(test),
|
)
|
||||||
)
|
});
|
||||||
});
|
let request = srv.request(http::Method::GET, srv.url("/test"));
|
||||||
let request = srv.request(http::Method::GET, srv.url("/test"));
|
let response = request.send().await.unwrap();
|
||||||
let response = request.send().await.unwrap();
|
assert!(response.status().is_success());
|
||||||
assert!(response.status().is_success());
|
|
||||||
|
|
||||||
let request = srv.request(http::Method::HEAD, srv.url("/test"));
|
let request = srv.request(http::Method::HEAD, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let request = srv.request(http::Method::CONNECT, srv.url("/test"));
|
let request = srv.request(http::Method::CONNECT, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let request = srv.request(http::Method::OPTIONS, srv.url("/test"));
|
let request = srv.request(http::Method::OPTIONS, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let request = srv.request(http::Method::TRACE, srv.url("/test"));
|
let request = srv.request(http::Method::TRACE, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let request = srv.request(http::Method::PATCH, srv.url("/test"));
|
let request = srv.request(http::Method::PATCH, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
let request = srv.request(http::Method::PUT, srv.url("/test"));
|
let request = srv.request(http::Method::PUT, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
assert_eq!(response.status(), http::StatusCode::CREATED);
|
assert_eq!(response.status(), http::StatusCode::CREATED);
|
||||||
|
|
||||||
let request = srv.request(http::Method::POST, srv.url("/test"));
|
let request = srv.request(http::Method::POST, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
assert_eq!(response.status(), http::StatusCode::NO_CONTENT);
|
||||||
|
|
||||||
let request = srv.request(http::Method::GET, srv.url("/test"));
|
let request = srv.request(http::Method::GET, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_auto_async() {
|
async fn test_auto_async() {
|
||||||
block_on(async {
|
let srv = TestServer::start(|| HttpService::new(App::new().service(auto_async)));
|
||||||
let srv = TestServer::start(|| HttpService::new(App::new().service(auto_async)));
|
|
||||||
|
|
||||||
let request = srv.request(http::Method::GET, srv.url("/test"));
|
let request = srv.request(http::Method::GET, srv.url("/test"));
|
||||||
let response = request.send().await.unwrap();
|
let response = request.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ default = ["brotli", "flate2-zlib"]
|
|||||||
openssl = ["open-ssl", "actix-http/openssl"]
|
openssl = ["open-ssl", "actix-http/openssl"]
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
# rustls = ["rust-tls", "actix-http/rustls"]
|
rustls = ["rust-tls", "actix-http/rustls"]
|
||||||
|
|
||||||
# brotli encoding, requires c compiler
|
# brotli encoding, requires c compiler
|
||||||
brotli = ["actix-http/brotli"]
|
brotli = ["actix-http/brotli"]
|
||||||
@ -45,6 +45,7 @@ flate2-rust = ["actix-http/flate2-rust"]
|
|||||||
actix-codec = "0.2.0-alpha.1"
|
actix-codec = "0.2.0-alpha.1"
|
||||||
actix-service = "1.0.0-alpha.1"
|
actix-service = "1.0.0-alpha.1"
|
||||||
actix-http = "0.3.0-alpha.1"
|
actix-http = "0.3.0-alpha.1"
|
||||||
|
actix-rt = "1.0.0-alpha.1"
|
||||||
|
|
||||||
base64 = "0.10.1"
|
base64 = "0.10.1"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
@ -57,12 +58,10 @@ rand = "0.7"
|
|||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_urlencoded = "0.6.1"
|
serde_urlencoded = "0.6.1"
|
||||||
tokio-timer = "0.3.0-alpha.6"
|
|
||||||
open-ssl = { version="0.10", package="openssl", optional = true }
|
open-ssl = { version="0.10", package="openssl", optional = true }
|
||||||
rust-tls = { version = "0.16.0", package="rustls", optional = true, features = ["dangerous_configuration"] }
|
rust-tls = { version = "0.16.0", package="rustls", optional = true, features = ["dangerous_configuration"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "1.0.0-alpha.1"
|
|
||||||
actix-connect = { version = "1.0.0-alpha.1", features=["openssl"] }
|
actix-connect = { version = "1.0.0-alpha.1", features=["openssl"] }
|
||||||
actix-web = { version = "2.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"] }
|
actix-http = { version = "0.3.0-alpha.1", features=["openssl"] }
|
||||||
@ -73,5 +72,4 @@ brotli2 = { version="0.3.2" }
|
|||||||
flate2 = { version="1.0.2" }
|
flate2 = { version="1.0.2" }
|
||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
tokio-tcp = "0.1"
|
|
||||||
webpki = { version = "0.21" }
|
webpki = { version = "0.21" }
|
||||||
|
@ -6,19 +6,16 @@
|
|||||||
//! use actix_rt::System;
|
//! use actix_rt::System;
|
||||||
//! use awc::Client;
|
//! use awc::Client;
|
||||||
//!
|
//!
|
||||||
//! fn main() {
|
//! #[actix_rt::main]
|
||||||
//! System::new("test").block_on(async {
|
//! async fn main() {
|
||||||
//! let mut client = Client::default();
|
//! let mut client = Client::default();
|
||||||
//!
|
//!
|
||||||
//! client.get("http://www.rust-lang.org") // <- Create request builder
|
//! let response = client.get("http://www.rust-lang.org") // <- Create request builder
|
||||||
//! .header("User-Agent", "Actix-web")
|
//! .header("User-Agent", "Actix-web")
|
||||||
//! .send() // <- Send http request
|
//! .send() // <- Send http request
|
||||||
//! .await
|
//! .await;
|
||||||
//! .and_then(|response| { // <- server http response
|
//!
|
||||||
//! println!("Response: {:?}", response);
|
//! println!("Response: {:?}", response);
|
||||||
//! Ok(())
|
|
||||||
//! })
|
|
||||||
//! });
|
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -39,19 +39,18 @@ const HTTPS_ENCODING: &str = "gzip, deflate";
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_rt::System;
|
/// use actix_rt::System;
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// #[actix_rt::main]
|
||||||
/// System::new("test").block_on(async {
|
/// async fn main() {
|
||||||
/// let response = awc::Client::new()
|
/// let response = awc::Client::new()
|
||||||
/// .get("http://www.rust-lang.org") // <- Create request builder
|
/// .get("http://www.rust-lang.org") // <- Create request builder
|
||||||
/// .header("User-Agent", "Actix-web")
|
/// .header("User-Agent", "Actix-web")
|
||||||
/// .send() // <- Send http request
|
/// .send() // <- Send http request
|
||||||
/// .await;
|
/// .await;
|
||||||
///
|
///
|
||||||
/// response.and_then(|response| { // <- server http response
|
/// response.and_then(|response| { // <- server http response
|
||||||
/// println!("Response: {:?}", response);
|
/// println!("Response: {:?}", response);
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// })
|
/// });
|
||||||
/// });
|
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct ClientRequest {
|
pub struct ClientRequest {
|
||||||
@ -308,25 +307,21 @@ impl ClientRequest {
|
|||||||
/// Set a cookie
|
/// Set a cookie
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use actix_rt::System;
|
/// #[actix_rt::main]
|
||||||
/// fn main() {
|
/// async fn main() {
|
||||||
/// System::new("test").block_on(async {
|
/// let resp = awc::Client::new().get("https://www.rust-lang.org")
|
||||||
/// awc::Client::new().get("https://www.rust-lang.org")
|
/// .cookie(
|
||||||
/// .cookie(
|
/// awc::http::Cookie::build("name", "value")
|
||||||
/// awc::http::Cookie::build("name", "value")
|
/// .domain("www.rust-lang.org")
|
||||||
/// .domain("www.rust-lang.org")
|
/// .path("/")
|
||||||
/// .path("/")
|
/// .secure(true)
|
||||||
/// .secure(true)
|
/// .http_only(true)
|
||||||
/// .http_only(true)
|
/// .finish(),
|
||||||
/// .finish(),
|
/// )
|
||||||
/// )
|
/// .send()
|
||||||
/// .send()
|
/// .await;
|
||||||
/// .await
|
///
|
||||||
/// .and_then(|response| {
|
/// println!("Response: {:?}", resp);
|
||||||
/// println!("Response: {:?}", response);
|
|
||||||
/// Ok(())
|
|
||||||
/// })
|
|
||||||
/// });
|
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
|
pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
|
||||||
|
@ -358,41 +358,37 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_http_test::block_on;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{http::header, test::TestResponse};
|
use crate::{http::header, test::TestResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_body() {
|
async fn test_body() {
|
||||||
block_on(async {
|
let mut req = TestResponse::with_header(header::CONTENT_LENGTH, "xxxx").finish();
|
||||||
let mut req =
|
match req.body().await.err().unwrap() {
|
||||||
TestResponse::with_header(header::CONTENT_LENGTH, "xxxx").finish();
|
PayloadError::UnknownLength => (),
|
||||||
match req.body().await.err().unwrap() {
|
_ => unreachable!("error"),
|
||||||
PayloadError::UnknownLength => (),
|
}
|
||||||
_ => unreachable!("error"),
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut req =
|
let mut req =
|
||||||
TestResponse::with_header(header::CONTENT_LENGTH, "1000000").finish();
|
TestResponse::with_header(header::CONTENT_LENGTH, "1000000").finish();
|
||||||
match req.body().await.err().unwrap() {
|
match req.body().await.err().unwrap() {
|
||||||
PayloadError::Overflow => (),
|
PayloadError::Overflow => (),
|
||||||
_ => unreachable!("error"),
|
_ => unreachable!("error"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut req = TestResponse::default()
|
let mut req = TestResponse::default()
|
||||||
.set_payload(Bytes::from_static(b"test"))
|
.set_payload(Bytes::from_static(b"test"))
|
||||||
.finish();
|
.finish();
|
||||||
assert_eq!(req.body().await.ok().unwrap(), Bytes::from_static(b"test"));
|
assert_eq!(req.body().await.ok().unwrap(), Bytes::from_static(b"test"));
|
||||||
|
|
||||||
let mut req = TestResponse::default()
|
let mut req = TestResponse::default()
|
||||||
.set_payload(Bytes::from_static(b"11111111111111"))
|
.set_payload(Bytes::from_static(b"11111111111111"))
|
||||||
.finish();
|
.finish();
|
||||||
match req.body().limit(5).await.err().unwrap() {
|
match req.body().limit(5).await.err().unwrap() {
|
||||||
PayloadError::Overflow => (),
|
PayloadError::Overflow => (),
|
||||||
_ => unreachable!("error"),
|
_ => unreachable!("error"),
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
@ -414,58 +410,56 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_json_body() {
|
async fn test_json_body() {
|
||||||
block_on(async {
|
let mut req = TestResponse::default().finish();
|
||||||
let mut req = TestResponse::default().finish();
|
let json = JsonBody::<_, MyObject>::new(&mut req).await;
|
||||||
let json = JsonBody::<_, MyObject>::new(&mut req).await;
|
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
||||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
|
||||||
|
|
||||||
let mut req = TestResponse::default()
|
let mut req = TestResponse::default()
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
header::HeaderValue::from_static("application/text"),
|
header::HeaderValue::from_static("application/text"),
|
||||||
)
|
)
|
||||||
.finish();
|
.finish();
|
||||||
let json = JsonBody::<_, MyObject>::new(&mut req).await;
|
let json = JsonBody::<_, MyObject>::new(&mut req).await;
|
||||||
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
|
||||||
|
|
||||||
let mut req = TestResponse::default()
|
let mut req = TestResponse::default()
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
header::HeaderValue::from_static("application/json"),
|
header::HeaderValue::from_static("application/json"),
|
||||||
)
|
)
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_LENGTH,
|
header::CONTENT_LENGTH,
|
||||||
header::HeaderValue::from_static("10000"),
|
header::HeaderValue::from_static("10000"),
|
||||||
)
|
)
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
let json = JsonBody::<_, MyObject>::new(&mut req).limit(100).await;
|
let json = JsonBody::<_, MyObject>::new(&mut req).limit(100).await;
|
||||||
assert!(json_eq(
|
assert!(json_eq(
|
||||||
json.err().unwrap(),
|
json.err().unwrap(),
|
||||||
JsonPayloadError::Payload(PayloadError::Overflow)
|
JsonPayloadError::Payload(PayloadError::Overflow)
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut req = TestResponse::default()
|
let mut req = TestResponse::default()
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
header::HeaderValue::from_static("application/json"),
|
header::HeaderValue::from_static("application/json"),
|
||||||
)
|
)
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_LENGTH,
|
header::CONTENT_LENGTH,
|
||||||
header::HeaderValue::from_static("16"),
|
header::HeaderValue::from_static("16"),
|
||||||
)
|
)
|
||||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
let json = JsonBody::<_, MyObject>::new(&mut req).await;
|
let json = JsonBody::<_, MyObject>::new(&mut req).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
json.ok().unwrap(),
|
json.ok().unwrap(),
|
||||||
MyObject {
|
MyObject {
|
||||||
name: "test".to_owned()
|
name: "test".to_owned()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ use std::rc::Rc;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use actix_rt::time::{delay_for, Delay};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use derive_more::From;
|
use derive_more::From;
|
||||||
use futures::{future::LocalBoxFuture, ready, Future, Stream};
|
use futures::{future::LocalBoxFuture, ready, Future, Stream};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use tokio_timer::{delay_for, Delay};
|
|
||||||
|
|
||||||
use actix_http::body::{Body, BodyStream};
|
use actix_http::body::{Body, BodyStream};
|
||||||
use actix_http::encoding::Decoder;
|
use actix_http::encoding::Decoder;
|
||||||
|
@ -7,8 +7,8 @@ use std::{fmt, str};
|
|||||||
use actix_codec::Framed;
|
use actix_codec::Framed;
|
||||||
use actix_http::cookie::{Cookie, CookieJar};
|
use actix_http::cookie::{Cookie, CookieJar};
|
||||||
use actix_http::{ws, Payload, RequestHead};
|
use actix_http::{ws, Payload, RequestHead};
|
||||||
|
use actix_rt::time::Timeout;
|
||||||
use percent_encoding::percent_encode;
|
use percent_encoding::percent_encode;
|
||||||
use tokio_timer::Timeout;
|
|
||||||
|
|
||||||
use actix_http::cookie::USERINFO;
|
use actix_http::cookie::USERINFO;
|
||||||
pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
|
pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
|
||||||
@ -389,21 +389,19 @@ impl fmt::Debug for WebsocketsRequest {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use actix_web::test::block_on;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Client;
|
use crate::Client;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_debug() {
|
async fn test_debug() {
|
||||||
let request = Client::new().ws("/").header("x-test", "111");
|
let request = Client::new().ws("/").header("x-test", "111");
|
||||||
let repr = format!("{:?}", request);
|
let repr = format!("{:?}", request);
|
||||||
assert!(repr.contains("WebsocketsRequest"));
|
assert!(repr.contains("WebsocketsRequest"));
|
||||||
assert!(repr.contains("x-test"));
|
assert!(repr.contains("x-test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_header_override() {
|
async fn test_header_override() {
|
||||||
let req = Client::build()
|
let req = Client::build()
|
||||||
.header(header::CONTENT_TYPE, "111")
|
.header(header::CONTENT_TYPE, "111")
|
||||||
.finish()
|
.finish()
|
||||||
@ -421,8 +419,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn basic_auth() {
|
async fn basic_auth() {
|
||||||
let req = Client::new()
|
let req = Client::new()
|
||||||
.ws("/")
|
.ws("/")
|
||||||
.basic_auth("username", Some("password"));
|
.basic_auth("username", Some("password"));
|
||||||
@ -448,8 +446,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn bearer_auth() {
|
async fn bearer_auth() {
|
||||||
let req = Client::new().ws("/").bearer_auth("someS3cr3tAutht0k3n");
|
let req = Client::new().ws("/").bearer_auth("someS3cr3tAutht0k3n");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
req.head
|
req.head
|
||||||
@ -463,35 +461,33 @@ mod tests {
|
|||||||
let _ = req.connect();
|
let _ = req.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn basics() {
|
async fn basics() {
|
||||||
block_on(async {
|
let req = Client::new()
|
||||||
let req = Client::new()
|
.ws("http://localhost/")
|
||||||
.ws("http://localhost/")
|
.origin("test-origin")
|
||||||
.origin("test-origin")
|
.max_frame_size(100)
|
||||||
.max_frame_size(100)
|
.server_mode()
|
||||||
.server_mode()
|
.protocols(&["v1", "v2"])
|
||||||
.protocols(&["v1", "v2"])
|
.set_header_if_none(header::CONTENT_TYPE, "json")
|
||||||
.set_header_if_none(header::CONTENT_TYPE, "json")
|
.set_header_if_none(header::CONTENT_TYPE, "text")
|
||||||
.set_header_if_none(header::CONTENT_TYPE, "text")
|
.cookie(Cookie::build("cookie1", "value1").finish());
|
||||||
.cookie(Cookie::build("cookie1", "value1").finish());
|
assert_eq!(
|
||||||
assert_eq!(
|
req.origin.as_ref().unwrap().to_str().unwrap(),
|
||||||
req.origin.as_ref().unwrap().to_str().unwrap(),
|
"test-origin"
|
||||||
"test-origin"
|
);
|
||||||
);
|
assert_eq!(req.max_size, 100);
|
||||||
assert_eq!(req.max_size, 100);
|
assert_eq!(req.server_mode, true);
|
||||||
assert_eq!(req.server_mode, true);
|
assert_eq!(req.protocols, Some("v1,v2".to_string()));
|
||||||
assert_eq!(req.protocols, Some("v1,v2".to_string()));
|
assert_eq!(
|
||||||
assert_eq!(
|
req.head.headers.get(header::CONTENT_TYPE).unwrap(),
|
||||||
req.head.headers.get(header::CONTENT_TYPE).unwrap(),
|
header::HeaderValue::from_static("json")
|
||||||
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("/").connect().await.is_err());
|
||||||
assert!(Client::new().ws("http:///test").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("hmm://test.com/").connect().await.is_err());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
use actix_http::HttpService;
|
use actix_http::HttpService;
|
||||||
use actix_http_test::{block_on, TestServer};
|
use actix_http_test::TestServer;
|
||||||
use actix_server::ssl::OpensslAcceptor;
|
use actix_server::ssl::OpensslAcceptor;
|
||||||
use actix_service::{pipeline_factory, ServiceFactory};
|
use actix_service::{pipeline_factory, ServiceFactory};
|
||||||
use actix_web::http::Version;
|
use actix_web::http::Version;
|
||||||
@ -53,57 +53,54 @@ mod danger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[actix_rt::test]
|
||||||
fn _test_connection_reuse_h2() {
|
async fn _test_connection_reuse_h2() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let num = Arc::new(AtomicUsize::new(0));
|
||||||
let num = Arc::new(AtomicUsize::new(0));
|
let num2 = num.clone();
|
||||||
let num2 = num.clone();
|
|
||||||
|
|
||||||
let srv = TestServer::start(move || {
|
let srv = TestServer::start(move || {
|
||||||
let num2 = num2.clone();
|
let num2 = num2.clone();
|
||||||
pipeline_factory(move |io| {
|
pipeline_factory(move |io| {
|
||||||
num2.fetch_add(1, Ordering::Relaxed);
|
num2.fetch_add(1, Ordering::Relaxed);
|
||||||
ok(io)
|
ok(io)
|
||||||
})
|
})
|
||||||
.and_then(
|
.and_then(
|
||||||
openssl
|
openssl
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
)
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.h2(App::new().service(
|
.h2(App::new()
|
||||||
web::resource("/").route(web::to(|| HttpResponse::Ok())),
|
.service(web::resource("/").route(web::to(|| HttpResponse::Ok()))))
|
||||||
))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// disable ssl verification
|
// disable ssl verification
|
||||||
let mut config = ClientConfig::new();
|
let mut config = ClientConfig::new();
|
||||||
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||||
config.set_protocols(&protos);
|
config.set_protocols(&protos);
|
||||||
config
|
config
|
||||||
.dangerous()
|
.dangerous()
|
||||||
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification {}));
|
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification {}));
|
||||||
|
|
||||||
let client = awc::Client::build()
|
let client = awc::Client::build()
|
||||||
.connector(awc::Connector::new().rustls(Arc::new(config)).finish())
|
.connector(awc::Connector::new().rustls(Arc::new(config)).finish())
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
// req 1
|
// req 1
|
||||||
let request = client.get(srv.surl("/")).send();
|
let request = client.get(srv.surl("/")).send();
|
||||||
let response = request.await.unwrap();
|
let response = request.await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// req 2
|
// req 2
|
||||||
let req = client.post(srv.surl("/"));
|
let req = client.post(srv.surl("/"));
|
||||||
let response = req.send().await.unwrap();
|
let response = req.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
assert_eq!(response.version(), Version::HTTP_2);
|
assert_eq!(response.version(), Version::HTTP_2);
|
||||||
|
|
||||||
// one connection
|
// one connection
|
||||||
assert_eq!(num.load(Ordering::Relaxed), 1);
|
assert_eq!(num.load(Ordering::Relaxed), 1);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_codec::{AsyncRead, AsyncWrite};
|
||||||
use actix_http::HttpService;
|
use actix_http::HttpService;
|
||||||
use actix_http_test::{block_on, TestServer};
|
use actix_http_test::TestServer;
|
||||||
use actix_server::ssl::OpensslAcceptor;
|
use actix_server::ssl::OpensslAcceptor;
|
||||||
use actix_service::{pipeline_factory, ServiceFactory};
|
use actix_service::{pipeline_factory, ServiceFactory};
|
||||||
use actix_web::http::Version;
|
use actix_web::http::Version;
|
||||||
@ -35,56 +35,53 @@ fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> Result<OpensslAcceptor<T, ()>> {
|
|||||||
Ok(actix_server::ssl::OpensslAcceptor::new(builder.build()))
|
Ok(actix_server::ssl::OpensslAcceptor::new(builder.build()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_connection_reuse_h2() {
|
async fn test_connection_reuse_h2() {
|
||||||
block_on(async {
|
let openssl = ssl_acceptor().unwrap();
|
||||||
let openssl = ssl_acceptor().unwrap();
|
let num = Arc::new(AtomicUsize::new(0));
|
||||||
let num = Arc::new(AtomicUsize::new(0));
|
let num2 = num.clone();
|
||||||
let num2 = num.clone();
|
|
||||||
|
|
||||||
let srv = TestServer::start(move || {
|
let srv = TestServer::start(move || {
|
||||||
let num2 = num2.clone();
|
let num2 = num2.clone();
|
||||||
pipeline_factory(move |io| {
|
pipeline_factory(move |io| {
|
||||||
num2.fetch_add(1, Ordering::Relaxed);
|
num2.fetch_add(1, Ordering::Relaxed);
|
||||||
ok(io)
|
ok(io)
|
||||||
})
|
})
|
||||||
.and_then(
|
.and_then(
|
||||||
openssl
|
openssl
|
||||||
.clone()
|
.clone()
|
||||||
.map_err(|e| println!("Openssl error: {}", e)),
|
.map_err(|e| println!("Openssl error: {}", e)),
|
||||||
)
|
)
|
||||||
.and_then(
|
.and_then(
|
||||||
HttpService::build()
|
HttpService::build()
|
||||||
.h2(App::new().service(
|
.h2(App::new()
|
||||||
web::resource("/").route(web::to(|| HttpResponse::Ok())),
|
.service(web::resource("/").route(web::to(|| HttpResponse::Ok()))))
|
||||||
))
|
.map_err(|_| ()),
|
||||||
.map_err(|_| ()),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// disable ssl verification
|
// disable ssl verification
|
||||||
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||||
builder.set_verify(SslVerifyMode::NONE);
|
builder.set_verify(SslVerifyMode::NONE);
|
||||||
let _ = builder
|
let _ = builder
|
||||||
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
||||||
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
||||||
|
|
||||||
let client = awc::Client::build()
|
let client = awc::Client::build()
|
||||||
.connector(awc::Connector::new().ssl(builder.build()).finish())
|
.connector(awc::Connector::new().ssl(builder.build()).finish())
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
// req 1
|
// req 1
|
||||||
let request = client.get(srv.surl("/")).send();
|
let request = client.get(srv.surl("/")).send();
|
||||||
let response = request.await.unwrap();
|
let response = request.await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
|
|
||||||
// req 2
|
// req 2
|
||||||
let req = client.post(srv.surl("/"));
|
let req = client.post(srv.surl("/"));
|
||||||
let response = req.send().await.unwrap();
|
let response = req.send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
assert_eq!(response.version(), Version::HTTP_2);
|
assert_eq!(response.version(), Version::HTTP_2);
|
||||||
|
|
||||||
// one connection
|
// one connection
|
||||||
assert_eq!(num.load(Ordering::Relaxed), 1);
|
assert_eq!(num.load(Ordering::Relaxed), 1);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::io;
|
|||||||
|
|
||||||
use actix_codec::Framed;
|
use actix_codec::Framed;
|
||||||
use actix_http::{body::BodySize, h1, ws, Error, HttpService, Request, Response};
|
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 bytes::{Bytes, BytesMut};
|
||||||
use futures::future::ok;
|
use futures::future::ok;
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
@ -28,56 +28,54 @@ async fn ws_service(req: ws::Frame) -> Result<ws::Message, io::Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_simple() {
|
async fn test_simple() {
|
||||||
block_on(async {
|
let mut srv = TestServer::start(|| {
|
||||||
let mut srv = TestServer::start(|| {
|
HttpService::build()
|
||||||
HttpService::build()
|
.upgrade(|(req, mut framed): (Request, Framed<_, _>)| {
|
||||||
.upgrade(|(req, mut framed): (Request, Framed<_, _>)| {
|
async move {
|
||||||
async move {
|
let res = ws::handshake_response(req.head()).finish();
|
||||||
let res = ws::handshake_response(req.head()).finish();
|
// send handshake response
|
||||||
// send handshake response
|
framed
|
||||||
framed
|
.send(h1::Message::Item((res.drop_body(), BodySize::None)))
|
||||||
.send(h1::Message::Item((res.drop_body(), BodySize::None)))
|
.await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
// start websocket service
|
// start websocket service
|
||||||
let framed = framed.into_framed(ws::Codec::new());
|
let framed = framed.into_framed(ws::Codec::new());
|
||||||
ws::Transport::with(framed, ws_service).await
|
ws::Transport::with(framed, ws_service).await
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finish(|_| ok::<_, Error>(Response::NotFound()))
|
.finish(|_| ok::<_, Error>(Response::NotFound()))
|
||||||
});
|
});
|
||||||
|
|
||||||
// client service
|
// client service
|
||||||
let mut framed = srv.ws().await.unwrap();
|
let mut framed = srv.ws().await.unwrap();
|
||||||
framed
|
framed
|
||||||
.send(ws::Message::Text("text".to_string()))
|
.send(ws::Message::Text("text".to_string()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let item = framed.next().await.unwrap().unwrap();
|
let item = framed.next().await.unwrap().unwrap();
|
||||||
assert_eq!(item, ws::Frame::Text(Some(BytesMut::from("text"))));
|
assert_eq!(item, ws::Frame::Text(Some(BytesMut::from("text"))));
|
||||||
|
|
||||||
framed
|
framed
|
||||||
.send(ws::Message::Binary("text".into()))
|
.send(ws::Message::Binary("text".into()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let item = framed.next().await.unwrap().unwrap();
|
let item = framed.next().await.unwrap().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
item,
|
item,
|
||||||
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
|
ws::Frame::Binary(Some(Bytes::from_static(b"text").into()))
|
||||||
);
|
);
|
||||||
|
|
||||||
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
framed.send(ws::Message::Ping("text".into())).await.unwrap();
|
||||||
let item = framed.next().await.unwrap().unwrap();
|
let item = framed.next().await.unwrap().unwrap();
|
||||||
assert_eq!(item, ws::Frame::Pong("text".to_string().into()));
|
assert_eq!(item, ws::Frame::Pong("text".to_string().into()));
|
||||||
|
|
||||||
framed
|
framed
|
||||||
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
.send(ws::Message::Close(Some(ws::CloseCode::Normal.into())))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let item = framed.next().await.unwrap().unwrap();
|
let item = framed.next().await.unwrap().unwrap();
|
||||||
assert_eq!(item, ws::Frame::Close(Some(ws::CloseCode::Normal.into())));
|
assert_eq!(item, ws::Frame::Close(Some(ws::CloseCode::Normal.into())));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
386
src/app.rs
386
src/app.rs
@ -2,12 +2,10 @@ use std::cell::RefCell;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::pin::Pin;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
|
||||||
|
|
||||||
use actix_http::body::{Body, MessageBody};
|
use actix_http::body::{Body, MessageBody};
|
||||||
use actix_service::boxed::{self, BoxedNewService};
|
use actix_service::boxed::{self, BoxServiceFactory};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, Transform,
|
apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, Transform,
|
||||||
};
|
};
|
||||||
@ -25,7 +23,7 @@ use crate::service::{
|
|||||||
ServiceResponse,
|
ServiceResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||||
type FnDataFactory =
|
type FnDataFactory =
|
||||||
Box<dyn Fn() -> LocalBoxFuture<'static, Result<Box<dyn DataFactory>, ()>>>;
|
Box<dyn Fn() -> LocalBoxFuture<'static, Result<Box<dyn DataFactory>, ()>>>;
|
||||||
|
|
||||||
@ -485,231 +483,195 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::future::{ok, Future};
|
use futures::future::ok;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::{header, HeaderValue, Method, StatusCode};
|
use crate::http::{header, HeaderValue, Method, StatusCode};
|
||||||
use crate::middleware::DefaultHeaders;
|
use crate::middleware::DefaultHeaders;
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::ServiceRequest;
|
||||||
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, Error, HttpRequest, HttpResponse};
|
use crate::{web, HttpRequest, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_default_resource() {
|
async fn test_default_resource() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new().service(web::resource("/test").to(|| HttpResponse::Ok())),
|
||||||
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<usize>| HttpResponse::Ok()),
|
||||||
|
))
|
||||||
.await;
|
.await;
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
let req = TestRequest::default().to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/blah").to_request();
|
let mut srv =
|
||||||
let resp = srv.call(req).await.unwrap();
|
init_service(App::new().data_factory(|| ok::<_, ()>(10u32)).service(
|
||||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
|
))
|
||||||
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;
|
.await;
|
||||||
|
let req = TestRequest::default().to_request();
|
||||||
let req = TestRequest::with_uri("/blah").to_request();
|
let resp = srv.call(req).await.unwrap();
|
||||||
let resp = srv.call(req).await.unwrap();
|
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
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);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_data_factory() {
|
async fn test_wrap() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv =
|
App::new()
|
||||||
init_service(App::new().data_factory(|| ok::<_, ()>(10usize)).service(
|
.wrap(
|
||||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
DefaultHeaders::new()
|
||||||
))
|
.header(header::CONTENT_TYPE, HeaderValue::from_static("0001")),
|
||||||
.await;
|
)
|
||||||
let req = TestRequest::default().to_request();
|
.route("/test", web::get().to(|| HttpResponse::Ok())),
|
||||||
let resp = srv.call(req).await.unwrap();
|
)
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
.await;
|
||||||
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
let mut srv =
|
let resp = call_service(&mut srv, req).await;
|
||||||
init_service(App::new().data_factory(|| ok::<_, ()>(10u32)).service(
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
assert_eq!(
|
||||||
))
|
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||||
.await;
|
HeaderValue::from_static("0001")
|
||||||
let req = TestRequest::default().to_request();
|
);
|
||||||
let resp = srv.call(req).await.unwrap();
|
|
||||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn md<S, B>(
|
#[actix_rt::test]
|
||||||
req: ServiceRequest,
|
async fn test_router_wrap() {
|
||||||
srv: &mut S,
|
let mut srv = init_service(
|
||||||
) -> impl Future<Output = Result<ServiceResponse<B>, Error>>
|
App::new()
|
||||||
where
|
.route("/test", web::get().to(|| HttpResponse::Ok()))
|
||||||
S: Service<
|
.wrap(
|
||||||
Request = ServiceRequest,
|
DefaultHeaders::new()
|
||||||
Response = ServiceResponse<B>,
|
.header(header::CONTENT_TYPE, HeaderValue::from_static("0001")),
|
||||||
Error = Error,
|
),
|
||||||
>,
|
)
|
||||||
{
|
.await;
|
||||||
let fut = srv.call(req);
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
async move {
|
let resp = call_service(&mut srv, req).await;
|
||||||
let mut res = fut.await?;
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
res.headers_mut()
|
assert_eq!(
|
||||||
.insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
|
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||||
Ok(res)
|
HeaderValue::from_static("0001")
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_wrap() {
|
async fn test_wrap_fn() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv =
|
App::new()
|
||||||
init_service(
|
.wrap_fn(|req, srv| {
|
||||||
App::new()
|
let fut = srv.call(req);
|
||||||
.wrap(DefaultHeaders::new().header(
|
async move {
|
||||||
|
let mut res = fut.await?;
|
||||||
|
res.headers_mut().insert(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
HeaderValue::from_static("0001"),
|
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();
|
.await;
|
||||||
let resp = call_service(&mut srv, req).await;
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
let body = read_body(resp).await;
|
||||||
HeaderValue::from_static("0001")
|
assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345"));
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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"));
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ use std::task::{Context, Poll};
|
|||||||
use actix_http::{Extensions, Request, Response};
|
use actix_http::{Extensions, Request, Response};
|
||||||
use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url};
|
use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url};
|
||||||
use actix_server_config::ServerConfig;
|
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 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::config::{AppConfig, AppService};
|
||||||
use crate::data::DataFactory;
|
use crate::data::DataFactory;
|
||||||
@ -21,9 +21,9 @@ use crate::rmap::ResourceMap;
|
|||||||
use crate::service::{AppServiceFactory, ServiceRequest, ServiceResponse};
|
use crate::service::{AppServiceFactory, ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
type Guards = Vec<Box<dyn Guard>>;
|
type Guards = Vec<Box<dyn Guard>>;
|
||||||
type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
|
type HttpService = BoxService<ServiceRequest, ServiceResponse, Error>;
|
||||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||||
type BoxedResponse = LocalBoxFuture<'static, Result<ServiceResponse, Error>>;
|
type BoxResponse = LocalBoxFuture<'static, Result<ServiceResponse, Error>>;
|
||||||
type FnDataFactory =
|
type FnDataFactory =
|
||||||
Box<dyn Fn() -> LocalBoxFuture<'static, Result<Box<dyn DataFactory>, ()>>>;
|
Box<dyn Fn() -> LocalBoxFuture<'static, Result<Box<dyn DataFactory>, ()>>>;
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ impl Service for AppRouting {
|
|||||||
type Request = ServiceRequest;
|
type Request = ServiceRequest;
|
||||||
type Response = ServiceResponse;
|
type Response = ServiceResponse;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = BoxedResponse;
|
type Future = BoxResponse;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
if self.ready.is_none() {
|
if self.ready.is_none() {
|
||||||
@ -447,13 +447,12 @@ impl ServiceFactory for AppEntry {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use actix_service::Service;
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{
|
use std::sync::Arc;
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
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<AtomicBool>);
|
struct DropData(Arc<AtomicBool>);
|
||||||
|
|
||||||
@ -463,19 +462,20 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn drop_data() {
|
async fn test_drop_data() {
|
||||||
let data = Arc::new(AtomicBool::new(false));
|
let data = Arc::new(AtomicBool::new(false));
|
||||||
test::block_on(async {
|
|
||||||
let mut app = test::init_service(
|
{
|
||||||
|
let mut app = init_service(
|
||||||
App::new()
|
App::new()
|
||||||
.data(DropData(data.clone()))
|
.data(DropData(data.clone()))
|
||||||
.service(web::resource("/test").to(|| HttpResponse::Ok())),
|
.service(web::resource("/test").to(|| HttpResponse::Ok())),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let req = test::TestRequest::with_uri("/test").to_request();
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
let _ = app.call(req).await.unwrap();
|
let _ = app.call(req).await.unwrap();
|
||||||
});
|
}
|
||||||
assert!(data.load(Ordering::Relaxed));
|
assert!(data.load(Ordering::Relaxed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
128
src/config.rs
128
src/config.rs
@ -18,7 +18,7 @@ use crate::service::{
|
|||||||
|
|
||||||
type Guards = Vec<Box<dyn Guard>>;
|
type Guards = Vec<Box<dyn Guard>>;
|
||||||
type HttpNewService =
|
type HttpNewService =
|
||||||
boxed::BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
boxed::BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||||
|
|
||||||
/// Application configuration
|
/// Application configuration
|
||||||
pub struct AppService {
|
pub struct AppService {
|
||||||
@ -246,28 +246,27 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::{Method, StatusCode};
|
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};
|
use crate::{web, App, HttpRequest, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_data() {
|
async fn test_data() {
|
||||||
block_on(async {
|
let cfg = |cfg: &mut ServiceConfig| {
|
||||||
let cfg = |cfg: &mut ServiceConfig| {
|
cfg.data(10usize);
|
||||||
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<usize>| HttpResponse::Ok()),
|
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
let req = TestRequest::default().to_request();
|
let req = TestRequest::default().to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[actix_rt::test]
|
||||||
// fn test_data_factory() {
|
// async fn test_data_factory() {
|
||||||
// let cfg = |cfg: &mut ServiceConfig| {
|
// let cfg = |cfg: &mut ServiceConfig| {
|
||||||
// cfg.data_factory(|| {
|
// cfg.data_factory(|| {
|
||||||
// sleep(std::time::Duration::from_millis(50)).then(|_| {
|
// sleep(std::time::Duration::from_millis(50)).then(|_| {
|
||||||
@ -282,7 +281,7 @@ mod tests {
|
|||||||
// web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
// web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
// ));
|
// ));
|
||||||
// let req = TestRequest::default().to_request();
|
// 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);
|
// assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
// let cfg2 = |cfg: &mut ServiceConfig| {
|
// let cfg2 = |cfg: &mut ServiceConfig| {
|
||||||
@ -294,63 +293,58 @@ mod tests {
|
|||||||
// .configure(cfg2),
|
// .configure(cfg2),
|
||||||
// );
|
// );
|
||||||
// let req = TestRequest::default().to_request();
|
// 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);
|
// assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_external_resource() {
|
async fn test_external_resource() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new()
|
||||||
App::new()
|
.configure(|cfg| {
|
||||||
.configure(|cfg| {
|
cfg.external_resource(
|
||||||
cfg.external_resource(
|
"youtube",
|
||||||
"youtube",
|
"https://youtube.com/watch/{video_id}",
|
||||||
"https://youtube.com/watch/{video_id}",
|
);
|
||||||
);
|
})
|
||||||
})
|
.route(
|
||||||
.route(
|
"/test",
|
||||||
"/test",
|
web::get().to(|req: HttpRequest| {
|
||||||
web::get().to(|req: HttpRequest| {
|
HttpResponse::Ok().body(format!(
|
||||||
HttpResponse::Ok().body(format!(
|
"{}",
|
||||||
"{}",
|
req.url_for("youtube", &["12345"]).unwrap()
|
||||||
req.url_for("youtube", &["12345"]).unwrap()
|
))
|
||||||
))
|
}),
|
||||||
}),
|
),
|
||||||
),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
let resp = call_service(&mut srv, req).await;
|
||||||
let resp = call_service(&mut srv, req).await;
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
let body = read_body(resp).await;
|
||||||
let body = read_body(resp).await;
|
assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345"));
|
||||||
assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345"));
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_service() {
|
async fn test_service() {
|
||||||
block_on(async {
|
let mut srv = init_service(App::new().configure(|cfg| {
|
||||||
let mut srv = init_service(App::new().configure(|cfg| {
|
cfg.service(
|
||||||
cfg.service(
|
web::resource("/test").route(web::get().to(|| HttpResponse::Created())),
|
||||||
web::resource("/test")
|
)
|
||||||
.route(web::get().to(|| HttpResponse::Created())),
|
.route("/index.html", web::get().to(|| HttpResponse::Ok()));
|
||||||
)
|
}))
|
||||||
.route("/index.html", web::get().to(|| HttpResponse::Ok()));
|
.await;
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::CREATED);
|
assert_eq!(resp.status(), StatusCode::CREATED);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/index.html")
|
let req = TestRequest::with_uri("/index.html")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
153
src/data.rs
153
src/data.rs
@ -139,104 +139,97 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::StatusCode;
|
use crate::http::StatusCode;
|
||||||
use crate::test::{block_on, init_service, TestRequest};
|
use crate::test::{init_service, TestRequest};
|
||||||
use crate::{web, App, HttpResponse};
|
use crate::{web, App, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_data_extractor() {
|
async fn test_data_extractor() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv = init_service(App::new().data(10usize).service(
|
init_service(App::new().data(10usize).service(
|
||||||
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let req = TestRequest::default().to_request();
|
let req = TestRequest::default().to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
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<usize>| HttpResponse::Ok()),
|
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
let req = TestRequest::default().to_request();
|
let req = TestRequest::default().to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_register_data_extractor() {
|
async fn test_register_data_extractor() {
|
||||||
block_on(async {
|
let mut srv =
|
||||||
let mut srv =
|
init_service(App::new().register_data(Data::new(10usize)).service(
|
||||||
init_service(App::new().register_data(Data::new(10usize)).service(
|
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
web::resource("/").to(|_: web::Data<usize>| 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<usize>| 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<usize>| {
|
|
||||||
let _ = data.clone();
|
|
||||||
HttpResponse::Ok()
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let req = TestRequest::default().to_request();
|
let req = TestRequest::default().to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
// different type
|
let mut srv =
|
||||||
let mut srv = init_service(
|
init_service(App::new().register_data(Data::new(10u32)).service(
|
||||||
App::new().service(
|
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
|
||||||
web::resource("/")
|
|
||||||
.data(10u32)
|
|
||||||
.route(web::get().to(|_: web::Data<usize>| 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<usize>| {
|
|
||||||
assert_eq!(*data, 10);
|
|
||||||
let _ = data.clone();
|
|
||||||
HttpResponse::Ok()
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
))
|
))
|
||||||
.await;
|
.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();
|
#[actix_rt::test]
|
||||||
let resp = srv.call(req).await.unwrap();
|
async fn test_route_data_extractor() {
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
let mut srv =
|
||||||
})
|
init_service(App::new().service(web::resource("/").data(10usize).route(
|
||||||
|
web::get().to(|data: web::Data<usize>| {
|
||||||
|
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<usize>| 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<usize>| {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ mod tests {
|
|||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
use crate::types::{Form, FormConfig};
|
use crate::types::{Form, FormConfig};
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
@ -278,8 +278,8 @@ mod tests {
|
|||||||
hello: String,
|
hello: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_option() {
|
async fn test_option() {
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
let (req, mut pl) = TestRequest::with_header(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
"application/x-www-form-urlencoded",
|
"application/x-www-form-urlencoded",
|
||||||
@ -287,7 +287,9 @@ mod tests {
|
|||||||
.data(FormConfig::default().limit(4096))
|
.data(FormConfig::default().limit(4096))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let r = block_on(Option::<Form<Info>>::from_request(&req, &mut pl)).unwrap();
|
let r = Option::<Form<Info>>::from_request(&req, &mut pl)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
assert_eq!(r, None);
|
assert_eq!(r, None);
|
||||||
|
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
let (req, mut pl) = TestRequest::with_header(
|
||||||
@ -298,7 +300,9 @@ mod tests {
|
|||||||
.set_payload(Bytes::from_static(b"hello=world"))
|
.set_payload(Bytes::from_static(b"hello=world"))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let r = block_on(Option::<Form<Info>>::from_request(&req, &mut pl)).unwrap();
|
let r = Option::<Form<Info>>::from_request(&req, &mut pl)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
r,
|
r,
|
||||||
Some(Form(Info {
|
Some(Form(Info {
|
||||||
@ -314,12 +318,14 @@ mod tests {
|
|||||||
.set_payload(Bytes::from_static(b"bye=world"))
|
.set_payload(Bytes::from_static(b"bye=world"))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let r = block_on(Option::<Form<Info>>::from_request(&req, &mut pl)).unwrap();
|
let r = Option::<Form<Info>>::from_request(&req, &mut pl)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
assert_eq!(r, None);
|
assert_eq!(r, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_result() {
|
async fn test_result() {
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
let (req, mut pl) = TestRequest::with_header(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
"application/x-www-form-urlencoded",
|
"application/x-www-form-urlencoded",
|
||||||
@ -328,7 +334,8 @@ mod tests {
|
|||||||
.set_payload(Bytes::from_static(b"hello=world"))
|
.set_payload(Bytes::from_static(b"hello=world"))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let r = block_on(Result::<Form<Info>, Error>::from_request(&req, &mut pl))
|
let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
|
||||||
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -346,8 +353,9 @@ mod tests {
|
|||||||
.set_payload(Bytes::from_static(b"bye=world"))
|
.set_payload(Bytes::from_static(b"bye=world"))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let r =
|
let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
|
||||||
block_on(Result::<Form<Info>, Error>::from_request(&req, &mut pl)).unwrap();
|
.await
|
||||||
|
.unwrap();
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
src/lib.rs
25
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
|
//! Actix web is a small, pragmatic, and extremely fast web framework
|
||||||
//! for Rust.
|
//! for Rust.
|
||||||
//!
|
//!
|
||||||
@ -143,9 +143,9 @@ pub mod dev {
|
|||||||
HttpServiceFactory, ServiceRequest, ServiceResponse, WebService,
|
HttpServiceFactory, ServiceRequest, ServiceResponse, WebService,
|
||||||
};
|
};
|
||||||
|
|
||||||
//pub use crate::types::form::UrlEncoded;
|
pub use crate::types::form::UrlEncoded;
|
||||||
//pub use crate::types::json::JsonBody;
|
pub use crate::types::json::JsonBody;
|
||||||
//pub use crate::types::readlines::Readlines;
|
pub use crate::types::readlines::Readlines;
|
||||||
|
|
||||||
pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody, SizedStream};
|
pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody, SizedStream};
|
||||||
pub use actix_http::encoding::Decoder as Decompress;
|
pub use actix_http::encoding::Decoder as Decompress;
|
||||||
@ -174,17 +174,16 @@ pub mod client {
|
|||||||
//! use actix_rt::System;
|
//! use actix_rt::System;
|
||||||
//! use actix_web::client::Client;
|
//! use actix_web::client::Client;
|
||||||
//!
|
//!
|
||||||
//! fn main() {
|
//! #[actix_rt::main]
|
||||||
//! System::new("test").block_on(async {
|
//! async fn main() {
|
||||||
//! let mut client = Client::default();
|
//! let mut client = Client::default();
|
||||||
//!
|
//!
|
||||||
//! // Create request builder and send request
|
//! // Create request builder and send request
|
||||||
//! let response = client.get("http://www.rust-lang.org")
|
//! let response = client.get("http://www.rust-lang.org")
|
||||||
//! .header("User-Agent", "Actix-web")
|
//! .header("User-Agent", "Actix-web")
|
||||||
//! .send().await; // <- Send http request
|
//! .send().await; // <- Send http request
|
||||||
//!
|
//!
|
||||||
//! println!("Response: {:?}", response);
|
//! println!("Response: {:?}", response);
|
||||||
//! });
|
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
pub use awc::error::{
|
pub use awc::error::{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_service::{Service, Transform};
|
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.
|
/// `Middleware` for conditionally enables another middleware.
|
||||||
/// The controled middleware must not change the `Service` interfaces.
|
/// The controled middleware must not change the `Service` interfaces.
|
||||||
@ -102,7 +102,7 @@ mod tests {
|
|||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
|
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
|
||||||
use crate::middleware::errhandlers::*;
|
use crate::middleware::errhandlers::*;
|
||||||
use crate::test::{self, block_on, TestRequest};
|
use crate::test::{self, TestRequest};
|
||||||
use crate::HttpResponse;
|
use crate::HttpResponse;
|
||||||
|
|
||||||
fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
@ -112,46 +112,40 @@ mod tests {
|
|||||||
Ok(ErrorHandlerResponse::Response(res))
|
Ok(ErrorHandlerResponse::Response(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_handler_enabled() {
|
async fn test_handler_enabled() {
|
||||||
block_on(async {
|
let srv = |req: ServiceRequest| {
|
||||||
let srv = |req: ServiceRequest| {
|
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||||
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mw = ErrorHandlers::new()
|
let mw =
|
||||||
.handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||||
|
|
||||||
let mut mw = Condition::new(true, mw)
|
let mut mw = Condition::new(true, mw)
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let resp =
|
let resp =
|
||||||
test::call_service(&mut mw, TestRequest::default().to_srv_request())
|
test::call_service(&mut mw, TestRequest::default().to_srv_request()).await;
|
||||||
.await;
|
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_handler_disabled() {
|
async fn test_handler_disabled() {
|
||||||
block_on(async {
|
let srv = |req: ServiceRequest| {
|
||||||
let srv = |req: ServiceRequest| {
|
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||||
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mw = ErrorHandlers::new()
|
let mw =
|
||||||
.handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||||
|
|
||||||
let mut mw = Condition::new(false, mw)
|
let mut mw = Condition::new(false, mw)
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let resp =
|
let resp =
|
||||||
test::call_service(&mut mw, TestRequest::default().to_srv_request())
|
test::call_service(&mut mw, TestRequest::default().to_srv_request()).await;
|
||||||
.await;
|
assert_eq!(resp.headers().get(CONTENT_TYPE), None);
|
||||||
assert_eq!(resp.headers().get(CONTENT_TYPE), None);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
//! Middleware for setting default response headers
|
//! Middleware for setting default response headers
|
||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
@ -161,55 +159,50 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::dev::ServiceRequest;
|
use crate::dev::ServiceRequest;
|
||||||
use crate::http::header::CONTENT_TYPE;
|
use crate::http::header::CONTENT_TYPE;
|
||||||
use crate::test::{block_on, ok_service, TestRequest};
|
use crate::test::{ok_service, TestRequest};
|
||||||
use crate::HttpResponse;
|
use crate::HttpResponse;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_default_headers() {
|
async fn test_default_headers() {
|
||||||
block_on(async {
|
let mut mw = DefaultHeaders::new()
|
||||||
let mut mw = DefaultHeaders::new()
|
.header(CONTENT_TYPE, "0001")
|
||||||
.header(CONTENT_TYPE, "0001")
|
.new_transform(ok_service())
|
||||||
.new_transform(ok_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::default().to_srv_request();
|
let req = TestRequest::default().to_srv_request();
|
||||||
let resp = mw.call(req).await.unwrap();
|
let resp = mw.call(req).await.unwrap();
|
||||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||||
|
|
||||||
let req = TestRequest::default().to_srv_request();
|
let req = TestRequest::default().to_srv_request();
|
||||||
let srv = |req: ServiceRequest| {
|
let srv = |req: ServiceRequest| {
|
||||||
ok(req.into_response(
|
ok(req
|
||||||
HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish(),
|
.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish()))
|
||||||
))
|
};
|
||||||
};
|
let mut mw = DefaultHeaders::new()
|
||||||
let mut mw = DefaultHeaders::new()
|
.header(CONTENT_TYPE, "0001")
|
||||||
.header(CONTENT_TYPE, "0001")
|
.new_transform(srv.into_service())
|
||||||
.new_transform(srv.into_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
let resp = mw.call(req).await.unwrap();
|
||||||
let resp = mw.call(req).await.unwrap();
|
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
|
||||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_content_type() {
|
async fn test_content_type() {
|
||||||
block_on(async {
|
let srv =
|
||||||
let srv =
|
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish()));
|
||||||
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish()));
|
let mut mw = DefaultHeaders::new()
|
||||||
let mut mw = DefaultHeaders::new()
|
.content_type()
|
||||||
.content_type()
|
.new_transform(srv.into_service())
|
||||||
.new_transform(srv.into_service())
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let req = TestRequest::default().to_srv_request();
|
let req = TestRequest::default().to_srv_request();
|
||||||
let resp = mw.call(req).await.unwrap();
|
let resp = mw.call(req).await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
"application/octet-stream"
|
"application/octet-stream"
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use std::rc::Rc;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_service::{Service, Transform};
|
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 hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::dev::{ServiceRequest, ServiceResponse};
|
use crate::dev::{ServiceRequest, ServiceResponse};
|
||||||
@ -151,7 +151,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
|
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
|
||||||
use crate::test::{self, block_on, TestRequest};
|
use crate::test::{self, TestRequest};
|
||||||
use crate::HttpResponse;
|
use crate::HttpResponse;
|
||||||
|
|
||||||
fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
@ -161,24 +161,21 @@ mod tests {
|
|||||||
Ok(ErrorHandlerResponse::Response(res))
|
Ok(ErrorHandlerResponse::Response(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_handler() {
|
async fn test_handler() {
|
||||||
block_on(async {
|
let srv = |req: ServiceRequest| {
|
||||||
let srv = |req: ServiceRequest| {
|
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||||
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mut mw = ErrorHandlers::new()
|
let mut mw = ErrorHandlers::new()
|
||||||
.handler(StatusCode::INTERNAL_SERVER_ERROR, render_500)
|
.handler(StatusCode::INTERNAL_SERVER_ERROR, render_500)
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let resp =
|
let resp =
|
||||||
test::call_service(&mut mw, TestRequest::default().to_srv_request())
|
test::call_service(&mut mw, TestRequest::default().to_srv_request()).await;
|
||||||
.await;
|
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_500_async<B: 'static>(
|
fn render_500_async<B: 'static>(
|
||||||
@ -190,23 +187,20 @@ mod tests {
|
|||||||
Ok(ErrorHandlerResponse::Future(ok(res).boxed_local()))
|
Ok(ErrorHandlerResponse::Future(ok(res).boxed_local()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_handler_async() {
|
async fn test_handler_async() {
|
||||||
block_on(async {
|
let srv = |req: ServiceRequest| {
|
||||||
let srv = |req: ServiceRequest| {
|
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
||||||
ok(req.into_response(HttpResponse::InternalServerError().finish()))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mut mw = ErrorHandlers::new()
|
let mut mw = ErrorHandlers::new()
|
||||||
.handler(StatusCode::INTERNAL_SERVER_ERROR, render_500_async)
|
.handler(StatusCode::INTERNAL_SERVER_ERROR, render_500_async)
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let resp =
|
let resp =
|
||||||
test::call_service(&mut mw, TestRequest::default().to_srv_request())
|
test::call_service(&mut mw, TestRequest::default().to_srv_request()).await;
|
||||||
.await;
|
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
||||||
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,10 +479,10 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::{header, StatusCode};
|
use crate::http::{header, StatusCode};
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_logger() {
|
async fn test_logger() {
|
||||||
let srv = |req: ServiceRequest| {
|
let srv = |req: ServiceRequest| {
|
||||||
ok(req.into_response(
|
ok(req.into_response(
|
||||||
HttpResponse::build(StatusCode::OK)
|
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 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(
|
let req = TestRequest::with_header(
|
||||||
header::USER_AGENT,
|
header::USER_AGENT,
|
||||||
header::HeaderValue::from_static("ACTIX-WEB"),
|
header::HeaderValue::from_static("ACTIX-WEB"),
|
||||||
)
|
)
|
||||||
.to_srv_request();
|
.to_srv_request();
|
||||||
let _res = block_on(srv.call(req));
|
let _res = srv.call(req).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_url_path() {
|
async fn test_url_path() {
|
||||||
let mut format = Format::new("%T %U");
|
let mut format = Format::new("%T %U");
|
||||||
let req = TestRequest::with_header(
|
let req = TestRequest::with_header(
|
||||||
header::USER_AGENT,
|
header::USER_AGENT,
|
||||||
@ -533,8 +533,8 @@ mod tests {
|
|||||||
assert!(s.contains("/test/route/yeah"));
|
assert!(s.contains("/test/route/yeah"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_default_format() {
|
async fn test_default_format() {
|
||||||
let mut format = Format::default();
|
let mut format = Format::default();
|
||||||
|
|
||||||
let req = TestRequest::with_header(
|
let req = TestRequest::with_header(
|
||||||
@ -566,8 +566,8 @@ mod tests {
|
|||||||
assert!(s.contains("ACTIX-WEB"));
|
assert!(s.contains("ACTIX-WEB"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_request_time_format() {
|
async fn test_request_time_format() {
|
||||||
let mut format = Format::new("%t");
|
let mut format = Format::new("%t");
|
||||||
let req = TestRequest::default().to_srv_request();
|
let req = TestRequest::default().to_srv_request();
|
||||||
|
|
||||||
|
@ -105,62 +105,56 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::dev::ServiceRequest;
|
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};
|
use crate::{web, App, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_wrap() {
|
async fn test_wrap() {
|
||||||
block_on(async {
|
let mut app = init_service(
|
||||||
let mut app = init_service(
|
App::new()
|
||||||
App::new()
|
.wrap(NormalizePath::default())
|
||||||
.wrap(NormalizePath::default())
|
.service(web::resource("/v1/something/").to(|| HttpResponse::Ok())),
|
||||||
.service(web::resource("/v1/something/").to(|| HttpResponse::Ok())),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/v1//something////").to_request();
|
let req = TestRequest::with_uri("/v1//something////").to_request();
|
||||||
let res = call_service(&mut app, req).await;
|
let res = call_service(&mut app, req).await;
|
||||||
assert!(res.status().is_success());
|
assert!(res.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_in_place_normalization() {
|
async fn test_in_place_normalization() {
|
||||||
block_on(async {
|
let srv = |req: ServiceRequest| {
|
||||||
let srv = |req: ServiceRequest| {
|
assert_eq!("/v1/something/", req.path());
|
||||||
assert_eq!("/v1/something/", req.path());
|
ok(req.into_response(HttpResponse::Ok().finish()))
|
||||||
ok(req.into_response(HttpResponse::Ok().finish()))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mut normalize = NormalizePath
|
let mut normalize = NormalizePath
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/v1//something////").to_srv_request();
|
let req = TestRequest::with_uri("/v1//something////").to_srv_request();
|
||||||
let res = normalize.call(req).await.unwrap();
|
let res = normalize.call(req).await.unwrap();
|
||||||
assert!(res.status().is_success());
|
assert!(res.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn should_normalize_nothing() {
|
async fn should_normalize_nothing() {
|
||||||
block_on(async {
|
const URI: &str = "/v1/something/";
|
||||||
const URI: &str = "/v1/something/";
|
|
||||||
|
|
||||||
let srv = |req: ServiceRequest| {
|
let srv = |req: ServiceRequest| {
|
||||||
assert_eq!(URI, req.path());
|
assert_eq!(URI, req.path());
|
||||||
ok(req.into_response(HttpResponse::Ok().finish()))
|
ok(req.into_response(HttpResponse::Ok().finish()))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut normalize = NormalizePath
|
let mut normalize = NormalizePath
|
||||||
.new_transform(srv.into_service())
|
.new_transform(srv.into_service())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let req = TestRequest::with_uri(URI).to_srv_request();
|
let req = TestRequest::with_uri(URI).to_srv_request();
|
||||||
let res = normalize.call(req).await.unwrap();
|
let res = normalize.call(req).await.unwrap();
|
||||||
assert!(res.status().is_success());
|
assert!(res.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
122
src/request.rs
122
src/request.rs
@ -350,7 +350,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::dev::{ResourceDef, ResourceMap};
|
use crate::dev::{ResourceDef, ResourceMap};
|
||||||
use crate::http::{header, StatusCode};
|
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};
|
use crate::{web, App, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -466,16 +466,62 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_app_data() {
|
async fn test_app_data() {
|
||||||
block_on(async {
|
let mut srv = init_service(App::new().data(10usize).service(
|
||||||
let mut srv = init_service(App::new().data(10usize).service(
|
web::resource("/").to(|req: HttpRequest| {
|
||||||
web::resource("/").to(|req: HttpRequest| {
|
if req.app_data::<usize>().is_some() {
|
||||||
if req.app_data::<usize>().is_some() {
|
HttpResponse::Ok()
|
||||||
HttpResponse::Ok()
|
} else {
|
||||||
} else {
|
HttpResponse::BadRequest()
|
||||||
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::<usize>().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<RefCell<Tracker>>,
|
||||||
|
}
|
||||||
|
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;
|
.await;
|
||||||
@ -483,58 +529,8 @@ mod tests {
|
|||||||
let req = TestRequest::default().to_request();
|
let req = TestRequest::default().to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
let mut srv = init_service(App::new().data(10u32).service(
|
assert!(tracker.borrow().dropped);
|
||||||
web::resource("/").to(|req: HttpRequest| {
|
|
||||||
if req.app_data::<usize>().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<RefCell<Tracker>>,
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
357
src/resource.rs
357
src/resource.rs
@ -6,12 +6,11 @@ use std::rc::Rc;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_http::{Error, Extensions, Response};
|
use actix_http::{Error, Extensions, Response};
|
||||||
use actix_service::boxed::{self, BoxedNewService, BoxedService};
|
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform,
|
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform,
|
||||||
};
|
};
|
||||||
use futures::future::{ok, Either, LocalBoxFuture, Ready};
|
use futures::future::{ok, Either, LocalBoxFuture, Ready};
|
||||||
use pin_project::pin_project;
|
|
||||||
|
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
use crate::dev::{insert_slash, AppService, HttpServiceFactory, ResourceDef};
|
use crate::dev::{insert_slash, AppService, HttpServiceFactory, ResourceDef};
|
||||||
@ -22,8 +21,8 @@ use crate::responder::Responder;
|
|||||||
use crate::route::{CreateRouteService, Route, RouteService};
|
use crate::route::{CreateRouteService, Route, RouteService};
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::{ServiceRequest, ServiceResponse};
|
||||||
|
|
||||||
type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
|
type HttpService = BoxService<ServiceRequest, ServiceResponse, Error>;
|
||||||
type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
|
type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||||
|
|
||||||
/// *Resource* is an entry in resources table which corresponds to requested URL.
|
/// *Resource* is an entry in resources table which corresponds to requested URL.
|
||||||
///
|
///
|
||||||
@ -585,40 +584,20 @@ impl ServiceFactory for ResourceEndpoint {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use actix_rt::time::delay_for;
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
use futures::future::{ok, Future};
|
use futures::future::ok;
|
||||||
use tokio_timer::delay_for;
|
|
||||||
|
|
||||||
use crate::http::{header, HeaderValue, Method, StatusCode};
|
use crate::http::{header, HeaderValue, Method, StatusCode};
|
||||||
use crate::middleware::DefaultHeaders;
|
use crate::middleware::DefaultHeaders;
|
||||||
use crate::service::{ServiceRequest, ServiceResponse};
|
use crate::service::ServiceRequest;
|
||||||
use crate::test::{block_on, call_service, init_service, TestRequest};
|
use crate::test::{call_service, init_service, TestRequest};
|
||||||
use crate::{guard, web, App, Error, HttpResponse};
|
use crate::{guard, web, App, Error, HttpResponse};
|
||||||
|
|
||||||
fn md<S, B>(
|
#[actix_rt::test]
|
||||||
req: ServiceRequest,
|
async fn test_middleware() {
|
||||||
srv: &mut S,
|
let mut srv =
|
||||||
) -> impl Future<Output = Result<ServiceResponse<B>, Error>>
|
init_service(
|
||||||
where
|
|
||||||
S: Service<
|
|
||||||
Request = ServiceRequest,
|
|
||||||
Response = ServiceResponse<B>,
|
|
||||||
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(
|
|
||||||
App::new().service(
|
App::new().service(
|
||||||
web::resource("/test")
|
web::resource("/test")
|
||||||
.name("test")
|
.name("test")
|
||||||
@ -630,185 +609,173 @@ mod tests {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||||
HeaderValue::from_static("0001")
|
HeaderValue::from_static("0001")
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_middleware_fn() {
|
async fn test_middleware_fn() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new().service(
|
||||||
App::new().service(
|
web::resource("/test")
|
||||||
web::resource("/test")
|
.wrap_fn(|req, srv| {
|
||||||
.wrap_fn(|req, srv| {
|
let fut = srv.call(req);
|
||||||
let fut = srv.call(req);
|
async {
|
||||||
async {
|
fut.await.map(|mut res| {
|
||||||
fut.await.map(|mut res| {
|
res.headers_mut().insert(
|
||||||
res.headers_mut().insert(
|
header::CONTENT_TYPE,
|
||||||
header::CONTENT_TYPE,
|
HeaderValue::from_static("0001"),
|
||||||
HeaderValue::from_static("0001"),
|
);
|
||||||
);
|
res
|
||||||
res
|
})
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
})
|
.route(web::get().to(|| HttpResponse::Ok())),
|
||||||
.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;
|
.await;
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(
|
|
||||||
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
|
||||||
HeaderValue::from_static("0001")
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_to() {
|
async fn test_default_resource() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv =
|
App::new()
|
||||||
init_service(App::new().service(web::resource("/test").to(|| {
|
.service(
|
||||||
async {
|
web::resource("/test").route(web::get().to(|| HttpResponse::Ok())),
|
||||||
delay_for(Duration::from_millis(100)).await;
|
)
|
||||||
Ok::<_, Error>(HttpResponse::Ok())
|
.default_service(|r: ServiceRequest| {
|
||||||
}
|
ok(r.into_response(HttpResponse::BadRequest()))
|
||||||
})))
|
}),
|
||||||
.await;
|
)
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
.await;
|
||||||
let resp = call_service(&mut srv, req).await;
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
let resp = call_service(&mut srv, req).await;
|
||||||
})
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
let req = TestRequest::with_uri("/test")
|
||||||
fn test_default_resource() {
|
.method(Method::POST)
|
||||||
block_on(async {
|
.to_request();
|
||||||
let mut srv = init_service(
|
let resp = call_service(&mut srv, req).await;
|
||||||
App::new()
|
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||||
.service(
|
|
||||||
web::resource("/test")
|
let mut srv = init_service(
|
||||||
.route(web::get().to(|| HttpResponse::Ok())),
|
App::new().service(
|
||||||
)
|
web::resource("/test")
|
||||||
|
.route(web::get().to(|| HttpResponse::Ok()))
|
||||||
.default_service(|r: ServiceRequest| {
|
.default_service(|r: ServiceRequest| {
|
||||||
ok(r.into_response(HttpResponse::BadRequest()))
|
ok(r.into_response(HttpResponse::BadRequest()))
|
||||||
}),
|
}),
|
||||||
)
|
),
|
||||||
.await;
|
)
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
.await;
|
||||||
let resp = call_service(&mut srv, req).await;
|
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
.method(Method::POST)
|
let resp = call_service(&mut srv, req).await;
|
||||||
.to_request();
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
let resp = call_service(&mut srv, req).await;
|
|
||||||
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
|
|
||||||
|
|
||||||
let mut srv = init_service(
|
let req = TestRequest::with_uri("/test")
|
||||||
App::new().service(
|
.method(Method::POST)
|
||||||
web::resource("/test")
|
.to_request();
|
||||||
.route(web::get().to(|| HttpResponse::Ok()))
|
let resp = call_service(&mut srv, req).await;
|
||||||
.default_service(|r: ServiceRequest| {
|
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||||
ok(r.into_response(HttpResponse::BadRequest()))
|
}
|
||||||
}),
|
|
||||||
|
#[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 req = TestRequest::with_uri("/test/it")
|
||||||
let resp = call_service(&mut srv, req).await;
|
.method(Method::GET)
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
.to_request();
|
||||||
|
let resp = call_service(&mut srv, req).await;
|
||||||
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test/it")
|
||||||
.method(Method::POST)
|
.method(Method::PUT)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
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]
|
#[actix_rt::test]
|
||||||
fn test_resource_guards() {
|
async fn test_data() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new()
|
||||||
App::new()
|
.data(1.0f64)
|
||||||
.service(
|
.data(1usize)
|
||||||
web::resource("/test/{p}")
|
.register_data(web::Data::new('-'))
|
||||||
.guard(guard::Get())
|
.service(
|
||||||
.to(|| HttpResponse::Ok()),
|
web::resource("/test")
|
||||||
)
|
.data(10usize)
|
||||||
.service(
|
.register_data(web::Data::new('*'))
|
||||||
web::resource("/test/{p}")
|
.guard(guard::Get())
|
||||||
.guard(guard::Put())
|
.to(
|
||||||
.to(|| HttpResponse::Created()),
|
|data1: web::Data<usize>,
|
||||||
)
|
data2: web::Data<char>,
|
||||||
.service(
|
data3: web::Data<f64>| {
|
||||||
web::resource("/test/{p}")
|
assert_eq!(*data1, 10);
|
||||||
.guard(guard::Delete())
|
assert_eq!(*data2, '*');
|
||||||
.to(|| HttpResponse::NoContent()),
|
assert_eq!(*data3, 1.0);
|
||||||
),
|
HttpResponse::Ok()
|
||||||
)
|
},
|
||||||
.await;
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test/it")
|
let req = TestRequest::get().uri("/test").to_request();
|
||||||
.method(Method::GET)
|
let resp = call_service(&mut srv, req).await;
|
||||||
.to_request();
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
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<usize>,
|
|
||||||
data2: web::Data<char>,
|
|
||||||
data3: web::Data<f64>| {
|
|
||||||
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);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
308
src/responder.rs
308
src/responder.rs
@ -10,7 +10,7 @@ use actix_http::http::{
|
|||||||
};
|
};
|
||||||
use actix_http::{Error, Response, ResponseBuilder};
|
use actix_http::{Error, Response, ResponseBuilder};
|
||||||
use bytes::{Bytes, BytesMut};
|
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 futures::ready;
|
||||||
use pin_project::{pin_project, project};
|
use pin_project::{pin_project, project};
|
||||||
|
|
||||||
@ -457,37 +457,34 @@ pub(crate) mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::dev::{Body, ResponseBody};
|
use crate::dev::{Body, ResponseBody};
|
||||||
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
|
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};
|
use crate::{error, web, App, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_option_responder() {
|
async fn test_option_responder() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new()
|
||||||
App::new()
|
.service(
|
||||||
.service(
|
web::resource("/none").to(|| async { Option::<&'static str>::None }),
|
||||||
web::resource("/none")
|
)
|
||||||
.to(|| async { Option::<&'static str>::None }),
|
.service(web::resource("/some").to(|| async { Some("some") })),
|
||||||
)
|
)
|
||||||
.service(web::resource("/some").to(|| async { Some("some") })),
|
.await;
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/none").to_request();
|
let req = TestRequest::with_uri("/none").to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/some").to_request();
|
let req = TestRequest::with_uri("/some").to_request();
|
||||||
let resp = srv.call(req).await.unwrap();
|
let resp = srv.call(req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
match resp.response().body() {
|
match resp.response().body() {
|
||||||
ResponseBody::Body(Body::Bytes(ref b)) => {
|
ResponseBody::Body(Body::Bytes(ref b)) => {
|
||||||
let bytes: Bytes = b.clone().into();
|
let bytes: Bytes = b.clone().into();
|
||||||
assert_eq!(bytes, Bytes::from_static(b"some"));
|
assert_eq!(bytes, Bytes::from_static(b"some"));
|
||||||
}
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
}
|
||||||
})
|
_ => panic!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait BodyTest {
|
pub(crate) trait BodyTest {
|
||||||
@ -516,153 +513,142 @@ pub(crate) mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_responder() {
|
async fn test_responder() {
|
||||||
block_on(async {
|
let req = TestRequest::default().to_http_request();
|
||||||
let req = TestRequest::default().to_http_request();
|
|
||||||
|
|
||||||
let resp: HttpResponse = "test".respond_to(&req).await.unwrap();
|
let resp: HttpResponse = "test".respond_to(&req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(resp.body().bin_ref(), b"test");
|
assert_eq!(resp.body().bin_ref(), b"test");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
HeaderValue::from_static("text/plain; charset=utf-8")
|
HeaderValue::from_static("text/plain; charset=utf-8")
|
||||||
);
|
);
|
||||||
|
|
||||||
let resp: HttpResponse = b"test".respond_to(&req).await.unwrap();
|
let resp: HttpResponse = b"test".respond_to(&req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(resp.body().bin_ref(), b"test");
|
assert_eq!(resp.body().bin_ref(), b"test");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
HeaderValue::from_static("application/octet-stream")
|
HeaderValue::from_static("application/octet-stream")
|
||||||
);
|
);
|
||||||
|
|
||||||
let resp: HttpResponse = "test".to_string().respond_to(&req).await.unwrap();
|
let resp: HttpResponse = "test".to_string().respond_to(&req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(resp.body().bin_ref(), b"test");
|
assert_eq!(resp.body().bin_ref(), b"test");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
HeaderValue::from_static("text/plain; charset=utf-8")
|
HeaderValue::from_static("text/plain; charset=utf-8")
|
||||||
);
|
);
|
||||||
|
|
||||||
let resp: HttpResponse =
|
let resp: HttpResponse = (&"test".to_string()).respond_to(&req).await.unwrap();
|
||||||
(&"test".to_string()).respond_to(&req).await.unwrap();
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.body().bin_ref(), b"test");
|
||||||
assert_eq!(resp.body().bin_ref(), b"test");
|
assert_eq!(
|
||||||
assert_eq!(
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
HeaderValue::from_static("text/plain; charset=utf-8")
|
||||||
HeaderValue::from_static("text/plain; charset=utf-8")
|
);
|
||||||
);
|
|
||||||
|
|
||||||
let resp: HttpResponse =
|
let resp: HttpResponse =
|
||||||
Bytes::from_static(b"test").respond_to(&req).await.unwrap();
|
Bytes::from_static(b"test").respond_to(&req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(resp.body().bin_ref(), b"test");
|
assert_eq!(resp.body().bin_ref(), b"test");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
HeaderValue::from_static("application/octet-stream")
|
HeaderValue::from_static("application/octet-stream")
|
||||||
);
|
);
|
||||||
|
|
||||||
let resp: HttpResponse = BytesMut::from(b"test".as_ref())
|
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<I, E>
|
|
||||||
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::<String, _>(error::InternalError::new(
|
|
||||||
"err",
|
|
||||||
StatusCode::BAD_REQUEST,
|
|
||||||
))
|
|
||||||
.respond_to(&req)
|
.respond_to(&req)
|
||||||
.await;
|
.await
|
||||||
assert!(res.is_err());
|
.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]
|
#[actix_rt::test]
|
||||||
fn test_custom_responder() {
|
async fn test_result_responder() {
|
||||||
block_on(async {
|
let req = TestRequest::default().to_http_request();
|
||||||
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 res = "test"
|
// Result<I, E>
|
||||||
.to_string()
|
let resp: HttpResponse = Ok::<_, Error>("test".to_string())
|
||||||
.with_header("content-type", "json")
|
.respond_to(&req)
|
||||||
.respond_to(&req)
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.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);
|
let res =
|
||||||
assert_eq!(res.body().bin_ref(), b"test");
|
Err::<String, _>(error::InternalError::new("err", StatusCode::BAD_REQUEST))
|
||||||
assert_eq!(
|
.respond_to(&req)
|
||||||
res.headers().get(CONTENT_TYPE).unwrap(),
|
.await;
|
||||||
HeaderValue::from_static("json")
|
assert!(res.is_err());
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_tuple_responder_with_status_code() {
|
async fn test_custom_responder() {
|
||||||
block_on(async {
|
let req = TestRequest::default().to_http_request();
|
||||||
let req = TestRequest::default().to_http_request();
|
let res = "test"
|
||||||
let res = ("test".to_string(), StatusCode::BAD_REQUEST)
|
.to_string()
|
||||||
.respond_to(&req)
|
.with_status(StatusCode::BAD_REQUEST)
|
||||||
.await
|
.respond_to(&req)
|
||||||
.unwrap();
|
.await
|
||||||
assert_eq!(res.status(), StatusCode::BAD_REQUEST);
|
.unwrap();
|
||||||
assert_eq!(res.body().bin_ref(), b"test");
|
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"
|
||||||
let res = ("test".to_string(), StatusCode::OK)
|
.to_string()
|
||||||
.with_header("content-type", "json")
|
.with_header("content-type", "json")
|
||||||
.respond_to(&req)
|
.respond_to(&req)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res.status(), StatusCode::OK);
|
|
||||||
assert_eq!(res.body().bin_ref(), b"test");
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
assert_eq!(
|
assert_eq!(res.body().bin_ref(), b"test");
|
||||||
res.headers().get(CONTENT_TYPE).unwrap(),
|
assert_eq!(
|
||||||
HeaderValue::from_static("json")
|
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")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
141
src/route.rs
141
src/route.rs
@ -5,7 +5,7 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
use actix_http::{http::Method, Error};
|
use actix_http::{http::Method, Error};
|
||||||
use actix_service::{Service, ServiceFactory};
|
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::extract::FromRequest;
|
||||||
use crate::guard::{self, Guard};
|
use crate::guard::{self, Guard};
|
||||||
@ -342,93 +342,90 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use actix_rt::time::delay_for;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::Future;
|
|
||||||
use serde_derive::Serialize;
|
use serde_derive::Serialize;
|
||||||
use tokio_timer::delay_for;
|
|
||||||
|
|
||||||
use crate::http::{Method, StatusCode};
|
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::{error, web, App, Error, HttpResponse};
|
use crate::{error, web, App, HttpResponse};
|
||||||
|
|
||||||
#[derive(Serialize, PartialEq, Debug)]
|
#[derive(Serialize, PartialEq, Debug)]
|
||||||
struct MyObject {
|
struct MyObject {
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_route() {
|
async fn test_route() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new()
|
||||||
App::new()
|
.service(
|
||||||
.service(
|
web::resource("/test")
|
||||||
web::resource("/test")
|
.route(web::get().to(|| HttpResponse::Ok()))
|
||||||
.route(web::get().to(|| HttpResponse::Ok()))
|
.route(web::put().to(|| {
|
||||||
.route(web::put().to(|| {
|
async {
|
||||||
async {
|
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
}
|
||||||
}
|
}))
|
||||||
}))
|
.route(web::post().to(|| {
|
||||||
.route(web::post().to(|| {
|
async {
|
||||||
async {
|
delay_for(Duration::from_millis(100)).await;
|
||||||
delay_for(Duration::from_millis(100)).await;
|
HttpResponse::Created()
|
||||||
HttpResponse::Created()
|
}
|
||||||
}
|
}))
|
||||||
}))
|
.route(web::delete().to(|| {
|
||||||
.route(web::delete().to(|| {
|
async {
|
||||||
async {
|
delay_for(Duration::from_millis(100)).await;
|
||||||
delay_for(Duration::from_millis(100)).await;
|
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
||||||
Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
|
}
|
||||||
}
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.service(web::resource("/json").route(web::get().to(|| {
|
||||||
.service(web::resource("/json").route(web::get().to(|| {
|
async {
|
||||||
async {
|
delay_for(Duration::from_millis(25)).await;
|
||||||
delay_for(Duration::from_millis(25)).await;
|
web::Json(MyObject {
|
||||||
web::Json(MyObject {
|
name: "test".to_string(),
|
||||||
name: "test".to_string(),
|
})
|
||||||
})
|
}
|
||||||
}
|
}))),
|
||||||
}))),
|
)
|
||||||
)
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test")
|
||||||
.method(Method::GET)
|
.method(Method::GET)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test")
|
||||||
.method(Method::POST)
|
.method(Method::POST)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::CREATED);
|
assert_eq!(resp.status(), StatusCode::CREATED);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test")
|
||||||
.method(Method::PUT)
|
.method(Method::PUT)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test")
|
||||||
.method(Method::DELETE)
|
.method(Method::DELETE)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test")
|
let req = TestRequest::with_uri("/test")
|
||||||
.method(Method::HEAD)
|
.method(Method::HEAD)
|
||||||
.to_request();
|
.to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
|
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/json").to_request();
|
let req = TestRequest::with_uri("/json").to_request();
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
let body = read_body(resp).await;
|
let body = read_body(resp).await;
|
||||||
assert_eq!(body, Bytes::from_static(b"{\"name\":\"test\"}"));
|
assert_eq!(body, Bytes::from_static(b"{\"name\":\"test\"}"));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1103
src/scope.rs
1103
src/scope.rs
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,6 @@ use actix_http::{
|
|||||||
};
|
};
|
||||||
use actix_router::{Path, Resource, ResourceDef, Url};
|
use actix_router::{Path, Resource, ResourceDef, Url};
|
||||||
use actix_service::{IntoServiceFactory, ServiceFactory};
|
use actix_service::{IntoServiceFactory, ServiceFactory};
|
||||||
use futures::future::{ok, Ready};
|
|
||||||
|
|
||||||
use crate::config::{AppConfig, AppService};
|
use crate::config::{AppConfig, AppService};
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
@ -529,9 +528,10 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test::{block_on, init_service, TestRequest};
|
use crate::test::{init_service, TestRequest};
|
||||||
use crate::{guard, http, web, App, HttpResponse};
|
use crate::{guard, http, web, App, HttpResponse};
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
|
use futures::future::ok;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_service_request() {
|
fn test_service_request() {
|
||||||
@ -554,35 +554,29 @@ mod tests {
|
|||||||
assert!(ServiceRequest::from_request(r).is_err());
|
assert!(ServiceRequest::from_request(r).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_service() {
|
async fn test_service() {
|
||||||
block_on(async {
|
let mut srv = init_service(
|
||||||
let mut srv = init_service(
|
App::new().service(web::service("/test").name("test").finish(
|
||||||
App::new().service(web::service("/test").name("test").finish(
|
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().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();
|
||||||
.await;
|
assert_eq!(resp.status(), http::StatusCode::OK);
|
||||||
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(
|
let mut srv = init_service(
|
||||||
web::service("/test").guard(guard::Get()).finish(
|
App::new().service(web::service("/test").guard(guard::Get()).finish(
|
||||||
|req: ServiceRequest| {
|
|req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
|
||||||
ok(req.into_response(HttpResponse::Ok().finish()))
|
)),
|
||||||
},
|
)
|
||||||
),
|
.await;
|
||||||
))
|
let req = TestRequest::with_uri("/test")
|
||||||
.await;
|
.method(http::Method::PUT)
|
||||||
let req = TestRequest::with_uri("/test")
|
.to_request();
|
||||||
.method(http::Method::PUT)
|
let resp = srv.call(req).await.unwrap();
|
||||||
.to_request();
|
assert_eq!(resp.status(), http::StatusCode::NOT_FOUND);
|
||||||
let resp = srv.call(req).await.unwrap();
|
|
||||||
assert_eq!(resp.status(), http::StatusCode::NOT_FOUND);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
332
src/test.rs
332
src/test.rs
@ -9,14 +9,13 @@ use actix_router::{Path, ResourceDef, Url};
|
|||||||
use actix_server_config::ServerConfig;
|
use actix_server_config::ServerConfig;
|
||||||
use actix_service::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
use actix_service::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures::future::{ok, Future, FutureExt};
|
use futures::future::ok;
|
||||||
use futures::stream::{Stream, StreamExt};
|
use futures::stream::{Stream, StreamExt};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
pub use actix_http::test::TestBuffer;
|
pub use actix_http::test::TestBuffer;
|
||||||
pub use actix_testing::{block_fn, block_on, run_on};
|
|
||||||
|
|
||||||
use crate::config::{AppConfig, AppConfigInner};
|
use crate::config::{AppConfig, AppConfigInner};
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
@ -51,8 +50,8 @@ pub fn default_service(
|
|||||||
/// use actix_service::Service;
|
/// use actix_service::Service;
|
||||||
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
|
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
|
||||||
///
|
///
|
||||||
/// #[test]
|
/// #[actix_rt::test]
|
||||||
/// fn test_init_service() {
|
/// async fn test_init_service() {
|
||||||
/// let mut app = test::init_service(
|
/// let mut app = test::init_service(
|
||||||
/// App::new()
|
/// App::new()
|
||||||
/// .service(web::resource("/test").to(|| async { HttpResponse::Ok() }))
|
/// .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();
|
/// let req = test::TestRequest::with_uri("/test").to_request();
|
||||||
///
|
///
|
||||||
/// // Execute application
|
/// // Execute application
|
||||||
/// let resp = test::block_on(app.call(req)).unwrap();
|
/// let resp = app.call(req).await.unwrap();
|
||||||
/// assert_eq!(resp.status(), StatusCode::OK);
|
/// assert_eq!(resp.status(), StatusCode::OK);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@ -116,14 +115,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function that returns a response body of a TestRequest
|
/// Helper function that returns a response body of a TestRequest
|
||||||
/// This function blocks the current thread until futures complete.
|
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_web::{test, web, App, HttpResponse, http::header};
|
/// use actix_web::{test, web, App, HttpResponse, http::header};
|
||||||
/// use bytes::Bytes;
|
/// use bytes::Bytes;
|
||||||
///
|
///
|
||||||
/// #[test]
|
/// #[actix_rt::test]
|
||||||
/// fn test_index() {
|
/// async fn test_index() {
|
||||||
/// let mut app = test::init_service(
|
/// let mut app = test::init_service(
|
||||||
/// App::new().service(
|
/// App::new().service(
|
||||||
/// web::resource("/index.html")
|
/// web::resource("/index.html")
|
||||||
@ -149,7 +147,7 @@ where
|
|||||||
let mut resp = app
|
let mut resp = app
|
||||||
.call(req)
|
.call(req)
|
||||||
.await
|
.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 body = resp.take_body();
|
||||||
let mut bytes = BytesMut::new();
|
let mut bytes = BytesMut::new();
|
||||||
@ -160,14 +158,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function that returns a response body of a ServiceResponse.
|
/// Helper function that returns a response body of a ServiceResponse.
|
||||||
/// This function blocks the current thread until futures complete.
|
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_web::{test, web, App, HttpResponse, http::header};
|
/// use actix_web::{test, web, App, HttpResponse, http::header};
|
||||||
/// use bytes::Bytes;
|
/// use bytes::Bytes;
|
||||||
///
|
///
|
||||||
/// #[test]
|
/// #[actix_rt::test]
|
||||||
/// fn test_index() {
|
/// async fn test_index() {
|
||||||
/// let mut app = test::init_service(
|
/// let mut app = test::init_service(
|
||||||
/// App::new().service(
|
/// App::new().service(
|
||||||
/// web::resource("/index.html")
|
/// web::resource("/index.html")
|
||||||
@ -210,7 +207,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function that returns a deserialized response body of a TestRequest
|
/// Helper function that returns a deserialized response body of a TestRequest
|
||||||
/// This function blocks the current thread until futures complete.
|
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_web::{App, test, web, HttpResponse, http::header};
|
/// use actix_web::{App, test, web, HttpResponse, http::header};
|
||||||
@ -222,8 +218,8 @@ where
|
|||||||
/// name: String
|
/// name: String
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[test]
|
/// #[actix_rt::test]
|
||||||
/// fn test_add_person() {
|
/// async fn test_add_person() {
|
||||||
/// let mut app = test::init_service(
|
/// let mut app = test::init_service(
|
||||||
/// App::new().service(
|
/// App::new().service(
|
||||||
/// web::resource("/people")
|
/// web::resource("/people")
|
||||||
@ -512,90 +508,81 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{http::header, web, App, HttpResponse};
|
use crate::{http::header, web, App, HttpResponse};
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_basics() {
|
async fn test_basics() {
|
||||||
block_on(async {
|
let req = TestRequest::with_hdr(header::ContentType::json())
|
||||||
let req = TestRequest::with_hdr(header::ContentType::json())
|
.version(Version::HTTP_2)
|
||||||
.version(Version::HTTP_2)
|
.set(header::Date(SystemTime::now().into()))
|
||||||
.set(header::Date(SystemTime::now().into()))
|
.param("test", "123")
|
||||||
.param("test", "123")
|
.data(10u32)
|
||||||
.data(10u32)
|
.to_http_request();
|
||||||
.to_http_request();
|
assert!(req.headers().contains_key(header::CONTENT_TYPE));
|
||||||
assert!(req.headers().contains_key(header::CONTENT_TYPE));
|
assert!(req.headers().contains_key(header::DATE));
|
||||||
assert!(req.headers().contains_key(header::DATE));
|
assert_eq!(&req.match_info()["test"], "123");
|
||||||
assert_eq!(&req.match_info()["test"], "123");
|
assert_eq!(req.version(), Version::HTTP_2);
|
||||||
assert_eq!(req.version(), Version::HTTP_2);
|
let data = req.get_app_data::<u32>().unwrap();
|
||||||
let data = req.get_app_data::<u32>().unwrap();
|
assert!(req.get_app_data::<u64>().is_none());
|
||||||
assert!(req.get_app_data::<u64>().is_none());
|
assert_eq!(*data, 10);
|
||||||
assert_eq!(*data, 10);
|
assert_eq!(*data.get_ref(), 10);
|
||||||
assert_eq!(*data.get_ref(), 10);
|
|
||||||
|
|
||||||
assert!(req.app_data::<u64>().is_none());
|
assert!(req.app_data::<u64>().is_none());
|
||||||
let data = req.app_data::<u32>().unwrap();
|
let data = req.app_data::<u32>().unwrap();
|
||||||
assert_eq!(*data, 10);
|
assert_eq!(*data, 10);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_request_methods() {
|
async fn test_request_methods() {
|
||||||
block_on(async {
|
let mut app = init_service(
|
||||||
let mut app = init_service(
|
App::new().service(
|
||||||
App::new().service(
|
web::resource("/index.html")
|
||||||
web::resource("/index.html")
|
.route(web::put().to(|| async { HttpResponse::Ok().body("put!") }))
|
||||||
.route(
|
.route(
|
||||||
web::put().to(|| async { HttpResponse::Ok().body("put!") }),
|
web::patch().to(|| async { HttpResponse::Ok().body("patch!") }),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
web::patch()
|
web::delete()
|
||||||
.to(|| async { HttpResponse::Ok().body("patch!") }),
|
.to(|| async { HttpResponse::Ok().body("delete!") }),
|
||||||
)
|
),
|
||||||
.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;
|
.await;
|
||||||
|
|
||||||
let put_req = TestRequest::put()
|
let req = TestRequest::post()
|
||||||
.uri("/index.html")
|
.uri("/index.html")
|
||||||
.header(header::CONTENT_TYPE, "application/json")
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
.to_request();
|
.to_request();
|
||||||
|
|
||||||
let result = read_response(&mut app, put_req).await;
|
let result = read_response(&mut app, req).await;
|
||||||
assert_eq!(result, Bytes::from_static(b"put!"));
|
assert_eq!(result, Bytes::from_static(b"welcome!"));
|
||||||
|
|
||||||
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!"));
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@ -604,114 +591,103 @@ mod tests {
|
|||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_response_json() {
|
async fn test_response_json() {
|
||||||
block_on(async {
|
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||||
let mut app =
|
web::post().to(|person: web::Json<Person>| {
|
||||||
init_service(App::new().service(web::resource("/people").route(
|
async { HttpResponse::Ok().json(person.into_inner()) }
|
||||||
web::post().to(|person: web::Json<Person>| {
|
}),
|
||||||
async { HttpResponse::Ok().json(person.into_inner()) }
|
)))
|
||||||
}),
|
.await;
|
||||||
)))
|
|
||||||
.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()
|
let req = TestRequest::post()
|
||||||
.uri("/people")
|
.uri("/people")
|
||||||
.header(header::CONTENT_TYPE, "application/json")
|
.header(header::CONTENT_TYPE, "application/json")
|
||||||
.set_payload(payload)
|
.set_payload(payload)
|
||||||
.to_request();
|
.to_request();
|
||||||
|
|
||||||
let result: Person = read_response_json(&mut app, req).await;
|
let result: Person = read_response_json(&mut app, req).await;
|
||||||
assert_eq!(&result.id, "12345");
|
assert_eq!(&result.id, "12345");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_request_response_form() {
|
async fn test_request_response_form() {
|
||||||
block_on(async {
|
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||||
let mut app =
|
web::post().to(|person: web::Form<Person>| {
|
||||||
init_service(App::new().service(web::resource("/people").route(
|
async { HttpResponse::Ok().json(person.into_inner()) }
|
||||||
web::post().to(|person: web::Form<Person>| {
|
}),
|
||||||
async { HttpResponse::Ok().json(person.into_inner()) }
|
)))
|
||||||
}),
|
.await;
|
||||||
)))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let payload = Person {
|
let payload = Person {
|
||||||
id: "12345".to_string(),
|
id: "12345".to_string(),
|
||||||
name: "User name".to_string(),
|
name: "User name".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let req = TestRequest::post()
|
let req = TestRequest::post()
|
||||||
.uri("/people")
|
.uri("/people")
|
||||||
.set_form(&payload)
|
.set_form(&payload)
|
||||||
.to_request();
|
.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;
|
let result: Person = read_response_json(&mut app, req).await;
|
||||||
assert_eq!(&result.id, "12345");
|
assert_eq!(&result.id, "12345");
|
||||||
assert_eq!(&result.name, "User name");
|
assert_eq!(&result.name, "User name");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_request_response_json() {
|
async fn test_request_response_json() {
|
||||||
block_on(async {
|
let mut app = init_service(App::new().service(web::resource("/people").route(
|
||||||
let mut app =
|
web::post().to(|person: web::Json<Person>| {
|
||||||
init_service(App::new().service(web::resource("/people").route(
|
async { HttpResponse::Ok().json(person.into_inner()) }
|
||||||
web::post().to(|person: web::Json<Person>| {
|
}),
|
||||||
async { HttpResponse::Ok().json(person.into_inner()) }
|
)))
|
||||||
}),
|
.await;
|
||||||
)))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let payload = Person {
|
let payload = Person {
|
||||||
id: "12345".to_string(),
|
id: "12345".to_string(),
|
||||||
name: "User name".to_string(),
|
name: "User name".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let req = TestRequest::post()
|
let req = TestRequest::post()
|
||||||
.uri("/people")
|
.uri("/people")
|
||||||
.set_json(&payload)
|
.set_json(&payload)
|
||||||
.to_request();
|
.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;
|
let result: Person = read_response_json(&mut app, req).await;
|
||||||
assert_eq!(&result.id, "12345");
|
assert_eq!(&result.id, "12345");
|
||||||
assert_eq!(&result.name, "User name");
|
assert_eq!(&result.name, "User name");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_async_with_block() {
|
async fn test_async_with_block() {
|
||||||
block_on(async {
|
async fn async_with_block() -> Result<HttpResponse, Error> {
|
||||||
async fn async_with_block() -> Result<HttpResponse, Error> {
|
let res = web::block(move || Some(4usize).ok_or("wrong")).await;
|
||||||
let res = web::block(move || Some(4usize).ok_or("wrong")).await;
|
|
||||||
|
|
||||||
match res? {
|
match res? {
|
||||||
Ok(value) => Ok(HttpResponse::Ok()
|
Ok(value) => Ok(HttpResponse::Ok()
|
||||||
.content_type("text/plain")
|
.content_type("text/plain")
|
||||||
.body(format!("Async with block value: {}", value))),
|
.body(format!("Async with block value: {}", value))),
|
||||||
Err(_) => panic!("Unexpected"),
|
Err(_) => panic!("Unexpected"),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut app = init_service(
|
let mut app = init_service(
|
||||||
App::new().service(web::resource("/index.html").to(async_with_block)),
|
App::new().service(web::resource("/index.html").to(async_with_block)),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let req = TestRequest::post().uri("/index.html").to_request();
|
let req = TestRequest::post().uri("/index.html").to_request();
|
||||||
let res = app.call(req).await.unwrap();
|
let res = app.call(req).await.unwrap();
|
||||||
assert!(res.status().is_success());
|
assert!(res.status().is_success());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[actix_rt::test]
|
||||||
// fn test_actor() {
|
// fn test_actor() {
|
||||||
// use actix::Actor;
|
// use actix::Actor;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use actix_http::{Error, HttpMessage, Payload, Response};
|
|||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use encoding_rs::{Encoding, UTF_8};
|
use encoding_rs::{Encoding, UTF_8};
|
||||||
use futures::future::{err, ok, FutureExt, LocalBoxFuture, Ready};
|
use futures::future::{err, ok, FutureExt, LocalBoxFuture, Ready};
|
||||||
use futures::{Stream, StreamExt};
|
use futures::StreamExt;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
use crate::http::header::{HeaderValue, CONTENT_TYPE};
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
||||||
struct Info {
|
struct Info {
|
||||||
@ -378,26 +378,22 @@ mod tests {
|
|||||||
counter: i64,
|
counter: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_form() {
|
async fn test_form() {
|
||||||
block_on(async {
|
let (req, mut pl) =
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||||
CONTENT_TYPE,
|
.header(CONTENT_LENGTH, "11")
|
||||||
"application/x-www-form-urlencoded",
|
.set_payload(Bytes::from_static(b"hello=world&counter=123"))
|
||||||
)
|
.to_http_parts();
|
||||||
.header(CONTENT_LENGTH, "11")
|
|
||||||
.set_payload(Bytes::from_static(b"hello=world&counter=123"))
|
|
||||||
.to_http_parts();
|
|
||||||
|
|
||||||
let Form(s) = Form::<Info>::from_request(&req, &mut pl).await.unwrap();
|
let Form(s) = Form::<Info>::from_request(&req, &mut pl).await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s,
|
s,
|
||||||
Info {
|
Info {
|
||||||
hello: "world".into(),
|
hello: "world".into(),
|
||||||
counter: 123
|
counter: 123
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eq(err: UrlencodedError, other: UrlencodedError) -> bool {
|
fn eq(err: UrlencodedError, other: UrlencodedError) -> bool {
|
||||||
@ -418,95 +414,83 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_urlencoded_error() {
|
async fn test_urlencoded_error() {
|
||||||
block_on(async {
|
let (req, mut pl) =
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||||
CONTENT_TYPE,
|
.header(CONTENT_LENGTH, "xxxx")
|
||||||
"application/x-www-form-urlencoded",
|
|
||||||
)
|
|
||||||
.header(CONTENT_LENGTH, "xxxx")
|
|
||||||
.to_http_parts();
|
|
||||||
let info = UrlEncoded::<Info>::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::<Info>::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();
|
.to_http_parts();
|
||||||
let info = UrlEncoded::<Info>::new(&req, &mut pl).await;
|
let info = UrlEncoded::<Info>::new(&req, &mut pl).await;
|
||||||
assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
|
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::<Info>::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::<Info>::new(&req, &mut pl).await;
|
||||||
|
assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_urlencoded() {
|
async fn test_urlencoded() {
|
||||||
block_on(async {
|
let (req, mut pl) =
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
|
||||||
CONTENT_TYPE,
|
.header(CONTENT_LENGTH, "11")
|
||||||
"application/x-www-form-urlencoded",
|
.set_payload(Bytes::from_static(b"hello=world&counter=123"))
|
||||||
)
|
.to_http_parts();
|
||||||
.header(CONTENT_LENGTH, "11")
|
|
||||||
.set_payload(Bytes::from_static(b"hello=world&counter=123"))
|
|
||||||
.to_http_parts();
|
|
||||||
|
|
||||||
let info = UrlEncoded::<Info>::new(&req, &mut pl).await.unwrap();
|
let info = UrlEncoded::<Info>::new(&req, &mut pl).await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
info,
|
info,
|
||||||
Info {
|
Info {
|
||||||
hello: "world".to_owned(),
|
hello: "world".to_owned(),
|
||||||
counter: 123
|
counter: 123
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
let (req, mut pl) = TestRequest::with_header(
|
||||||
CONTENT_TYPE,
|
CONTENT_TYPE,
|
||||||
"application/x-www-form-urlencoded; charset=utf-8",
|
"application/x-www-form-urlencoded; charset=utf-8",
|
||||||
)
|
)
|
||||||
.header(CONTENT_LENGTH, "11")
|
.header(CONTENT_LENGTH, "11")
|
||||||
.set_payload(Bytes::from_static(b"hello=world&counter=123"))
|
.set_payload(Bytes::from_static(b"hello=world&counter=123"))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let info = UrlEncoded::<Info>::new(&req, &mut pl).await.unwrap();
|
let info = UrlEncoded::<Info>::new(&req, &mut pl).await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
info,
|
info,
|
||||||
Info {
|
Info {
|
||||||
hello: "world".to_owned(),
|
hello: "world".to_owned(),
|
||||||
counter: 123
|
counter: 123
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_responder() {
|
async fn test_responder() {
|
||||||
block_on(async {
|
let req = TestRequest::default().to_http_request();
|
||||||
let req = TestRequest::default().to_http_request();
|
|
||||||
|
|
||||||
let form = Form(Info {
|
let form = Form(Info {
|
||||||
hello: "world".to_string(),
|
hello: "world".to_string(),
|
||||||
counter: 123,
|
counter: 123,
|
||||||
});
|
});
|
||||||
let resp = form.respond_to(&req).await.unwrap();
|
let resp = form.respond_to(&req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(CONTENT_TYPE).unwrap(),
|
resp.headers().get(CONTENT_TYPE).unwrap(),
|
||||||
HeaderValue::from_static("application/x-www-form-urlencoded")
|
HeaderValue::from_static("application/x-www-form-urlencoded")
|
||||||
);
|
);
|
||||||
|
|
||||||
use crate::responder::tests::BodyTest;
|
use crate::responder::tests::BodyTest;
|
||||||
assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123");
|
assert_eq!(resp.body().bin_ref(), b"hello=world&counter=123");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use std::{fmt, ops};
|
|||||||
|
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use futures::future::{err, ok, FutureExt, LocalBoxFuture, Ready};
|
use futures::future::{err, ok, FutureExt, LocalBoxFuture, Ready};
|
||||||
use futures::{Stream, StreamExt};
|
use futures::StreamExt;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
@ -402,7 +402,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::error::InternalError;
|
use crate::error::InternalError;
|
||||||
use crate::http::header;
|
use crate::http::header;
|
||||||
use crate::test::{block_on, load_stream, TestRequest};
|
use crate::test::{load_stream, TestRequest};
|
||||||
use crate::HttpResponse;
|
use crate::HttpResponse;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
@ -424,236 +424,222 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_responder() {
|
async fn test_responder() {
|
||||||
block_on(async {
|
let req = TestRequest::default().to_http_request();
|
||||||
let req = TestRequest::default().to_http_request();
|
|
||||||
|
|
||||||
let j = Json(MyObject {
|
let j = Json(MyObject {
|
||||||
name: "test".to_string(),
|
name: "test".to_string(),
|
||||||
});
|
});
|
||||||
let resp = j.respond_to(&req).await.unwrap();
|
let resp = j.respond_to(&req).await.unwrap();
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
resp.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||||
header::HeaderValue::from_static("application/json")
|
header::HeaderValue::from_static("application/json")
|
||||||
);
|
);
|
||||||
|
|
||||||
use crate::responder::tests::BodyTest;
|
use crate::responder::tests::BodyTest;
|
||||||
assert_eq!(resp.body().bin_ref(), b"{\"name\":\"test\"}");
|
assert_eq!(resp.body().bin_ref(), b"{\"name\":\"test\"}");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_custom_error_responder() {
|
async fn test_custom_error_responder() {
|
||||||
block_on(async {
|
let (req, mut pl) = TestRequest::default()
|
||||||
let (req, mut pl) = TestRequest::default()
|
.header(
|
||||||
.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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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(
|
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
header::HeaderValue::from_static("text/plain"),
|
header::HeaderValue::from_static("application/json"),
|
||||||
)
|
)
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_LENGTH,
|
header::CONTENT_LENGTH,
|
||||||
header::HeaderValue::from_static("16"),
|
header::HeaderValue::from_static("16"),
|
||||||
)
|
)
|
||||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
||||||
.data(JsonConfig::default().limit(4096))
|
.data(JsonConfig::default().limit(10).error_handler(|err, _| {
|
||||||
.to_http_parts();
|
let msg = MyObject {
|
||||||
|
name: "invalid request".to_string(),
|
||||||
let s = Json::<MyObject>::from_request(&req, &mut pl).await;
|
};
|
||||||
assert!(s.is_err())
|
let resp = HttpResponse::BadRequest()
|
||||||
})
|
.body(serde_json::to_string(&msg).unwrap());
|
||||||
}
|
InternalError::from_response(err, resp).into()
|
||||||
|
|
||||||
#[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
|
|
||||||
}))
|
}))
|
||||||
.to_http_parts();
|
.to_http_parts();
|
||||||
|
|
||||||
let s = Json::<MyObject>::from_request(&req, &mut pl).await;
|
let s = Json::<MyObject>::from_request(&req, &mut pl).await;
|
||||||
assert!(s.is_ok())
|
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]
|
#[actix_rt::test]
|
||||||
fn test_with_json_and_bad_custom_content_type() {
|
async fn test_extract() {
|
||||||
block_on(async {
|
let (req, mut pl) = TestRequest::default()
|
||||||
let (req, mut pl) = TestRequest::with_header(
|
.header(
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
header::HeaderValue::from_static("text/html"),
|
header::HeaderValue::from_static("application/json"),
|
||||||
)
|
)
|
||||||
.header(
|
.header(
|
||||||
header::CONTENT_LENGTH,
|
header::CONTENT_LENGTH,
|
||||||
header::HeaderValue::from_static("16"),
|
header::HeaderValue::from_static("16"),
|
||||||
)
|
)
|
||||||
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
|
.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();
|
.to_http_parts();
|
||||||
|
|
||||||
let s = Json::<MyObject>::from_request(&req, &mut pl).await;
|
let s = Json::<MyObject>::from_request(&req, &mut pl).await.unwrap();
|
||||||
assert!(s.is_err())
|
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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::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::<MyObject>::from_request(&req, &mut pl).await;
|
||||||
|
assert!(s.is_err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,3 +12,4 @@ pub use self::json::{Json, JsonConfig};
|
|||||||
pub use self::path::{Path, PathConfig};
|
pub use self::path::{Path, PathConfig};
|
||||||
pub use self::payload::{Payload, PayloadConfig};
|
pub use self::payload::{Payload, PayloadConfig};
|
||||||
pub use self::query::{Query, QueryConfig};
|
pub use self::query::{Query, QueryConfig};
|
||||||
|
pub use self::readlines::Readlines;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
//! Path extractor
|
//! Path extractor
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{fmt, ops};
|
use std::{fmt, ops};
|
||||||
|
|
||||||
@ -253,7 +252,7 @@ mod tests {
|
|||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
use crate::{error, http, HttpResponse};
|
use crate::{error, http, HttpResponse};
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Display)]
|
#[derive(Deserialize, Debug, Display)]
|
||||||
@ -269,118 +268,110 @@ mod tests {
|
|||||||
value: u32,
|
value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_extract_path_single() {
|
async fn test_extract_path_single() {
|
||||||
block_on(async {
|
let resource = ResourceDef::new("/{value}/");
|
||||||
let resource = ResourceDef::new("/{value}/");
|
|
||||||
|
|
||||||
let mut req = TestRequest::with_uri("/32/").to_srv_request();
|
let mut req = TestRequest::with_uri("/32/").to_srv_request();
|
||||||
resource.match_path(req.match_info_mut());
|
resource.match_path(req.match_info_mut());
|
||||||
|
|
||||||
let (req, mut pl) = req.into_parts();
|
let (req, mut pl) = req.into_parts();
|
||||||
assert_eq!(*Path::<i8>::from_request(&req, &mut pl).await.unwrap(), 32);
|
assert_eq!(*Path::<i8>::from_request(&req, &mut pl).await.unwrap(), 32);
|
||||||
assert!(Path::<MyStruct>::from_request(&req, &mut pl).await.is_err());
|
assert!(Path::<MyStruct>::from_request(&req, &mut pl).await.is_err());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_tuple_extract() {
|
async fn test_tuple_extract() {
|
||||||
block_on(async {
|
let resource = ResourceDef::new("/{key}/{value}/");
|
||||||
let resource = ResourceDef::new("/{key}/{value}/");
|
|
||||||
|
|
||||||
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
||||||
resource.match_path(req.match_info_mut());
|
resource.match_path(req.match_info_mut());
|
||||||
|
|
||||||
let (req, mut pl) = req.into_parts();
|
let (req, mut pl) = req.into_parts();
|
||||||
let res = <(Path<(String, String)>,)>::from_request(&req, &mut pl)
|
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,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!((res.0).0, "name");
|
assert_eq!((res.0).0, "name");
|
||||||
assert_eq!((res.0).1, "user1");
|
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();
|
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]
|
#[actix_rt::test]
|
||||||
fn test_request_extract() {
|
async fn test_request_extract() {
|
||||||
block_on(async {
|
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
||||||
let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
|
||||||
|
|
||||||
let resource = ResourceDef::new("/{key}/{value}/");
|
let resource = ResourceDef::new("/{key}/{value}/");
|
||||||
resource.match_path(req.match_info_mut());
|
resource.match_path(req.match_info_mut());
|
||||||
|
|
||||||
let (req, mut pl) = req.into_parts();
|
let (req, mut pl) = req.into_parts();
|
||||||
let mut s = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap();
|
let mut s = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap();
|
||||||
assert_eq!(s.key, "name");
|
assert_eq!(s.key, "name");
|
||||||
assert_eq!(s.value, "user1");
|
assert_eq!(s.value, "user1");
|
||||||
s.value = "user2".to_string();
|
s.value = "user2".to_string();
|
||||||
assert_eq!(s.value, "user2");
|
assert_eq!(s.value, "user2");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{}, {:?}", s, s),
|
format!("{}, {:?}", s, s),
|
||||||
"MyStruct(name, user2), MyStruct { key: \"name\", value: \"user2\" }"
|
"MyStruct(name, user2), MyStruct { key: \"name\", value: \"user2\" }"
|
||||||
);
|
);
|
||||||
let s = s.into_inner();
|
let s = s.into_inner();
|
||||||
assert_eq!(s.value, "user2");
|
assert_eq!(s.value, "user2");
|
||||||
|
|
||||||
let s = Path::<(String, String)>::from_request(&req, &mut pl)
|
let s = Path::<(String, String)>::from_request(&req, &mut pl)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(s.0, "name");
|
assert_eq!(s.0, "name");
|
||||||
assert_eq!(s.1, "user1");
|
assert_eq!(s.1, "user1");
|
||||||
|
|
||||||
let mut req = TestRequest::with_uri("/name/32/").to_srv_request();
|
let mut req = TestRequest::with_uri("/name/32/").to_srv_request();
|
||||||
let resource = ResourceDef::new("/{key}/{value}/");
|
let resource = ResourceDef::new("/{key}/{value}/");
|
||||||
resource.match_path(req.match_info_mut());
|
resource.match_path(req.match_info_mut());
|
||||||
|
|
||||||
let (req, mut pl) = req.into_parts();
|
let (req, mut pl) = req.into_parts();
|
||||||
let s = Path::<Test2>::from_request(&req, &mut pl).await.unwrap();
|
let s = Path::<Test2>::from_request(&req, &mut pl).await.unwrap();
|
||||||
assert_eq!(s.as_ref().key, "name");
|
assert_eq!(s.as_ref().key, "name");
|
||||||
assert_eq!(s.value, 32);
|
assert_eq!(s.value, 32);
|
||||||
|
|
||||||
let s = Path::<(String, u8)>::from_request(&req, &mut pl)
|
let s = Path::<(String, u8)>::from_request(&req, &mut pl)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(s.0, "name");
|
assert_eq!(s.0, "name");
|
||||||
assert_eq!(s.1, 32);
|
assert_eq!(s.1, 32);
|
||||||
|
|
||||||
let res = Path::<Vec<String>>::from_request(&req, &mut pl)
|
let res = Path::<Vec<String>>::from_request(&req, &mut pl)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res[0], "name".to_owned());
|
assert_eq!(res[0], "name".to_owned());
|
||||||
assert_eq!(res[1], "32".to_owned());
|
assert_eq!(res[1], "32".to_owned());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_custom_err_handler() {
|
async fn test_custom_err_handler() {
|
||||||
block_on(async {
|
let (req, mut pl) = TestRequest::with_uri("/name/user1/")
|
||||||
let (req, mut pl) = TestRequest::with_uri("/name/user1/")
|
.data(PathConfig::default().error_handler(|err, _| {
|
||||||
.data(PathConfig::default().error_handler(|err, _| {
|
error::InternalError::from_response(
|
||||||
error::InternalError::from_response(
|
err,
|
||||||
err,
|
HttpResponse::Conflict().finish(),
|
||||||
HttpResponse::Conflict().finish(),
|
)
|
||||||
)
|
.into()
|
||||||
.into()
|
}))
|
||||||
}))
|
.to_http_parts();
|
||||||
.to_http_parts();
|
|
||||||
|
|
||||||
let s = Path::<(usize,)>::from_request(&req, &mut pl)
|
let s = Path::<(usize,)>::from_request(&req, &mut pl)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
let res: HttpResponse = s.into();
|
let res: HttpResponse = s.into();
|
||||||
|
|
||||||
assert_eq!(res.status(), http::StatusCode::CONFLICT);
|
assert_eq!(res.status(), http::StatusCode::CONFLICT);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,10 +395,10 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::http::header;
|
use crate::http::header;
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_payload_config() {
|
async fn test_payload_config() {
|
||||||
let req = TestRequest::default().to_http_request();
|
let req = TestRequest::default().to_http_request();
|
||||||
let cfg = PayloadConfig::default().mimetype(mime::APPLICATION_JSON);
|
let cfg = PayloadConfig::default().mimetype(mime::APPLICATION_JSON);
|
||||||
assert!(cfg.check_mimetype(&req).is_err());
|
assert!(cfg.check_mimetype(&req).is_err());
|
||||||
@ -415,32 +415,32 @@ mod tests {
|
|||||||
assert!(cfg.check_mimetype(&req).is_ok());
|
assert!(cfg.check_mimetype(&req).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_bytes() {
|
async fn test_bytes() {
|
||||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
||||||
.set_payload(Bytes::from_static(b"hello=world"))
|
.set_payload(Bytes::from_static(b"hello=world"))
|
||||||
.to_http_parts();
|
.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"));
|
assert_eq!(s, Bytes::from_static(b"hello=world"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_string() {
|
async fn test_string() {
|
||||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "11")
|
||||||
.set_payload(Bytes::from_static(b"hello=world"))
|
.set_payload(Bytes::from_static(b"hello=world"))
|
||||||
.to_http_parts();
|
.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");
|
assert_eq!(s, "hello=world");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_message_body() {
|
async fn test_message_body() {
|
||||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "xxxx")
|
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "xxxx")
|
||||||
.to_srv_request()
|
.to_srv_request()
|
||||||
.into_parts();
|
.into_parts();
|
||||||
let res = block_on(HttpMessageBody::new(&req, &mut pl));
|
let res = HttpMessageBody::new(&req, &mut pl).await;
|
||||||
match res.err().unwrap() {
|
match res.err().unwrap() {
|
||||||
PayloadError::UnknownLength => (),
|
PayloadError::UnknownLength => (),
|
||||||
_ => unreachable!("error"),
|
_ => unreachable!("error"),
|
||||||
@ -449,7 +449,7 @@ mod tests {
|
|||||||
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "1000000")
|
let (req, mut pl) = TestRequest::with_header(header::CONTENT_LENGTH, "1000000")
|
||||||
.to_srv_request()
|
.to_srv_request()
|
||||||
.into_parts();
|
.into_parts();
|
||||||
let res = block_on(HttpMessageBody::new(&req, &mut pl));
|
let res = HttpMessageBody::new(&req, &mut pl).await;
|
||||||
match res.err().unwrap() {
|
match res.err().unwrap() {
|
||||||
PayloadError::Overflow => (),
|
PayloadError::Overflow => (),
|
||||||
_ => unreachable!("error"),
|
_ => unreachable!("error"),
|
||||||
@ -458,13 +458,13 @@ mod tests {
|
|||||||
let (req, mut pl) = TestRequest::default()
|
let (req, mut pl) = TestRequest::default()
|
||||||
.set_payload(Bytes::from_static(b"test"))
|
.set_payload(Bytes::from_static(b"test"))
|
||||||
.to_http_parts();
|
.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"));
|
assert_eq!(res.ok().unwrap(), Bytes::from_static(b"test"));
|
||||||
|
|
||||||
let (req, mut pl) = TestRequest::default()
|
let (req, mut pl) = TestRequest::default()
|
||||||
.set_payload(Bytes::from_static(b"11111111111111"))
|
.set_payload(Bytes::from_static(b"11111111111111"))
|
||||||
.to_http_parts();
|
.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() {
|
match res.err().unwrap() {
|
||||||
PayloadError::Overflow => (),
|
PayloadError::Overflow => (),
|
||||||
_ => unreachable!("error"),
|
_ => unreachable!("error"),
|
||||||
|
@ -228,7 +228,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::error::InternalError;
|
use crate::error::InternalError;
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
use crate::HttpResponse;
|
use crate::HttpResponse;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Display)]
|
#[derive(Deserialize, Debug, Display)]
|
||||||
@ -236,8 +236,8 @@ mod tests {
|
|||||||
id: String,
|
id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_service_request_extract() {
|
async fn test_service_request_extract() {
|
||||||
let req = TestRequest::with_uri("/name/user1/").to_srv_request();
|
let req = TestRequest::with_uri("/name/user1/").to_srv_request();
|
||||||
assert!(Query::<Id>::from_query(&req.query_string()).is_err());
|
assert!(Query::<Id>::from_query(&req.query_string()).is_err());
|
||||||
|
|
||||||
@ -252,48 +252,44 @@ mod tests {
|
|||||||
assert_eq!(s.id, "test1");
|
assert_eq!(s.id, "test1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_request_extract() {
|
async fn test_request_extract() {
|
||||||
block_on(async {
|
let req = TestRequest::with_uri("/name/user1/").to_srv_request();
|
||||||
let req = TestRequest::with_uri("/name/user1/").to_srv_request();
|
let (req, mut pl) = req.into_parts();
|
||||||
let (req, mut pl) = req.into_parts();
|
assert!(Query::<Id>::from_request(&req, &mut pl).await.is_err());
|
||||||
assert!(Query::<Id>::from_request(&req, &mut pl).await.is_err());
|
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
let req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
|
||||||
let (req, mut pl) = req.into_parts();
|
let (req, mut pl) = req.into_parts();
|
||||||
|
|
||||||
let mut s = Query::<Id>::from_request(&req, &mut pl).await.unwrap();
|
let mut s = Query::<Id>::from_request(&req, &mut pl).await.unwrap();
|
||||||
assert_eq!(s.id, "test");
|
assert_eq!(s.id, "test");
|
||||||
assert_eq!(format!("{}, {:?}", s, s), "test, Id { id: \"test\" }");
|
assert_eq!(format!("{}, {:?}", s, s), "test, Id { id: \"test\" }");
|
||||||
|
|
||||||
s.id = "test1".to_string();
|
s.id = "test1".to_string();
|
||||||
let s = s.into_inner();
|
let s = s.into_inner();
|
||||||
assert_eq!(s.id, "test1");
|
assert_eq!(s.id, "test1");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_custom_error_responder() {
|
async fn test_custom_error_responder() {
|
||||||
block_on(async {
|
let req = TestRequest::with_uri("/name/user1/")
|
||||||
let req = TestRequest::with_uri("/name/user1/")
|
.data(QueryConfig::default().error_handler(|e, _| {
|
||||||
.data(QueryConfig::default().error_handler(|e, _| {
|
let resp = HttpResponse::UnprocessableEntity().finish();
|
||||||
let resp = HttpResponse::UnprocessableEntity().finish();
|
InternalError::from_response(e, resp).into()
|
||||||
InternalError::from_response(e, resp).into()
|
}))
|
||||||
}))
|
.to_srv_request();
|
||||||
.to_srv_request();
|
|
||||||
|
|
||||||
let (req, mut pl) = req.into_parts();
|
let (req, mut pl) = req.into_parts();
|
||||||
let query = Query::<Id>::from_request(&req, &mut pl).await;
|
let query = Query::<Id>::from_request(&req, &mut pl).await;
|
||||||
|
|
||||||
assert!(query.is_err());
|
assert!(query.is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
query
|
query
|
||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
.as_response_error()
|
.as_response_error()
|
||||||
.error_response()
|
.error_response()
|
||||||
.status(),
|
.status(),
|
||||||
StatusCode::UNPROCESSABLE_ENTITY
|
StatusCode::UNPROCESSABLE_ENTITY
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@ -7,7 +6,6 @@ use std::task::{Context, Poll};
|
|||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use encoding_rs::{Encoding, UTF_8};
|
use encoding_rs::{Encoding, UTF_8};
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use pin_project::pin_project;
|
|
||||||
|
|
||||||
use crate::dev::Payload;
|
use crate::dev::Payload;
|
||||||
use crate::error::{PayloadError, ReadlinesError};
|
use crate::error::{PayloadError, ReadlinesError};
|
||||||
@ -174,12 +172,11 @@ mod tests {
|
|||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::test::{block_on, TestRequest};
|
use crate::test::TestRequest;
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
fn test_readlines() {
|
async fn test_readlines() {
|
||||||
block_on(async {
|
let mut req = TestRequest::default()
|
||||||
let mut req = TestRequest::default()
|
|
||||||
.set_payload(Bytes::from_static(
|
.set_payload(Bytes::from_static(
|
||||||
b"Lorem Ipsum is simply dummy text of the printing and typesetting\n\
|
b"Lorem Ipsum is simply dummy text of the printing and typesetting\n\
|
||||||
industry. Lorem Ipsum has been the industry's standard dummy\n\
|
industry. Lorem Ipsum has been the industry's standard dummy\n\
|
||||||
@ -187,21 +184,20 @@ mod tests {
|
|||||||
))
|
))
|
||||||
.to_request();
|
.to_request();
|
||||||
|
|
||||||
let mut stream = Readlines::new(&mut req);
|
let mut stream = Readlines::new(&mut req);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
stream.next().await.unwrap().unwrap(),
|
stream.next().await.unwrap().unwrap(),
|
||||||
"Lorem Ipsum is simply dummy text of the printing and typesetting\n"
|
"Lorem Ipsum is simply dummy text of the printing and typesetting\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
stream.next().await.unwrap().unwrap(),
|
stream.next().await.unwrap().unwrap(),
|
||||||
"industry. Lorem Ipsum has been the industry's standard dummy\n"
|
"industry. Lorem Ipsum has been the industry's standard dummy\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
stream.next().await.unwrap().unwrap(),
|
stream.next().await.unwrap().unwrap(),
|
||||||
"Contrary to popular belief, Lorem Ipsum is not simply random text."
|
"Contrary to popular belief, Lorem Ipsum is not simply random text."
|
||||||
);
|
);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ pub use actix_http::Response as HttpResponse;
|
|||||||
pub use bytes::{Bytes, BytesMut};
|
pub use bytes::{Bytes, BytesMut};
|
||||||
pub use futures::channel::oneshot::Canceled;
|
pub use futures::channel::oneshot::Canceled;
|
||||||
|
|
||||||
use crate::error::Error;
|
|
||||||
use crate::extract::FromRequest;
|
use crate::extract::FromRequest;
|
||||||
use crate::handler::Factory;
|
use crate::handler::Factory;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
|
@ -54,8 +54,6 @@ slab = "0.4"
|
|||||||
serde_urlencoded = "0.6.1"
|
serde_urlencoded = "0.6.1"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
tokio-net = "0.2.0-alpha.6"
|
tokio-net = "0.2.0-alpha.6"
|
||||||
tokio-timer = "0.3.0-alpha.6"
|
|
||||||
|
|
||||||
open-ssl = { version="0.10", package="openssl", optional = true }
|
open-ssl = { version="0.10", package="openssl", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -23,26 +23,25 @@ pub use actix_testing::*;
|
|||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_http::HttpService;
|
/// use actix_http::HttpService;
|
||||||
/// use actix_http_test::{block_on, TestServer};
|
/// use actix_http_test::TestServer;
|
||||||
/// use actix_web::{web, App, HttpResponse, Error};
|
/// use actix_web::{web, App, HttpResponse, Error};
|
||||||
///
|
///
|
||||||
/// async fn my_handler() -> Result<HttpResponse, Error> {
|
/// async fn my_handler() -> Result<HttpResponse, Error> {
|
||||||
/// Ok(HttpResponse::Ok().into())
|
/// Ok(HttpResponse::Ok().into())
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// #[actix_rt::test]
|
||||||
/// block_on( async {
|
/// async fn test_example() {
|
||||||
/// let mut srv = TestServer::start(
|
/// let mut srv = TestServer::start(
|
||||||
/// || HttpService::new(
|
/// || HttpService::new(
|
||||||
/// App::new().service(
|
/// App::new().service(
|
||||||
/// web::resource("/").to(my_handler))
|
/// web::resource("/").to(my_handler))
|
||||||
/// )
|
/// )
|
||||||
/// );
|
/// );
|
||||||
///
|
///
|
||||||
/// let req = srv.get("/");
|
/// let req = srv.get("/");
|
||||||
/// let response = req.send().await.unwrap();
|
/// let response = req.send().await.unwrap();
|
||||||
/// assert!(response.status().is_success());
|
/// assert!(response.status().is_success());
|
||||||
/// })
|
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct TestServer;
|
pub struct TestServer;
|
||||||
|
@ -6,7 +6,7 @@ use std::{net, thread, time::Duration};
|
|||||||
use open_ssl::ssl::SslAcceptorBuilder;
|
use open_ssl::ssl::SslAcceptorBuilder;
|
||||||
|
|
||||||
use actix_http::Response;
|
use actix_http::Response;
|
||||||
use actix_web::{test, web, App, HttpServer};
|
use actix_web::{web, App, HttpServer};
|
||||||
|
|
||||||
fn unused_addr() -> net::SocketAddr {
|
fn unused_addr() -> net::SocketAddr {
|
||||||
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||||
@ -17,9 +17,9 @@ fn unused_addr() -> net::SocketAddr {
|
|||||||
tcp.local_addr().unwrap()
|
tcp.local_addr().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn test_start() {
|
#[actix_rt::test]
|
||||||
|
async fn test_start() {
|
||||||
let addr = unused_addr();
|
let addr = unused_addr();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
@ -53,21 +53,18 @@ fn test_start() {
|
|||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
{
|
{
|
||||||
use actix_http::client;
|
use actix_http::client;
|
||||||
use actix_web::test;
|
|
||||||
|
|
||||||
test::block_on(async {
|
let client = awc::Client::build()
|
||||||
let client = awc::Client::build()
|
.connector(
|
||||||
.connector(
|
client::Connector::new()
|
||||||
client::Connector::new()
|
.timeout(Duration::from_millis(100))
|
||||||
.timeout(Duration::from_millis(100))
|
.finish(),
|
||||||
.finish(),
|
)
|
||||||
)
|
.finish();
|
||||||
.finish();
|
|
||||||
|
|
||||||
let host = format!("http://{}", addr);
|
let host = format!("http://{}", addr);
|
||||||
let response = client.get(host.clone()).send().await.unwrap();
|
let response = client.get(host.clone()).send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop
|
// stop
|
||||||
@ -91,9 +88,9 @@ fn ssl_acceptor() -> std::io::Result<SslAcceptorBuilder> {
|
|||||||
Ok(builder)
|
Ok(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[actix_rt::test]
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
fn test_start_ssl() {
|
async fn test_start_ssl() {
|
||||||
let addr = unused_addr();
|
let addr = unused_addr();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
@ -119,27 +116,25 @@ fn test_start_ssl() {
|
|||||||
});
|
});
|
||||||
let (srv, sys) = rx.recv().unwrap();
|
let (srv, sys) = rx.recv().unwrap();
|
||||||
|
|
||||||
test::block_on(async move {
|
use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||||
use open_ssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||||
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
builder.set_verify(SslVerifyMode::NONE);
|
||||||
builder.set_verify(SslVerifyMode::NONE);
|
let _ = builder
|
||||||
let _ = builder
|
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
||||||
.set_alpn_protos(b"\x02h2\x08http/1.1")
|
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
||||||
.map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
|
|
||||||
|
|
||||||
let client = awc::Client::build()
|
let client = awc::Client::build()
|
||||||
.connector(
|
.connector(
|
||||||
awc::Connector::new()
|
awc::Connector::new()
|
||||||
.ssl(builder.build())
|
.ssl(builder.build())
|
||||||
.timeout(Duration::from_millis(100))
|
.timeout(Duration::from_millis(100))
|
||||||
.finish(),
|
.finish(),
|
||||||
)
|
)
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
let host = format!("https://{}", addr);
|
let host = format!("https://{}", addr);
|
||||||
let response = client.get(host.clone()).send().await.unwrap();
|
let response = client.get(host.clone()).send().await.unwrap();
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
});
|
|
||||||
|
|
||||||
// stop
|
// stop
|
||||||
let _ = srv.stop(false);
|
let _ = srv.stop(false);
|
||||||
|
1328
tests/test_server.rs
1328
tests/test_server.rs
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user