diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d587a4a7..ad50806e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -366,5 +366,7 @@ jobs: name: Run `rpk,underscore-wildcards` tests - run: cargo test --features pq-experimental,rpk,underscore-wildcards name: Run `pq-experimental,rpk,underscore-wildcards` tests - - run: cargo test -p hyper-boring --features hyper1 + - run: cargo test -p hyper-boring --features hyper1-runtime name: Run hyper 1.0 tests for hyper-boring + - run: cargo test -p hyper-boring --features hyper0-runtime + name: Run hyper 0. tests for hyper-boring diff --git a/Cargo.toml b/Cargo.toml index d31e703b..b30114bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,16 +37,16 @@ futures = "0.3" tokio = "1" anyhow = "1" antidote = "1.0.0" -http = "1" +http1 = { package = "http", version = "1" } http-body-util = "0.1.2" -http_old = { package = "http", version = "0.2" } -hyper = "1" +http0 = { package = "http", version = "0.2" } +hyper1 = { package = "hyper", version = "1" } hyper-util = "0.1.6" -hyper_old = { package = "hyper", version = "0.14", default-features = false } +hyper0 = { package = "hyper", version = "0.14", default-features = false } linked_hash_set = "0.1" once_cell = "1.0" openssl-macros = "0.1.1" -tower = "0.4" +tower = { version = "0.4", default-features = false, features = ["util"] } tower-layer = "0.3" tower-service = "0.3" autocfg = "1.3.0" diff --git a/hyper-boring/Cargo.toml b/hyper-boring/Cargo.toml index 1e30d035..f8560ff0 100644 --- a/hyper-boring/Cargo.toml +++ b/hyper-boring/Cargo.toml @@ -15,9 +15,13 @@ features = ["pq-experimental"] rustdoc-args = ["--cfg", "docsrs"] [features] -default = ["runtime"] +default = ["runtime", "hyper1-runtime"] -runtime = ["hyper_old/runtime"] +runtime = [] +# `hyper1` + `runtime`. +hyper1-runtime = ["hyper1", "dep:tower"] +# `hyper0` + `runtime`. +hyper0-runtime = ["hyper0", "hyper0/runtime"] # Use a FIPS-validated version of boringssl. fips = ["tokio-boring/fips"] @@ -28,21 +32,24 @@ fips-link-precompiled = ["tokio-boring/fips-link-precompiled"] # Enables experimental post-quantum crypto (https://blog.cloudflare.com/post-quantum-for-all/) pq-experimental = ["tokio-boring/pq-experimental"] -# Enable Hyper 1 support -hyper1 = ["dep:http", "dep:hyper", "dep:hyper-util", "dep:tower-service"] +# Enable Hyper 1 support. +hyper1 = ["dep:hyper1", "dep:http1", "dep:hyper-util", "dep:tower-service"] +# Enable Hyper 0 support. +hyper0 = ["dep:hyper0", "dep:http0"] [dependencies] antidote = { workspace = true } -http = { workspace = true, optional = true } -http_old = { workspace = true } -hyper = { workspace = true, optional = true } +http1 = { workspace = true, optional = true } +http0 = { workspace = true, optional = true } +hyper1 = { workspace = true, optional = true } hyper-util = { workspace = true, optional = true, features = ["client", "client-legacy"] } -hyper_old = { workspace = true, features = ["client"] } +hyper0 = { workspace = true, optional = true, features = ["client"] } linked_hash_set = { workspace = true } once_cell = { workspace = true } boring = { workspace = true } tokio = { workspace = true } tokio-boring = { workspace = true } +tower = { workspace = true, optional = true } tower-layer = { workspace = true } tower-service = { workspace = true, optional = true } @@ -50,8 +57,8 @@ tower-service = { workspace = true, optional = true } bytes = { workspace = true } http-body-util = { workspace = true } hyper-util = { workspace = true, features = ["http1", "http2", "service", "tokio"] } -hyper = { workspace = true, features = ["server"] } -hyper_old = { workspace = true, features = [ "full" ] } +hyper1 = { workspace = true, features = ["server"] } +hyper0 = { workspace = true, features = [ "full" ] } tokio = { workspace = true, features = [ "full" ] } tower = { workspace = true, features = ["util"] } futures = { workspace = true } diff --git a/hyper-boring/src/lib.rs b/hyper-boring/src/lib.rs index 736a3d89..f51dfaac 100644 --- a/hyper-boring/src/lib.rs +++ b/hyper-boring/src/lib.rs @@ -11,12 +11,14 @@ use std::fmt; use tokio_boring::SslStream; mod cache; -mod v0; -/// Hyper 1 support. +/// Hyper 0 support. +#[cfg(feature = "hyper0")] +pub mod v0; #[cfg(feature = "hyper1")] -pub mod v1; +mod v1; -pub use self::v0::*; +#[cfg(feature = "hyper1")] +pub use self::v1::*; fn key_index() -> Result, ErrorStack> { static IDX: OnceCell> = OnceCell::new(); diff --git a/hyper-boring/src/v0.rs b/hyper-boring/src/v0.rs index 172d1640..dcb9f9ac 100644 --- a/hyper-boring/src/v0.rs +++ b/hyper-boring/src/v0.rs @@ -6,11 +6,11 @@ use boring::ssl::{ ConnectConfiguration, Ssl, SslConnector, SslConnectorBuilder, SslMethod, SslRef, SslSessionCacheMode, }; -use http_old::uri::Scheme; -use hyper_old::client::connect::{Connected, Connection}; -use hyper_old::client::HttpConnector; -use hyper_old::service::Service; -use hyper_old::Uri; +use http0::uri::Scheme; +use hyper0::client::connect::{Connected, Connection}; +use hyper0::client::HttpConnector; +use hyper0::service::Service; +use hyper0::Uri; use std::error::Error; use std::future::Future; use std::net; diff --git a/hyper-boring/src/v1.rs b/hyper-boring/src/v1.rs index e1f9a43d..45654c51 100644 --- a/hyper-boring/src/v1.rs +++ b/hyper-boring/src/v1.rs @@ -6,9 +6,9 @@ use boring::ssl::{ ConnectConfiguration, Ssl, SslConnector, SslConnectorBuilder, SslMethod, SslRef, SslSessionCacheMode, }; -use http::uri::Scheme; -use http::Uri; -use hyper::rt::{Read, ReadBufCursor, Write}; +use http1::uri::Scheme; +use http1::Uri; +use hyper1::rt::{Read, ReadBufCursor, Write}; use hyper_util::client::legacy::connect::{Connected, Connection, HttpConnector}; use hyper_util::rt::TokioIo; use std::error::Error; @@ -19,6 +19,11 @@ use std::sync::Arc; use std::task::{Context, Poll}; use std::{io, net}; use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::net::TcpStream; +#[cfg(all(feature = "runtime", feature = "hyper1-runtime"))] +use tower::util::MapResponse; +#[cfg(all(feature = "runtime", feature = "hyper1-runtime"))] +use tower::ServiceExt; use tower_layer::Layer; use tower_service::Service; @@ -29,25 +34,30 @@ pub struct HttpsConnector { inner: Inner, } -#[cfg(feature = "runtime")] -impl HttpsConnector { +/// Specialized version of [`HttpConnector`] with responses wrapped with +/// [`TokioIo::new`] in order to bring back compatibility with Tokio traits. +pub type TokioHttpConnector = + MapResponse) -> TokioIo>>; + +#[cfg(all(feature = "runtime", feature = "hyper1-runtime"))] +impl HttpsConnector { /// Creates a a new `HttpsConnector` using default settings. /// /// The Hyper `HttpConnector` is used to perform the TCP socket connection. ALPN is configured to support both /// HTTP/2 and HTTP/1.1. /// /// Requires the `runtime` Cargo feature. - pub fn new() -> Result, ErrorStack> { + pub fn new() -> Result { let mut http = HttpConnector::new(); http.enforce_http(false); - HttpsLayer::new().map(|l| l.layer(http)) + HttpsLayer::new().map(|l| l.layer(http.map_response(TokioIo::new as _))) } } impl HttpsConnector where - S: Service> + Send, + S: Service + Send, S::Error: Into>, S::Future: Unpin + Send + 'static, T: AsyncRead + AsyncWrite + Connection + Unpin + fmt::Debug + Sync + Send + 'static, @@ -55,6 +65,10 @@ where /// Creates a new `HttpsConnector`. /// /// The session cache configuration of `ssl` will be overwritten. + /// + /// If the provided service's response type does not fit the trait + /// requirements because it is closer to the Hyper ecosystem than the Tokio + /// one, wrapping your responses with [`TokioIo`] should work. pub fn with_connector( http: S, ssl: SslConnectorBuilder, @@ -215,7 +229,7 @@ impl Inner { impl Service for HttpsConnector where - S: Service> + Send, + S: Service + Send, S::Error: Into>, S::Future: Unpin + Send + 'static, T: AsyncRead + AsyncWrite + Connection + Unpin + fmt::Debug + Sync + Send + 'static, @@ -244,7 +258,7 @@ where let connect = self.http.call(uri); let f = async { - let conn = connect.await.map_err(Into::into)?.into_inner(); + let conn = connect.await.map_err(Into::into)?; let (inner, uri) = match tls_setup { Some((inner, uri)) => (inner, uri), diff --git a/hyper-boring/tests/v0.rs b/hyper-boring/tests/v0.rs index 08cfce12..0a681e55 100644 --- a/hyper-boring/tests/v0.rs +++ b/hyper-boring/tests/v0.rs @@ -1,10 +1,12 @@ +#![cfg(feature = "hyper0")] + use boring::ssl::{SslAcceptor, SslConnector, SslFiletype, SslMethod}; use futures::StreamExt; -use hyper_boring::HttpsConnector; -use hyper_old::client::HttpConnector; -use hyper_old::server::conn::Http; -use hyper_old::{service, Response}; -use hyper_old::{Body, Client}; +use hyper0::client::HttpConnector; +use hyper0::server::conn::Http; +use hyper0::{service, Response}; +use hyper0::{Body, Client}; +use hyper_boring::v0::HttpsConnector; use std::convert::Infallible; use std::{io, iter}; use tokio::net::TcpListener; diff --git a/hyper-boring/tests/v1.rs b/hyper-boring/tests/v1.rs index 441caea6..3e8273dd 100644 --- a/hyper-boring/tests/v1.rs +++ b/hyper-boring/tests/v1.rs @@ -4,14 +4,15 @@ use boring::ssl::{SslAcceptor, SslConnector, SslFiletype, SslMethod}; use bytes::Bytes; use futures::StreamExt; use http_body_util::{BodyStream, Empty}; -use hyper::{service, Response}; -use hyper_boring::v1::HttpsConnector; +use hyper1::{service, Response}; +use hyper_boring::HttpsConnector; use hyper_util::client::legacy::connect::HttpConnector; use hyper_util::client::legacy::Client; use hyper_util::rt::{TokioExecutor, TokioIo}; use std::convert::Infallible; use std::{io, iter}; use tokio::net::TcpListener; +use tower::ServiceExt; #[tokio::test] async fn google() { @@ -55,7 +56,7 @@ async fn localhost() { Ok::<_, io::Error>(Response::new(>::new())) }); - hyper::server::conn::http1::Builder::new() + hyper1::server::conn::http1::Builder::new() .keep_alive(false) .serve_connection(TokioIo::new(stream), service) .await @@ -83,7 +84,7 @@ async fn localhost() { let _ = writeln!(&file, "{}", line); }); - let ssl = HttpsConnector::with_connector(connector, ssl).unwrap(); + let ssl = HttpsConnector::with_connector(connector.map_response(TokioIo::new), ssl).unwrap(); let client = Client::builder(TokioExecutor::new()).build::<_, Empty>(ssl); for _ in 0..3 { @@ -126,7 +127,7 @@ async fn alpn_h2() { Ok::<_, io::Error>(Response::new(>::new())) }); - hyper::server::conn::http2::Builder::new(TokioExecutor::new()) + hyper1::server::conn::http2::Builder::new(TokioExecutor::new()) .serve_connection(TokioIo::new(stream), service) .await .unwrap(); @@ -144,7 +145,8 @@ async fn alpn_h2() { ssl.set_ca_file("tests/test/root-ca.pem").unwrap(); - let mut ssl = HttpsConnector::with_connector(connector, ssl).unwrap(); + let mut ssl = + HttpsConnector::with_connector(connector.map_response(TokioIo::new), ssl).unwrap(); ssl.set_ssl_callback(|ssl, _| ssl.set_alpn_protos(b"\x02h2\x08http/1.1"));