Repository: actix/actix-web (language: rust)

Issue:
TLS handshake rate limit adjustment does not work for rustls 0.22 & 0.23
Your issue may already be reported! Please search on the [Actix Web issue tracker](https://github.com/actix/actix-web/issues) before creating one.

## Expected Behavior

[HttpServer::method.max_connection_rate](https://docs.rs/actix-web/latest/actix_web/struct.HttpServer.html#method.max_connection_rate) should allow to adjust TLS handshakes per second as suggested by documentation when used with any version of rustls or openssl.
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->

## Current Behavior

<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
When used with `rustls 0.22` or `0.23` due to conditional compilation part of code to adjust handshake per seconds is ingored.

## Possible Solution

<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
Will be provided as pull request.

## Steps to Reproduce (for bugs)

<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->

1. Receive `> 256` new TLS connections per second per worker.

## Context

<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
In case of incoming TLS handshakes exceed default limit of `256` per second service to start accepting connection slower with part of the connections reset at TCP level.

## Your Environment

<!--- Include as many relevant details about the environment you experienced the bug in -->

- Rust Version (I.e, output of `rustc -V`): `rustc 1.79.0 (129f3b996 2024-06-10)`
- Actix Web Version: `actix-web 4.7.0`



Discussion / hints:

Fix patch:
diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml
index 4dc0f0bd82d..25e8b28f507 100644
--- a/actix-http/Cargo.toml
+++ b/actix-http/Cargo.toml
@@ -70,22 +70,22 @@ ws = [
 ]
 
 # TLS via OpenSSL
-openssl = ["actix-tls/accept", "actix-tls/openssl"]
+openssl = ["__tls", "actix-tls/accept", "actix-tls/openssl"]
 
 # TLS via Rustls v0.20
-rustls = ["rustls-0_20"]
+rustls = ["__tls", "rustls-0_20"]
 
 # TLS via Rustls v0.20
-rustls-0_20 = ["actix-tls/accept", "actix-tls/rustls-0_20"]
+rustls-0_20 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_20"]
 
 # TLS via Rustls v0.21
-rustls-0_21 = ["actix-tls/accept", "actix-tls/rustls-0_21"]
+rustls-0_21 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_21"]
 
 # TLS via Rustls v0.22
-rustls-0_22 = ["actix-tls/accept", "actix-tls/rustls-0_22"]
+rustls-0_22 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_22"]
 
 # TLS via Rustls v0.23
-rustls-0_23 = ["actix-tls/accept", "actix-tls/rustls-0_23"]
+rustls-0_23 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_23"]
 
 # Compression codecs
 compress-brotli = ["__compress", "brotli"]
@@ -96,6 +96,10 @@ compress-zstd   = ["__compress", "zstd"]
 # Don't rely on these whatsoever. They are semver-exempt and may disappear at anytime.
 __compress = []
 
+# Internal (PRIVATE!) features used to aid checking feature status.
+# Don't rely on these whatsoever. They may disappear at anytime.
+__tls = []
+
 [dependencies]
 actix-service = "2"
 actix-codec = "0.5"
diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs
index f9697c4d5fb..b76032ba3dd 100644
--- a/actix-http/src/lib.rs
+++ b/actix-http/src/lib.rs
@@ -61,13 +61,7 @@ pub mod ws;
 
 #[allow(deprecated)]
 pub use self::payload::PayloadStream;
-#[cfg(any(
-    feature = "openssl",
-    feature = "rustls-0_20",
-    feature = "rustls-0_21",
-    feature = "rustls-0_22",
-    feature = "rustls-0_23",
-))]
+#[cfg(feature = "__tls")]
 pub use self::service::TlsAcceptorConfig;
 pub use self::{
     builder::HttpServiceBuilder,
diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs
index a58be93c756..37cee960f18 100644
--- a/actix-http/src/service.rs
+++ b/actix-http/src/service.rs
@@ -241,25 +241,13 @@ where
 }
 
 /// Configuration options used when accepting TLS connection.
-#[cfg(any(
-    feature = "openssl",
-    feature = "rustls-0_20",
-    feature = "rustls-0_21",
-    feature = "rustls-0_22",
-    feature = "rustls-0_23",
-))]
+#[cfg(feature = "__tls")]
 #[derive(Debug, Default)]
 pub struct TlsAcceptorConfig {
     pub(crate) handshake_timeout: Option<std::time::Duration>,
 }
 
-#[cfg(any(
-    feature = "openssl",
-    feature = "rustls-0_20",
-    feature = "rustls-0_21",
-    feature = "rustls-0_22",
-    feature = "rustls-0_23",
-))]
+#[cfg(feature = "__tls")]
 impl TlsAcceptorConfig {
     /// Set TLS handshake timeout duration.
     pub fn handshake_timeout(self, dur: std::time::Duration) -> Self {
diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md
index 54c7045ae87..bf63a689eb6 100644
--- a/actix-web/CHANGES.md
+++ b/actix-web/CHANGES.md
@@ -11,6 +11,7 @@
 
 - `ConnectionInfo::realip_remote_addr()` now handles IPv6 addresses from `Forwarded` header correctly. Previously, it sometimes returned the forwarded port as well.
 - The `UrlencodedError::ContentType` variant (relevant to the `Form` extractor) now uses the 415 (Media Type Unsupported) status code in it's `ResponseError` implementation.
+- `HttpServer::method.max_connection_rate` now takes effect on any TLS implementation. Previously, the configuration was missing for rustls versions 0.22 and 0.23.
 
 ## 4.7.0
 
diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml
index 3827d440046..bc441fd7efb 100644
--- a/actix-web/Cargo.toml
+++ b/actix-web/Cargo.toml
@@ -93,18 +93,18 @@ secure-cookies = ["cookies", "cookie/secure"]
 http2 = ["actix-http/http2"]
 
 # TLS via OpenSSL
-openssl = ["http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"]
+openssl = ["__tls", "http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"]
 
 # TLS via Rustls v0.20
 rustls = ["rustls-0_20"]
 # TLS via Rustls v0.20
-rustls-0_20 = ["http2", "actix-http/rustls-0_20", "actix-tls/accept", "actix-tls/rustls-0_20"]
+rustls-0_20 = ["__tls", "http2", "actix-http/rustls-0_20", "actix-tls/accept", "actix-tls/rustls-0_20"]
 # TLS via Rustls v0.21
-rustls-0_21 = ["http2", "actix-http/rustls-0_21", "actix-tls/accept", "actix-tls/rustls-0_21"]
+rustls-0_21 = ["__tls", "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"]
+rustls-0_22 = ["__tls", "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"]
+rustls-0_23 = ["__tls", "http2", "actix-http/rustls-0_23", "actix-tls/accept", "actix-tls/rustls-0_23"]
 
 # Full unicode support
 unicode = ["dep:regex", "actix-router/unicode"]
@@ -113,6 +113,10 @@ unicode = ["dep:regex", "actix-router/unicode"]
 # Don't rely on these whatsoever. They may disappear at anytime.
 __compress = []
 
+# Internal (PRIVATE!) features used to aid checking feature status.
+# Don't rely on these whatsoever. They may disappear at anytime.
+__tls = []
+
 # io-uring feature only available for Linux OSes.
 experimental-io-uring = ["actix-server/io-uring"]
 
diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs
index 33b1e18942d..95e15581ff8 100644
--- a/actix-web/src/server.rs
+++ b/actix-web/src/server.rs
@@ -7,13 +7,7 @@ use std::{
     time::Duration,
 };
 
-#[cfg(any(
-    feature = "openssl",
-    feature = "rustls-0_20",
-    feature = "rustls-0_21",
-    feature = "rustls-0_22",
-    feature = "rustls-0_23",
-))]
+#[cfg(feature = "__tls")]
 use actix_http::TlsAcceptorConfig;
 use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
 use actix_server::{Server, ServerBuilder};
@@ -190,7 +184,7 @@ where
     /// By default max connections is set to a 256.
     #[allow(unused_variables)]
     pub fn max_connection_rate(self, num: usize) -> Self {
-        #[cfg(any(feature = "rustls-0_20", feature = "rustls-0_21", feature = "openssl"))]
+        #[cfg(feature = "__tls")]
         actix_tls::accept::max_concurrent_tls_connect(num);
         self
     }
@@ -243,13 +237,7 @@ 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",
-        feature = "rustls-0_22",
-        feature = "rustls-0_23",
-    ))]
+    #[cfg(feature = "__tls")]
     pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
         self.config
             .lock()


Test patch: