Make HTTP/2 optional via 'http2' feature.

Closes #2030.
This commit is contained in:
Edgar Onghena 2022-02-23 20:11:28 +01:00 committed by Sergio Benitez
parent cc98f98aa7
commit ff7cf68461
6 changed files with 35 additions and 16 deletions

View File

@ -18,6 +18,7 @@ edition = "2018"
default = [] default = []
tls = ["rustls", "tokio-rustls", "rustls-pemfile"] tls = ["rustls", "tokio-rustls", "rustls-pemfile"]
mtls = ["tls", "x509-parser"] mtls = ["tls", "x509-parser"]
http2 = ["hyper/http2"]
private-cookies = ["cookie/private", "cookie/key-expansion"] private-cookies = ["cookie/private", "cookie/key-expansion"]
serde = ["uncased/with-serde-alloc", "serde_"] serde = ["uncased/with-serde-alloc", "serde_"]
uuid = ["uuid_"] uuid = ["uuid_"]
@ -50,7 +51,7 @@ optional = true
[dependencies.hyper] [dependencies.hyper]
version = "0.14.9" version = "0.14.9"
default-features = false default-features = false
features = ["http1", "http2", "runtime", "server", "stream"] features = ["http1", "runtime", "server", "stream"]
[dependencies.serde_] [dependencies.serde_]
package = "serde" package = "serde"

View File

@ -64,7 +64,12 @@ impl TlsListener {
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS config: {}", e)))?; .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS config: {}", e)))?;
tls_config.ignore_client_order = c.prefer_server_order; tls_config.ignore_client_order = c.prefer_server_order;
tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
tls_config.alpn_protocols = vec![b"http/1.1".to_vec()];
if cfg!(feature = "http2") {
tls_config.alpn_protocols.insert(0, b"h2".to_vec());
}
tls_config.session_storage = ServerSessionMemoryCache::new(1024); tls_config.session_storage = ServerSessionMemoryCache::new(1024);
tls_config.ticketer = rustls::Ticketer::new() tls_config.ticketer = rustls::Ticketer::new()
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS ticketer: {}", e)))?; .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("bad TLS ticketer: {}", e)))?;

View File

@ -19,9 +19,10 @@ edition = "2018"
all-features = true all-features = true
[features] [features]
default = [] default = ["http2"]
tls = ["rocket_http/tls"] tls = ["rocket_http/tls"]
mtls = ["rocket_http/mtls", "tls"] mtls = ["rocket_http/mtls", "tls"]
http2 = ["rocket_http/http2"]
secrets = ["rocket_http/private-cookies"] secrets = ["rocket_http/private-cookies"]
json = ["serde_json", "tokio/io-util"] json = ["serde_json", "tokio/io-util"]
msgpack = ["rmp-serde", "tokio/io-util"] msgpack = ["rmp-serde", "tokio/io-util"]

View File

@ -56,25 +56,33 @@
//! //!
//! ## Features //! ## Features
//! //!
//! To avoid compiling unused dependencies, Rocket gates certain features, all //! To avoid compiling unused dependencies, Rocket gates certain features. With
//! of which are disabled by default: //! the exception of `http2`, all are disabled by default:
//! //!
//! | Feature | Description | //! | Feature | Description |
//! |-----------|---------------------------------------------------------| //! |-----------|---------------------------------------------------------|
//! | `secrets` | Support for authenticated, encrypted [private cookies]. | //! | `secrets` | Support for authenticated, encrypted [private cookies]. |
//! | `tls` | Support for [TLS] encrypted connections. | //! | `tls` | Support for [TLS] encrypted connections. |
//! | `mtls` | Support for verified clients via [mutual TLS]. | //! | `mtls` | Support for verified clients via [mutual TLS]. |
//! | `http2` | Support for HTTP/2 (enabled by default). |
//! | `json` | Support for [JSON (de)serialization]. | //! | `json` | Support for [JSON (de)serialization]. |
//! | `msgpack` | Support for [MessagePack (de)serialization]. | //! | `msgpack` | Support for [MessagePack (de)serialization]. |
//! | `uuid` | Support for [UUID value parsing and (de)serialization]. | //! | `uuid` | Support for [UUID value parsing and (de)serialization]. |
//! //!
//! Features can be selectively enabled in `Cargo.toml`: //! Disabled features can be selectively enabled in `Cargo.toml`:
//! //!
//! ```toml //! ```toml
//! [dependencies] //! [dependencies]
//! rocket = { version = "0.5.0-rc.1", features = ["secrets", "tls", "json"] } //! rocket = { version = "0.5.0-rc.1", features = ["secrets", "tls", "json"] }
//! ``` //! ```
//! //!
//! Conversely, HTTP/2 can be disabled:
//!
//! ```toml
//! [dependencies]
//! rocket = { version = "0.5.0-rc.1", default-features = false }
//! ```
//!
//! [JSON (de)serialization]: crate::serde::json //! [JSON (de)serialization]: crate::serde::json
//! [MessagePack (de)serialization]: crate::serde::msgpack //! [MessagePack (de)serialization]: crate::serde::msgpack
//! [UUID value parsing and (de)serialization]: crate::serde::uuid //! [UUID value parsing and (de)serialization]: crate::serde::uuid

View File

@ -405,13 +405,6 @@ impl Rocket<Orbit> {
}); });
} }
// Determine keep-alives.
let http1_keepalive = self.config.keep_alive != 0;
let http2_keep_alive = match self.config.keep_alive {
0 => None,
n => Some(Duration::from_secs(n as u64))
};
// Set up cancellable I/O from the given listener. Shutdown occurs when // Set up cancellable I/O from the given listener. Shutdown occurs when
// `Shutdown` (`TripWire`) resolves. This can occur directly through a // `Shutdown` (`TripWire`) resolves. This can occur directly through a
// notification or indirectly through an external signal which, when // notification or indirectly through an external signal which, when
@ -438,6 +431,9 @@ impl Rocket<Orbit> {
}); });
} }
// Save the keep-alive value for later use; we're about to move `self`.
let keep_alive = self.config.keep_alive;
// Create the Hyper `Service`. // Create the Hyper `Service`.
let rocket = Arc::new(self); let rocket = Arc::new(self);
let service_fn = move |conn: &CancellableIo<_, L::Connection>| { let service_fn = move |conn: &CancellableIo<_, L::Connection>| {
@ -456,10 +452,17 @@ impl Rocket<Orbit> {
// NOTE: `hyper` uses `tokio::spawn()` as the default executor. // NOTE: `hyper` uses `tokio::spawn()` as the default executor.
let listener = CancellableListener::new(shutdown.clone(), listener, grace, mercy); let listener = CancellableListener::new(shutdown.clone(), listener, grace, mercy);
let server = hyper::Server::builder(Incoming::new(listener)) let builder = hyper::Server::builder(Incoming::new(listener));
.http1_keepalive(http1_keepalive)
#[cfg(feature = "http2")]
let builder = builder.http2_keep_alive_interval(match keep_alive {
0 => None,
n => Some(Duration::from_secs(n as u64))
});
let server = builder
.http1_keepalive(keep_alive != 0)
.http1_preserve_header_case(true) .http1_preserve_header_case(true)
.http2_keep_alive_interval(http2_keep_alive)
.serve(hyper::service::make_service_fn(service_fn)) .serve(hyper::service::make_service_fn(service_fn))
.with_graceful_shutdown(shutdown.clone()) .with_graceful_shutdown(shutdown.clone())
.map_err(|e| Error::new(ErrorKind::Runtime(Box::new(e)))); .map_err(|e| Error::new(ErrorKind::Runtime(Box::new(e))));

View File

@ -118,6 +118,7 @@ function test_core() {
secrets secrets
tls tls
mtls mtls
http2
json json
msgpack msgpack
uuid uuid