diff --git a/src/server/acceptor.rs b/src/server/acceptor.rs index 15d66112..3dcd8ac8 100644 --- a/src/server/acceptor.rs +++ b/src/server/acceptor.rs @@ -176,12 +176,15 @@ where /// Applies timeout to request prcoessing. pub(crate) struct AcceptorTimeout { inner: T, - timeout: u64, + timeout: Duration, } impl AcceptorTimeout { pub(crate) fn new(timeout: u64, inner: T) -> Self { - Self { inner, timeout } + Self { + inner, + timeout: Duration::from_millis(timeout), + } } } @@ -204,7 +207,7 @@ impl NewService for AcceptorTimeout { #[doc(hidden)] pub(crate) struct AcceptorTimeoutFut { fut: T::Future, - timeout: u64, + timeout: Duration, } impl Future for AcceptorTimeoutFut { @@ -225,7 +228,7 @@ impl Future for AcceptorTimeoutFut { /// Applies timeout to request prcoessing. pub(crate) struct AcceptorTimeoutService { inner: T, - timeout: u64, + timeout: Duration, } impl Service for AcceptorTimeoutService { @@ -241,7 +244,7 @@ impl Service for AcceptorTimeoutService { fn call(&mut self, req: Self::Request) -> Self::Future { AcceptorTimeoutResponse { fut: self.inner.call(req), - sleep: sleep(Duration::from_millis(self.timeout)), + sleep: sleep(self.timeout), } } } diff --git a/src/server/builder.rs b/src/server/builder.rs index 6bafb460..8a979752 100644 --- a/src/server/builder.rs +++ b/src/server/builder.rs @@ -59,18 +59,6 @@ where ); if secure { - Either::A(ServerMessageAcceptor::new( - settings.clone(), - TcpAcceptor::new(acceptor.create().map_err(AcceptorError::Service)) - .map_err(|_| ()) - .map_init_err(|_| ()) - .and_then( - HttpService::new(settings) - .map_init_err(|_| ()) - .map_err(|_| ()), - ), - )) - } else { Either::B(ServerMessageAcceptor::new( settings.clone(), TcpAcceptor::new(AcceptorTimeout::new( @@ -84,25 +72,23 @@ where .map_err(|_| ()), ), )) + } else { + Either::A(ServerMessageAcceptor::new( + settings.clone(), + TcpAcceptor::new(acceptor.create().map_err(AcceptorError::Service)) + .map_err(|_| ()) + .map_init_err(|_| ()) + .and_then( + HttpService::new(settings) + .map_init_err(|_| ()) + .map_err(|_| ()), + ), + )) } } } } -impl Clone for HttpServiceBuilder -where - F: Fn() -> H + Send + Clone, - H: IntoHttpHandler, - A: AcceptorServiceFactory, -{ - fn clone(&self) -> Self { - HttpServiceBuilder { - factory: self.factory.clone(), - acceptor: self.acceptor.clone(), - } - } -} - impl ServiceProvider for HttpServiceBuilder where F: Fn() -> H + Send + Clone + 'static, diff --git a/tests/test_server.rs b/tests/test_server.rs index 03a89642..4f33e313 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -15,6 +15,9 @@ extern crate tokio_current_thread as current_thread; extern crate tokio_reactor; extern crate tokio_tcp; +#[cfg(feature = "ssl")] +extern crate openssl; + use std::io::{Read, Write}; use std::sync::Arc; use std::{thread, time}; @@ -1084,13 +1087,13 @@ fn test_slow_request() { let mut stream = net::TcpStream::connect(addr).unwrap(); let mut data = String::new(); let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 408 Request Timeou")); + assert!(data.starts_with("HTTP/1.1 408 Request Timeout")); let mut stream = net::TcpStream::connect(addr).unwrap(); let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n"); let mut data = String::new(); let _ = stream.read_to_string(&mut data); - assert!(data.starts_with("HTTP/1.1 408 Request Timeou")); + assert!(data.starts_with("HTTP/1.1 408 Request Timeout")); sys.stop(); } @@ -1106,9 +1109,9 @@ fn test_malformed_request() { thread::spawn(move || { System::run(move || { let srv = server::new(|| { - vec![App::new().resource("/", |r| { + App::new().resource("/", |r| { r.method(http::Method::GET).f(|_| HttpResponse::Ok()) - })] + }) }); let _ = srv.bind(addr).unwrap().start(); @@ -1126,3 +1129,64 @@ fn test_malformed_request() { sys.stop(); } + +#[test] +fn test_app_404() { + let mut srv = test::TestServer::with_factory(|| { + App::new().prefix("/prefix").resource("/", |r| { + r.method(http::Method::GET).f(|_| HttpResponse::Ok()) + }) + }); + + let request = srv.client(http::Method::GET, "/prefix/").finish().unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert!(response.status().is_success()); + + let request = srv.client(http::Method::GET, "/").finish().unwrap(); + let response = srv.execute(request.send()).unwrap(); + assert_eq!(response.status(), http::StatusCode::NOT_FOUND); +} + +#[test] +#[cfg(feature = "ssl")] +fn test_ssl_handshake_timeout() { + use actix::System; + use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; + use std::net; + use std::sync::mpsc; + + let (tx, rx) = mpsc::channel(); + let addr = test::TestServer::unused_addr(); + + // load ssl keys + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + builder + .set_private_key_file("tests/key.pem", SslFiletype::PEM) + .unwrap(); + builder + .set_certificate_chain_file("tests/cert.pem") + .unwrap(); + + thread::spawn(move || { + System::run(move || { + let srv = server::new(|| { + App::new().resource("/", |r| { + r.method(http::Method::GET).f(|_| HttpResponse::Ok()) + }) + }); + + srv.bind_ssl(addr, builder) + .unwrap() + .workers(1) + .client_timeout(200) + .start(); + let _ = tx.send(System::current()); + }); + }); + let sys = rx.recv().unwrap(); + + let mut stream = net::TcpStream::connect(addr).unwrap(); + let mut data = String::new(); + let _ = stream.read_to_string(&mut data); + assert!(data.is_empty()) +} diff --git a/tests/test_ws.rs b/tests/test_ws.rs index 522832e0..ebb5ff29 100644 --- a/tests/test_ws.rs +++ b/tests/test_ws.rs @@ -14,7 +14,7 @@ use futures::Stream; use rand::distributions::Alphanumeric; use rand::Rng; -#[cfg(feature = "alpn")] +#[cfg(feature = "ssl")] extern crate openssl; #[cfg(feature = "rust-tls")] extern crate rustls; @@ -282,7 +282,7 @@ fn test_server_send_bin() { } #[test] -#[cfg(feature = "alpn")] +#[cfg(feature = "ssl")] fn test_ws_server_ssl() { extern crate openssl; use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};