diff --git a/src/server/h1.rs b/src/server/h1.rs index 8c793ed50..8d862b39b 100644 --- a/src/server/h1.rs +++ b/src/server/h1.rs @@ -165,7 +165,7 @@ where // completed self.flags.insert(Flags::ERROR); - if let Some(ref mut payload) = self.payload { + if let Some(mut payload) = self.payload.take() { payload.set_error(PayloadError::Incomplete); } } else { @@ -350,7 +350,7 @@ where } } Ok(Some(Message::Eof)) => { - if let Some(ref mut payload) = self.payload { + if let Some(mut payload) = self.payload.take() { payload.feed_eof(); } else { error!("Internal server error: unexpected eof"); @@ -360,7 +360,7 @@ where Ok(None) => break, Err(e) => { self.flags.insert(Flags::ERROR); - if let Some(ref mut payload) = self.payload { + if let Some(mut payload) = self.payload.take() { let e = match e { DecoderError::Io(e) => PayloadError::Io(e), DecoderError::Error(_) => PayloadError::EncodingCorrupted, diff --git a/tests/test_handlers.rs b/tests/test_handlers.rs index 7a9abe974..8aea34d0a 100644 --- a/tests/test_handlers.rs +++ b/tests/test_handlers.rs @@ -7,10 +7,17 @@ extern crate http; extern crate tokio_core; #[macro_use] extern crate serde_derive; +extern crate serde_json; +use std::time::Duration; + +use actix::*; use actix_web::*; use bytes::Bytes; +use futures::Future; use http::StatusCode; +use serde_json::Value; +use tokio_core::reactor::Timeout; #[derive(Deserialize)] struct PParam { @@ -67,6 +74,33 @@ fn test_query_extractor() { assert_eq!(response.status(), StatusCode::BAD_REQUEST); } +#[test] +fn test_async_extractor_async() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route().with(|data: Json| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| Ok(format!("{}", data.0))) + .responder() + }) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.execute(response.body()).unwrap(); + assert_eq!(bytes, Bytes::from_static(b"{\"test\":1}")); +} + #[test] fn test_path_and_query_extractor() { let mut srv = test::TestServer::new(|app| { @@ -130,6 +164,219 @@ fn test_path_and_query_extractor2() { assert_eq!(response.status(), StatusCode::BAD_REQUEST); } +#[test] +fn test_path_and_query_extractor2_async() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route().with3( + |p: Path, _: Query, data: Json| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| { + Ok(format!("Welcome {} - {}!", p.username, data.0)) + }) + .responder() + }, + ) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html?username=test2")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.execute(response.body()).unwrap(); + assert_eq!( + bytes, + Bytes::from_static(b"Welcome test1 - {\"test\":1}!") + ); +} + +#[test] +fn test_path_and_query_extractor3_async() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route().with2(|p: Path, data: Json| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| { + Ok(format!("Welcome {} - {}!", p.username, data.0)) + }) + .responder() + }) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); +} + +#[test] +fn test_path_and_query_extractor4_async() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route().with2(|data: Json, p: Path| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| { + Ok(format!("Welcome {} - {}!", p.username, data.0)) + }) + .responder() + }) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); +} + +#[test] +fn test_path_and_query_extractor2_async2() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route().with3( + |p: Path, data: Json, _: Query| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| { + Ok(format!("Welcome {} - {}!", p.username, data.0)) + }) + .responder() + }, + ) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html?username=test2")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.execute(response.body()).unwrap(); + assert_eq!( + bytes, + Bytes::from_static(b"Welcome test1 - {\"test\":1}!") + ); + + // client request + let request = srv.get() + .uri(srv.url("/test1/index.html")) + .finish() + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + +#[test] +fn test_path_and_query_extractor2_async3() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route().with3( + |data: Json, p: Path, _: Query| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| { + Ok(format!("Welcome {} - {}!", p.username, data.0)) + }) + .responder() + }, + ) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html?username=test2")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.execute(response.body()).unwrap(); + assert_eq!( + bytes, + Bytes::from_static(b"Welcome test1 - {\"test\":1}!") + ); + + // client request + let request = srv.get() + .uri(srv.url("/test1/index.html")) + .finish() + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + +#[test] +fn test_path_and_query_extractor2_async4() { + let mut srv = test::TestServer::new(|app| { + app.resource("/{username}/index.html", |r| { + r.route() + .with(|data: (Json, Path, Query)| { + Timeout::new(Duration::from_millis(10), &Arbiter::handle()) + .unwrap() + .and_then(move |_| { + Ok(format!( + "Welcome {} - {}!", + data.1.username, + (data.0).0 + )) + }) + .responder() + }) + }); + }); + + // client request + let request = srv.post() + .uri(srv.url("/test1/index.html?username=test2")) + .header("content-type", "application/json") + .body("{\"test\": 1}") + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + // read response + let bytes = srv.execute(response.body()).unwrap(); + assert_eq!( + bytes, + Bytes::from_static(b"Welcome test1 - {\"test\":1}!") + ); + + // client request + let request = srv.get() + .uri(srv.url("/test1/index.html")) + .finish() + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); +} + #[test] fn test_non_ascii_route() { let mut srv = test::TestServer::new(|app| { diff --git a/tests/test_middleware.rs b/tests/test_middleware.rs index 3216856ec..9a6bf0040 100644 --- a/tests/test_middleware.rs +++ b/tests/test_middleware.rs @@ -74,6 +74,38 @@ fn test_middleware() { assert_eq!(num3.load(Ordering::Relaxed), 1); } +#[test] +fn test_middleware_multiple() { + let num1 = Arc::new(AtomicUsize::new(0)); + let num2 = Arc::new(AtomicUsize::new(0)); + let num3 = Arc::new(AtomicUsize::new(0)); + + let act_num1 = Arc::clone(&num1); + let act_num2 = Arc::clone(&num2); + let act_num3 = Arc::clone(&num3); + + let mut srv = test::TestServer::new(move |app| { + app.middleware(MiddlewareTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }).middleware(MiddlewareTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .handler(|_| HttpResponse::Ok()) + }); + + let request = srv.get().finish().unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + assert_eq!(num1.load(Ordering::Relaxed), 2); + assert_eq!(num2.load(Ordering::Relaxed), 2); + assert_eq!(num3.load(Ordering::Relaxed), 2); +} + #[test] fn test_resource_middleware() { let num1 = Arc::new(AtomicUsize::new(0)); @@ -101,6 +133,38 @@ fn test_resource_middleware() { assert_eq!(num3.load(Ordering::Relaxed), 1); } +#[test] +fn test_resource_middleware_multiple() { + let num1 = Arc::new(AtomicUsize::new(0)); + let num2 = Arc::new(AtomicUsize::new(0)); + let num3 = Arc::new(AtomicUsize::new(0)); + + let act_num1 = Arc::clone(&num1); + let act_num2 = Arc::clone(&num2); + let act_num3 = Arc::clone(&num3); + + let mut srv = test::TestServer::new(move |app| { + app.middleware(MiddlewareTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }).middleware(MiddlewareTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .handler(|_| HttpResponse::Ok()) + }); + + let request = srv.get().finish().unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + assert_eq!(num1.load(Ordering::Relaxed), 2); + assert_eq!(num2.load(Ordering::Relaxed), 2); + assert_eq!(num3.load(Ordering::Relaxed), 2); +} + #[test] fn test_scope_middleware() { let num1 = Arc::new(AtomicUsize::new(0)); @@ -114,7 +178,7 @@ fn test_scope_middleware() { let mut srv = test::TestServer::with_factory(move || { App::new().scope("/scope", |scope| { scope - .middleware(MiddlewareAsyncTest { + .middleware(MiddlewareTest { start: Arc::clone(&act_num1), response: Arc::clone(&act_num2), finish: Arc::clone(&act_num3), @@ -135,6 +199,45 @@ fn test_scope_middleware() { assert_eq!(num3.load(Ordering::Relaxed), 1); } +#[test] +fn test_scope_middleware_multiple() { + let num1 = Arc::new(AtomicUsize::new(0)); + let num2 = Arc::new(AtomicUsize::new(0)); + let num3 = Arc::new(AtomicUsize::new(0)); + + let act_num1 = Arc::clone(&num1); + let act_num2 = Arc::clone(&num2); + let act_num3 = Arc::clone(&num3); + + let mut srv = test::TestServer::with_factory(move || { + App::new().scope("/scope", |scope| { + scope + .middleware(MiddlewareTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .middleware(MiddlewareTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .resource("/test", |r| r.f(|_| HttpResponse::Ok())) + }) + }); + + let request = srv.get() + .uri(srv.url("/scope/test")) + .finish() + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + assert_eq!(num1.load(Ordering::Relaxed), 2); + assert_eq!(num2.load(Ordering::Relaxed), 2); + assert_eq!(num3.load(Ordering::Relaxed), 2); +} + #[test] fn test_middleware_async_handler() { let num1 = Arc::new(AtomicUsize::new(0)); @@ -416,6 +519,42 @@ fn test_async_middleware() { assert_eq!(num3.load(Ordering::Relaxed), 1); } +#[test] +fn test_async_middleware_multiple() { + let num1 = Arc::new(AtomicUsize::new(0)); + let num2 = Arc::new(AtomicUsize::new(0)); + let num3 = Arc::new(AtomicUsize::new(0)); + + let act_num1 = Arc::clone(&num1); + let act_num2 = Arc::clone(&num2); + let act_num3 = Arc::clone(&num3); + + let mut srv = test::TestServer::with_factory(move || { + App::new() + .middleware(MiddlewareAsyncTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .middleware(MiddlewareAsyncTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .resource("/test", |r| r.f(|_| HttpResponse::Ok())) + }); + + let request = srv.get().uri(srv.url("/test")).finish().unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + assert_eq!(num1.load(Ordering::Relaxed), 2); + assert_eq!(num2.load(Ordering::Relaxed), 2); + + thread::sleep(Duration::from_millis(30)); + assert_eq!(num3.load(Ordering::Relaxed), 2); +} + #[test] fn test_async_scope_middleware() { let num1 = Arc::new(AtomicUsize::new(0)); @@ -452,6 +591,47 @@ fn test_async_scope_middleware() { assert_eq!(num3.load(Ordering::Relaxed), 1); } +#[test] +fn test_async_scope_middleware_multiple() { + let num1 = Arc::new(AtomicUsize::new(0)); + let num2 = Arc::new(AtomicUsize::new(0)); + let num3 = Arc::new(AtomicUsize::new(0)); + + let act_num1 = Arc::clone(&num1); + let act_num2 = Arc::clone(&num2); + let act_num3 = Arc::clone(&num3); + + let mut srv = test::TestServer::with_factory(move || { + App::new().scope("/scope", |scope| { + scope + .middleware(MiddlewareAsyncTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .middleware(MiddlewareAsyncTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }) + .resource("/test", |r| r.f(|_| HttpResponse::Ok())) + }) + }); + + let request = srv.get() + .uri(srv.url("/scope/test")) + .finish() + .unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + assert_eq!(num1.load(Ordering::Relaxed), 2); + assert_eq!(num2.load(Ordering::Relaxed), 2); + + thread::sleep(Duration::from_millis(20)); + assert_eq!(num3.load(Ordering::Relaxed), 2); +} + #[test] fn test_async_resource_middleware() { let num1 = Arc::new(AtomicUsize::new(0)); @@ -481,6 +661,45 @@ fn test_async_resource_middleware() { assert_eq!(num1.load(Ordering::Relaxed), 1); assert_eq!(num2.load(Ordering::Relaxed), 1); - thread::sleep(Duration::from_millis(20)); + thread::sleep(Duration::from_millis(40)); assert_eq!(num3.load(Ordering::Relaxed), 1); } + +#[test] +fn test_async_resource_middleware_multiple() { + let num1 = Arc::new(AtomicUsize::new(0)); + let num2 = Arc::new(AtomicUsize::new(0)); + let num3 = Arc::new(AtomicUsize::new(0)); + + let act_num1 = Arc::clone(&num1); + let act_num2 = Arc::clone(&num2); + let act_num3 = Arc::clone(&num3); + + let mut srv = test::TestServer::with_factory(move || { + let mw1 = MiddlewareAsyncTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }; + let mw2 = MiddlewareAsyncTest { + start: Arc::clone(&act_num1), + response: Arc::clone(&act_num2), + finish: Arc::clone(&act_num3), + }; + App::new().resource("/test", move |r| { + r.middleware(mw1); + r.middleware(mw2); + r.h(|_| HttpResponse::Ok()); + }) + }); + + let request = srv.get().uri(srv.url("/test")).finish().unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + assert_eq!(num1.load(Ordering::Relaxed), 2); + assert_eq!(num2.load(Ordering::Relaxed), 2); + + thread::sleep(Duration::from_millis(40)); + assert_eq!(num3.load(Ordering::Relaxed), 2); +}