mirror of https://github.com/fafhrd91/actix-web
Expose option for setting TLS handshake timeout
This commit is contained in:
parent
dce57a79c9
commit
fcba8a3858
|
@ -69,6 +69,8 @@ pub use self::payload::{BoxedPayloadStream, Payload, PayloadStream};
|
|||
pub use self::requests::{Request, RequestHead, RequestHeadType};
|
||||
pub use self::responses::{Response, ResponseBuilder, ResponseHead};
|
||||
pub use self::service::HttpService;
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
pub use self::service::TlsAcceptorConfig;
|
||||
|
||||
/// A major HTTP protocol version.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -181,6 +181,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
pub struct TlsAcceptorConfig {
|
||||
pub(crate) handshake_timeout: Option<std::time::Duration>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
impl TlsAcceptorConfig {
|
||||
pub fn new(handshake_timeout: Option<std::time::Duration>) -> Self {
|
||||
Self { handshake_timeout }
|
||||
}
|
||||
|
||||
pub fn handshake_timeout(self, dur: std::time::Duration) -> Self {
|
||||
Self {
|
||||
handshake_timeout: Some(dur),
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
mod openssl {
|
||||
use actix_service::ServiceFactoryExt as _;
|
||||
|
@ -230,7 +249,27 @@ mod openssl {
|
|||
Error = TlsError<SslError, DispatchError>,
|
||||
InitError = (),
|
||||
> {
|
||||
Acceptor::new(acceptor)
|
||||
self.openssl_with_config(acceptor, TlsAcceptorConfig::new(None))
|
||||
}
|
||||
|
||||
/// Create OpenSSL based service with configuration.
|
||||
pub fn openssl_with_config(
|
||||
self,
|
||||
acceptor: SslAcceptor,
|
||||
tls_acceptor_config: TlsAcceptorConfig,
|
||||
) -> impl ServiceFactory<
|
||||
TcpStream,
|
||||
Config = (),
|
||||
Response = (),
|
||||
Error = TlsError<SslError, DispatchError>,
|
||||
InitError = (),
|
||||
> {
|
||||
let mut acceptor = Acceptor::new(acceptor);
|
||||
if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
|
||||
acceptor.set_handshake_timeout(handshake_timeout);
|
||||
}
|
||||
|
||||
acceptor
|
||||
.map_init_err(|_| {
|
||||
unreachable!("TLS acceptor service factory does not error on init")
|
||||
})
|
||||
|
@ -293,8 +332,23 @@ mod rustls {
|
|||
{
|
||||
/// Create Rustls based service.
|
||||
pub fn rustls(
|
||||
self,
|
||||
config: ServerConfig,
|
||||
) -> impl ServiceFactory<
|
||||
TcpStream,
|
||||
Config = (),
|
||||
Response = (),
|
||||
Error = TlsError<io::Error, DispatchError>,
|
||||
InitError = (),
|
||||
> {
|
||||
self.rustls_with_config(config, TlsAcceptorConfig::new(None))
|
||||
}
|
||||
|
||||
/// Create Rustls based service with configuration.
|
||||
pub fn rustls_with_config(
|
||||
self,
|
||||
mut config: ServerConfig,
|
||||
tls_acceptor_config: TlsAcceptorConfig,
|
||||
) -> impl ServiceFactory<
|
||||
TcpStream,
|
||||
Config = (),
|
||||
|
@ -306,7 +360,11 @@ mod rustls {
|
|||
protos.extend_from_slice(&config.alpn_protocols);
|
||||
config.alpn_protocols = protos;
|
||||
|
||||
Acceptor::new(config)
|
||||
let mut acceptor = Acceptor::new(config);
|
||||
if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
|
||||
acceptor.set_handshake_timeout(handshake_timeout);
|
||||
}
|
||||
acceptor
|
||||
.map_init_err(|_| {
|
||||
unreachable!("TLS acceptor service factory does not error on init")
|
||||
})
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
extern crate tls_openssl as openssl;
|
||||
|
||||
use std::time::Duration;
|
||||
use std::{convert::Infallible, io};
|
||||
|
||||
use actix_http::{
|
||||
body::{BodyStream, BoxBody, SizedStream},
|
||||
error::PayloadError,
|
||||
header::{self, HeaderValue},
|
||||
Error, HttpService, Method, Request, Response, StatusCode, Version,
|
||||
Error, HttpService, Method, Request, Response, StatusCode, TlsAcceptorConfig, Version,
|
||||
};
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_service, ServiceFactoryExt};
|
||||
|
@ -89,7 +90,10 @@ async fn h2_1() -> io::Result<()> {
|
|||
assert_eq!(req.version(), Version::HTTP_2);
|
||||
ok::<_, Error>(Response::ok())
|
||||
})
|
||||
.openssl(tls_config())
|
||||
.openssl_with_config(
|
||||
tls_config(),
|
||||
TlsAcceptorConfig::new(Some(Duration::from_secs(5))),
|
||||
)
|
||||
.map_err(|_| ())
|
||||
})
|
||||
.await;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
- Add `Route::wrap()` to allow individual routes to use middleware. [#2725]
|
||||
- Add `ServiceConfig::default_service()`. [#2338] [#2743]
|
||||
- Implement `ResponseError` for `std::convert::Infallible`
|
||||
- Add `tls_handshake_timeout` server configuration option to configure TLS handshake timeout [#2752]
|
||||
|
||||
### Fixed
|
||||
- Clear connection-level data on `HttpRequest` drop. [#2742]
|
||||
|
|
|
@ -18,6 +18,9 @@ use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorB
|
|||
#[cfg(feature = "rustls")]
|
||||
use actix_tls::accept::rustls::reexports::ServerConfig as RustlsServerConfig;
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
use actix_http::TlsAcceptorConfig;
|
||||
|
||||
use crate::{config::AppConfig, Error};
|
||||
|
||||
struct Socket {
|
||||
|
@ -30,6 +33,8 @@ struct Config {
|
|||
keep_alive: KeepAlive,
|
||||
client_request_timeout: Duration,
|
||||
client_disconnect_timeout: Duration,
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
tls_handshake_timeout: Option<Duration>,
|
||||
}
|
||||
|
||||
/// An HTTP Server.
|
||||
|
@ -92,6 +97,8 @@ where
|
|||
keep_alive: KeepAlive::default(),
|
||||
client_request_timeout: Duration::from_secs(5),
|
||||
client_disconnect_timeout: Duration::from_secs(1),
|
||||
#[cfg(any(feature = "rustls", feature = "openssl"))]
|
||||
tls_handshake_timeout: None,
|
||||
})),
|
||||
backlog: 1024,
|
||||
sockets: Vec::new(),
|
||||
|
@ -225,6 +232,22 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||
/// Set TLS handshake timeout.
|
||||
///
|
||||
/// Defines a timeout for TLS handshake. If the TLS handshake does not complete
|
||||
/// within this time, the connection is closed.
|
||||
///
|
||||
/// By default handshake timeout is set to 3000 milliseconds.
|
||||
pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
|
||||
self.config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.tls_handshake_timeout
|
||||
.replace(dur);
|
||||
self
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(since = "4.0.0", note = "Renamed to `client_disconnect_timeout`.")]
|
||||
pub fn client_shutdown(self, dur: u64) -> Self {
|
||||
|
@ -379,7 +402,10 @@ where
|
|||
svc.finish(map_config(fac, move |_| {
|
||||
AppConfig::new(true, host.clone(), addr)
|
||||
}))
|
||||
.openssl(acceptor.clone())
|
||||
.openssl_with_config(
|
||||
acceptor.clone(),
|
||||
TlsAcceptorConfig::new(c.tls_handshake_timeout),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(self)
|
||||
|
@ -437,7 +463,10 @@ where
|
|||
svc.finish(map_config(fac, move |_| {
|
||||
AppConfig::new(true, host.clone(), addr)
|
||||
}))
|
||||
.rustls(config.clone())
|
||||
.rustls_with_config(
|
||||
config.clone(),
|
||||
TlsAcceptorConfig::new(c.tls_handshake_timeout),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(self)
|
||||
|
|
Loading…
Reference in New Issue