mirror of https://github.com/fafhrd91/actix-web
				
				
				
			fix ssh handshake timeout
This commit is contained in:
		
							parent
							
								
									61c7534e03
								
							
						
					
					
						commit
						724668910b
					
				|  | @ -176,12 +176,15 @@ where | ||||||
| /// Applies timeout to request prcoessing.
 | /// Applies timeout to request prcoessing.
 | ||||||
| pub(crate) struct AcceptorTimeout<T> { | pub(crate) struct AcceptorTimeout<T> { | ||||||
|     inner: T, |     inner: T, | ||||||
|     timeout: u64, |     timeout: Duration, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<T: NewService> AcceptorTimeout<T> { | impl<T: NewService> AcceptorTimeout<T> { | ||||||
|     pub(crate) fn new(timeout: u64, inner: T) -> Self { |     pub(crate) fn new(timeout: u64, inner: T) -> Self { | ||||||
|         Self { inner, timeout } |         Self { | ||||||
|  |             inner, | ||||||
|  |             timeout: Duration::from_millis(timeout), | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -204,7 +207,7 @@ impl<T: NewService> NewService for AcceptorTimeout<T> { | ||||||
| #[doc(hidden)] | #[doc(hidden)] | ||||||
| pub(crate) struct AcceptorTimeoutFut<T: NewService> { | pub(crate) struct AcceptorTimeoutFut<T: NewService> { | ||||||
|     fut: T::Future, |     fut: T::Future, | ||||||
|     timeout: u64, |     timeout: Duration, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<T: NewService> Future for AcceptorTimeoutFut<T> { | impl<T: NewService> Future for AcceptorTimeoutFut<T> { | ||||||
|  | @ -225,7 +228,7 @@ impl<T: NewService> Future for AcceptorTimeoutFut<T> { | ||||||
| /// Applies timeout to request prcoessing.
 | /// Applies timeout to request prcoessing.
 | ||||||
| pub(crate) struct AcceptorTimeoutService<T> { | pub(crate) struct AcceptorTimeoutService<T> { | ||||||
|     inner: T, |     inner: T, | ||||||
|     timeout: u64, |     timeout: Duration, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<T: Service> Service for AcceptorTimeoutService<T> { | impl<T: Service> Service for AcceptorTimeoutService<T> { | ||||||
|  | @ -241,7 +244,7 @@ impl<T: Service> Service for AcceptorTimeoutService<T> { | ||||||
|     fn call(&mut self, req: Self::Request) -> Self::Future { |     fn call(&mut self, req: Self::Request) -> Self::Future { | ||||||
|         AcceptorTimeoutResponse { |         AcceptorTimeoutResponse { | ||||||
|             fut: self.inner.call(req), |             fut: self.inner.call(req), | ||||||
|             sleep: sleep(Duration::from_millis(self.timeout)), |             sleep: sleep(self.timeout), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -59,18 +59,6 @@ where | ||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|             if secure { |             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( |                 Either::B(ServerMessageAcceptor::new( | ||||||
|                     settings.clone(), |                     settings.clone(), | ||||||
|                     TcpAcceptor::new(AcceptorTimeout::new( |                     TcpAcceptor::new(AcceptorTimeout::new( | ||||||
|  | @ -84,25 +72,23 @@ where | ||||||
|                             .map_err(|_| ()), |                             .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<F, H, A> Clone for HttpServiceBuilder<F, H, A> |  | ||||||
| where |  | ||||||
|     F: Fn() -> H + Send + Clone, |  | ||||||
|     H: IntoHttpHandler, |  | ||||||
|     A: AcceptorServiceFactory, |  | ||||||
| { |  | ||||||
|     fn clone(&self) -> Self { |  | ||||||
|         HttpServiceBuilder { |  | ||||||
|             factory: self.factory.clone(), |  | ||||||
|             acceptor: self.acceptor.clone(), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<F, H, A> ServiceProvider for HttpServiceBuilder<F, H, A> | impl<F, H, A> ServiceProvider for HttpServiceBuilder<F, H, A> | ||||||
| where | where | ||||||
|     F: Fn() -> H + Send + Clone + 'static, |     F: Fn() -> H + Send + Clone + 'static, | ||||||
|  |  | ||||||
|  | @ -15,6 +15,9 @@ extern crate tokio_current_thread as current_thread; | ||||||
| extern crate tokio_reactor; | extern crate tokio_reactor; | ||||||
| extern crate tokio_tcp; | extern crate tokio_tcp; | ||||||
| 
 | 
 | ||||||
|  | #[cfg(feature = "ssl")] | ||||||
|  | extern crate openssl; | ||||||
|  | 
 | ||||||
| use std::io::{Read, Write}; | use std::io::{Read, Write}; | ||||||
| use std::sync::Arc; | use std::sync::Arc; | ||||||
| use std::{thread, time}; | use std::{thread, time}; | ||||||
|  | @ -1084,13 +1087,13 @@ fn test_slow_request() { | ||||||
|     let mut stream = net::TcpStream::connect(addr).unwrap(); |     let mut stream = net::TcpStream::connect(addr).unwrap(); | ||||||
|     let mut data = String::new(); |     let mut data = String::new(); | ||||||
|     let _ = stream.read_to_string(&mut data); |     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 mut stream = net::TcpStream::connect(addr).unwrap(); | ||||||
|     let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n"); |     let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n"); | ||||||
|     let mut data = String::new(); |     let mut data = String::new(); | ||||||
|     let _ = stream.read_to_string(&mut data); |     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(); |     sys.stop(); | ||||||
| } | } | ||||||
|  | @ -1106,9 +1109,9 @@ fn test_malformed_request() { | ||||||
|     thread::spawn(move || { |     thread::spawn(move || { | ||||||
|         System::run(move || { |         System::run(move || { | ||||||
|             let srv = server::new(|| { |             let srv = server::new(|| { | ||||||
|                 vec![App::new().resource("/", |r| { |                 App::new().resource("/", |r| { | ||||||
|                     r.method(http::Method::GET).f(|_| HttpResponse::Ok()) |                     r.method(http::Method::GET).f(|_| HttpResponse::Ok()) | ||||||
|                 })] |                 }) | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             let _ = srv.bind(addr).unwrap().start(); |             let _ = srv.bind(addr).unwrap().start(); | ||||||
|  | @ -1126,3 +1129,64 @@ fn test_malformed_request() { | ||||||
| 
 | 
 | ||||||
|     sys.stop(); |     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()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ use futures::Stream; | ||||||
| use rand::distributions::Alphanumeric; | use rand::distributions::Alphanumeric; | ||||||
| use rand::Rng; | use rand::Rng; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "alpn")] | #[cfg(feature = "ssl")] | ||||||
| extern crate openssl; | extern crate openssl; | ||||||
| #[cfg(feature = "rust-tls")] | #[cfg(feature = "rust-tls")] | ||||||
| extern crate rustls; | extern crate rustls; | ||||||
|  | @ -282,7 +282,7 @@ fn test_server_send_bin() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| #[cfg(feature = "alpn")] | #[cfg(feature = "ssl")] | ||||||
| fn test_ws_server_ssl() { | fn test_ws_server_ssl() { | ||||||
|     extern crate openssl; |     extern crate openssl; | ||||||
|     use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; |     use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue