mirror of
https://github.com/fafhrd91/actix-web
synced 2025-06-27 07:19:04 +02:00
actix-web: Add rustls 0.23 (#3363)
* Fix type confusion in some scenarios When the feature for rustls 0.22 is enabled, and rustls 0.23 is also present in a project, there suddently exist multiple paths for errors when building middleware chains due to the use of two consecutive `?` operators without specifying the intermediate error type. This commit addresses the issue by removing the first `?`, so that the first error type will always be known, and the second `?` always has a well defined implementation. * Add CHANGES entry about type confusion * actix-http: add rustls 0.23 support * actix-http: update ws example, tests for rustls 0.23 * actix-http: add rustls 0.23 to changelog * Update comments to mention 0.23 instead of 0.22 * awc: add rustls 0.23 support This also fixes certificate lookup when native-roots is enabled for rustls 0.22. * awc: update changelog for rustls 0.23 * awc: Add base rustls-0_23 feature without roots to better enable custom config * actix-test: add rustls-0.23 * actix-test: add rustls 0.23 to changelog * awc: update changelog with rustls 0.23 tweaks * actix-web: add rustls 0.23 * Add rustls-0_23 to CI * Update tls_rustls.rs * review nits * review nits part 2 * fix doc test --------- Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
@ -5,6 +5,9 @@
|
||||
### Added
|
||||
|
||||
- Add `unicode` crate feature (on-by-default) to switch between `regex` and `regex-lite` as a trade-off between full unicode support and binary size.
|
||||
- Add `rustls-0_23` crate feature.
|
||||
- Add `HttpServer::{bind_rustls_0_23, listen_rustls_0_23}()` builder methods.
|
||||
- Add `HttpServer::tls_handshake_timeout()` builder method for `rustls-0_22` and `rustls-0_23`.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -27,6 +27,7 @@ features = [
|
||||
"rustls-0_20",
|
||||
"rustls-0_21",
|
||||
"rustls-0_22",
|
||||
"rustls-0_23",
|
||||
"compress-brotli",
|
||||
"compress-gzip",
|
||||
"compress-zstd",
|
||||
@ -71,6 +72,8 @@ rustls-0_20 = ["http2", "actix-http/rustls-0_20", "actix-tls/accept", "actix-tls
|
||||
rustls-0_21 = ["http2", "actix-http/rustls-0_21", "actix-tls/accept", "actix-tls/rustls-0_21"]
|
||||
# TLS via Rustls v0.22
|
||||
rustls-0_22 = ["http2", "actix-http/rustls-0_22", "actix-tls/accept", "actix-tls/rustls-0_22"]
|
||||
# TLS via Rustls v0.23
|
||||
rustls-0_23 = ["http2", "actix-http/rustls-0_23", "actix-tls/accept", "actix-tls/rustls-0_23"]
|
||||
|
||||
# Full unicode support
|
||||
unicode = ["dep:regex", "actix-router/unicode"]
|
||||
@ -122,7 +125,7 @@ url = "2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-files = "0.6"
|
||||
actix-test = { version = "0.1", features = ["openssl", "rustls-0_22"] }
|
||||
actix-test = { version = "0.1", features = ["openssl", "rustls-0_23"] }
|
||||
awc = { version = "3", features = ["openssl"] }
|
||||
|
||||
brotli = "6"
|
||||
@ -137,7 +140,7 @@ rustls-pemfile = "2"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
static_assertions = "1"
|
||||
tls-openssl = { package = "openssl", version = "0.10.55" }
|
||||
tls-rustls = { package = "rustls", version = "0.22" }
|
||||
tls-rustls = { package = "rustls", version = "0.23" }
|
||||
tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] }
|
||||
zstd = "0.13"
|
||||
|
||||
|
@ -64,7 +64,10 @@
|
||||
//! - `compress-gzip` - gzip and deflate content encoding compression support (enabled by default)
|
||||
//! - `compress-zstd` - zstd content encoding compression support (enabled by default)
|
||||
//! - `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
|
||||
//! - `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2`
|
||||
//! - `rustls` - HTTPS support via `rustls` 0.20 crate, supports `HTTP/2`
|
||||
//! - `rustls-0_21` - HTTPS support via `rustls` 0.21 crate, supports `HTTP/2`
|
||||
//! - `rustls-0_22` - HTTPS support via `rustls` 0.22 crate, supports `HTTP/2`
|
||||
//! - `rustls-0_23` - HTTPS support via `rustls` 0.23 crate, supports `HTTP/2`
|
||||
//! - `secure-cookies` - secure cookies support
|
||||
|
||||
#![deny(rust_2018_idioms, nonstandard_style)]
|
||||
|
@ -12,6 +12,7 @@ use std::{
|
||||
feature = "rustls-0_20",
|
||||
feature = "rustls-0_21",
|
||||
feature = "rustls-0_22",
|
||||
feature = "rustls-0_23",
|
||||
))]
|
||||
use actix_http::TlsAcceptorConfig;
|
||||
use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
|
||||
@ -242,7 +243,13 @@ where
|
||||
/// time, the connection is closed.
|
||||
///
|
||||
/// By default, the handshake timeout is 3 seconds.
|
||||
#[cfg(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21"))]
|
||||
#[cfg(any(
|
||||
feature = "openssl",
|
||||
feature = "rustls-0_20",
|
||||
feature = "rustls-0_21",
|
||||
feature = "rustls-0_22",
|
||||
feature = "rustls-0_23",
|
||||
))]
|
||||
pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
|
||||
self.config
|
||||
.lock()
|
||||
@ -270,6 +277,10 @@ where
|
||||
/// Rustls v0.20.
|
||||
/// - `actix_tls::accept::rustls_0_21::TlsStream<actix_web::rt::net::TcpStream>` when using
|
||||
/// Rustls v0.21.
|
||||
/// - `actix_tls::accept::rustls_0_22::TlsStream<actix_web::rt::net::TcpStream>` when using
|
||||
/// Rustls v0.22.
|
||||
/// - `actix_tls::accept::rustls_0_23::TlsStream<actix_web::rt::net::TcpStream>` when using
|
||||
/// Rustls v0.23.
|
||||
/// - `actix_web::rt::net::TcpStream` when no encryption is used.
|
||||
///
|
||||
/// See the `on_connect` example for additional details.
|
||||
@ -466,6 +477,25 @@ where
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Resolves socket address(es) and binds server to created listener(s) for TLS connections
|
||||
/// using Rustls v0.23.
|
||||
///
|
||||
/// See [`bind()`](Self::bind()) for more details on `addrs` argument.
|
||||
///
|
||||
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
|
||||
#[cfg(feature = "rustls-0_23")]
|
||||
pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
|
||||
mut self,
|
||||
addrs: A,
|
||||
config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
|
||||
) -> io::Result<Self> {
|
||||
let sockets = bind_addrs(addrs, self.backlog)?;
|
||||
for lst in sockets {
|
||||
self = self.listen_rustls_0_23_inner(lst, config.clone())?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Resolves socket address(es) and binds server to created listener(s) for TLS connections
|
||||
/// using OpenSSL.
|
||||
///
|
||||
@ -595,7 +625,7 @@ where
|
||||
/// Binds to existing listener for accepting incoming TLS connection requests using Rustls
|
||||
/// v0.21.
|
||||
///
|
||||
/// See [`listen()`](Self::listen) for more details on the `lst` argument.
|
||||
/// See [`listen()`](Self::listen()) for more details on the `lst` argument.
|
||||
///
|
||||
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
|
||||
#[cfg(feature = "rustls-0_21")]
|
||||
@ -712,7 +742,7 @@ where
|
||||
/// Binds to existing listener for accepting incoming TLS connection requests using Rustls
|
||||
/// v0.22.
|
||||
///
|
||||
/// See [`listen()`](Self::listen) for more details on the `lst` argument.
|
||||
/// See [`listen()`](Self::listen()) for more details on the `lst` argument.
|
||||
///
|
||||
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
|
||||
#[cfg(feature = "rustls-0_22")]
|
||||
@ -775,6 +805,72 @@ where
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Binds to existing listener for accepting incoming TLS connection requests using Rustls
|
||||
/// v0.23.
|
||||
///
|
||||
/// See [`listen()`](Self::listen()) for more details on the `lst` argument.
|
||||
///
|
||||
/// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
|
||||
#[cfg(feature = "rustls-0_23")]
|
||||
pub fn listen_rustls_0_23(
|
||||
self,
|
||||
lst: net::TcpListener,
|
||||
config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
|
||||
) -> io::Result<Self> {
|
||||
self.listen_rustls_0_23_inner(lst, config)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls-0_23")]
|
||||
fn listen_rustls_0_23_inner(
|
||||
mut self,
|
||||
lst: net::TcpListener,
|
||||
config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
|
||||
) -> io::Result<Self> {
|
||||
let factory = self.factory.clone();
|
||||
let cfg = self.config.clone();
|
||||
let addr = lst.local_addr().unwrap();
|
||||
self.sockets.push(Socket {
|
||||
addr,
|
||||
scheme: "https",
|
||||
});
|
||||
|
||||
let on_connect_fn = self.on_connect_fn.clone();
|
||||
|
||||
self.builder =
|
||||
self.builder
|
||||
.listen(format!("actix-web-service-{}", addr), lst, move || {
|
||||
let c = cfg.lock().unwrap();
|
||||
let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
|
||||
|
||||
let svc = HttpService::build()
|
||||
.keep_alive(c.keep_alive)
|
||||
.client_request_timeout(c.client_request_timeout)
|
||||
.client_disconnect_timeout(c.client_disconnect_timeout);
|
||||
|
||||
let svc = if let Some(handler) = on_connect_fn.clone() {
|
||||
svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
|
||||
} else {
|
||||
svc
|
||||
};
|
||||
|
||||
let fac = factory()
|
||||
.into_factory()
|
||||
.map_err(|err| err.into().error_response());
|
||||
|
||||
let acceptor_config = match c.tls_handshake_timeout {
|
||||
Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
|
||||
None => TlsAcceptorConfig::default(),
|
||||
};
|
||||
|
||||
svc.finish(map_config(fac, move |_| {
|
||||
AppConfig::new(true, host.clone(), addr)
|
||||
}))
|
||||
.rustls_0_23_with_config(config.clone(), acceptor_config)
|
||||
})?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Binds to existing listener for accepting incoming TLS connection requests using OpenSSL.
|
||||
///
|
||||
/// See [`listen()`](Self::listen) for more details on the `lst` argument.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#[cfg(feature = "openssl")]
|
||||
extern crate tls_openssl as openssl;
|
||||
#[cfg(feature = "rustls-0_22")]
|
||||
#[cfg(feature = "rustls-0_23")]
|
||||
extern crate tls_rustls as rustls;
|
||||
|
||||
use std::{
|
||||
@ -704,7 +704,7 @@ async fn test_brotli_encoding_large_openssl() {
|
||||
srv.stop().await;
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls-0_22")]
|
||||
#[cfg(feature = "rustls-0_23")]
|
||||
mod plus_rustls {
|
||||
use std::io::BufReader;
|
||||
|
||||
@ -740,7 +740,7 @@ mod plus_rustls {
|
||||
.map(char::from)
|
||||
.collect::<String>();
|
||||
|
||||
let srv = actix_test::start_with(actix_test::config().rustls_0_22(tls_config()), || {
|
||||
let srv = actix_test::start_with(actix_test::config().rustls_0_23(tls_config()), || {
|
||||
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async {
|
||||
// echo decompressed request body back in response
|
||||
HttpResponse::Ok()
|
||||
|
Reference in New Issue
Block a user