diff --git a/src/client/legacy.rs b/src/client/legacy.rs index 21ccdd9b..0cb60ea1 100644 --- a/src/client/legacy.rs +++ b/src/client/legacy.rs @@ -452,6 +452,7 @@ where } } + #[cfg(any(feature = "http1", feature = "http2"))] fn connect_to( &self, pool_key: PoolKey, @@ -512,37 +513,46 @@ where Either::Left(Box::pin(async move { let tx = if is_h2 { - let (mut tx, conn) = - h2_builder.handshake(io).await.map_err(Error::tx)?; - - trace!( - "http2 handshake complete, spawning background dispatcher task" - ); - executor.execute( - conn.map_err(|e| debug!("client connection error: {}", e)) - .map(|_| ()), - ); - - // Wait for 'conn' to ready up before we - // declare this tx as usable - tx.ready().await.map_err(Error::tx)?; - PoolTx::Http2(tx) + #[cfg(feature = "http2")] { + let (mut tx, conn) = + h2_builder.handshake(io).await.map_err(Error::tx)?; + + trace!( + "http2 handshake complete, spawning background dispatcher task" + ); + executor.execute( + conn.map_err(|e| debug!("client connection error: {}", e)) + .map(|_| ()), + ); + + // Wait for 'conn' to ready up before we + // declare this tx as usable + tx.ready().await.map_err(Error::tx)?; + PoolTx::Http2(tx) + } + #[cfg(not(feature = "http2"))] + panic!("http2 feature is not enabled"); } else { - let (mut tx, conn) = - h1_builder.handshake(io).await.map_err(Error::tx)?; - - trace!( - "http1 handshake complete, spawning background dispatcher task" - ); - executor.execute( - conn.map_err(|e| debug!("client connection error: {}", e)) - .map(|_| ()), - ); - - // Wait for 'conn' to ready up before we - // declare this tx as usable - tx.ready().await.map_err(Error::tx)?; - PoolTx::Http1(tx) + #[cfg(feature = "http1")] { + let (mut tx, conn) = + h1_builder.handshake(io).await.map_err(Error::tx)?; + + trace!( + "http1 handshake complete, spawning background dispatcher task" + ); + executor.execute( + conn.map_err(|e| debug!("client connection error: {}", e)) + .map(|_| ()), + ); + + // Wait for 'conn' to ready up before we + // declare this tx as usable + tx.ready().await.map_err(Error::tx)?; + PoolTx::Http1(tx) + } + #[cfg(not(feature = "http1"))] { + panic!("http1 feature is not enabled"); + } }; Ok(pool.pooled( @@ -604,7 +614,9 @@ impl Clone for Client { Client { config: self.config.clone(), exec: self.exec.clone(), + #[cfg(feature = "http1")] h1_builder: self.h1_builder.clone(), + #[cfg(feature = "http2")] h2_builder: self.h2_builder.clone(), connector: self.connector.clone(), pool: self.pool.clone(), @@ -660,14 +672,19 @@ struct PoolClient { } enum PoolTx { + #[cfg(feature = "http1")] Http1(hyper::client::conn::http1::SendRequest), #[cfg(feature = "http2")] Http2(hyper::client::conn::http2::SendRequest), } impl PoolClient { - fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll> { + fn poll_ready( + &mut self, + #[allow(unused_variables)] cx: &mut task::Context<'_>, + ) -> Poll> { match self.tx { + #[cfg(feature = "http1")] PoolTx::Http1(ref mut tx) => tx.poll_ready(cx).map_err(|_| todo!()), #[cfg(feature = "http2")] PoolTx::Http2(_) => Poll::Ready(Ok(())), @@ -680,6 +697,7 @@ impl PoolClient { fn is_http2(&self) -> bool { match self.tx { + #[cfg(feature = "http1")] PoolTx::Http1(_) => false, #[cfg(feature = "http2")] PoolTx::Http2(_) => true, @@ -688,6 +706,7 @@ impl PoolClient { fn is_ready(&self) -> bool { match self.tx { + #[cfg(feature = "http1")] PoolTx::Http1(ref tx) => tx.is_ready(), #[cfg(feature = "http2")] PoolTx::Http2(ref tx) => tx.is_ready(), @@ -696,6 +715,7 @@ impl PoolClient { fn is_closed(&self) -> bool { match self.tx { + #[cfg(feature = "http1")] PoolTx::Http1(ref tx) => tx.is_closed(), #[cfg(feature = "http2")] PoolTx::Http2(ref tx) => tx.is_closed(), @@ -711,15 +731,30 @@ impl PoolClient { where B: Send, { - match self.tx { - #[cfg(not(feature = "http2"))] - PoolTx::Http1(ref mut tx) => tx.send_request(req), - #[cfg(feature = "http2")] + #[cfg(all(feature = "http1", feature = "http2"))] + return match self.tx { + #[cfg(feature = "http1")] PoolTx::Http1(ref mut tx) => Either::Left(tx.send_request(req)), #[cfg(feature = "http2")] PoolTx::Http2(ref mut tx) => Either::Right(tx.send_request(req)), } - .map_err(|_| todo!()) + .map_err(|_| todo!()); + + #[cfg(feature = "http1")] + #[cfg(not(feature = "http2"))] + return match self.tx { + #[cfg(feature = "http1")] + PoolTx::Http1(ref mut tx) => tx.send_request(req), + } + .map_err(|_| todo!()); + + #[cfg(not(feature = "http1"))] + #[cfg(feature = "http2")] + return match self.tx { + #[cfg(feature = "http2")] + PoolTx::Http2(ref mut tx) => tx.send_request(req), + } + .map_err(|_| todo!()); } /* //TODO: can we re-introduce this somehow? Or must people use tower::retry? @@ -733,7 +768,7 @@ impl PoolClient { match self.tx { #[cfg(not(feature = "http2"))] PoolTx::Http1(ref mut tx) => tx.send_request_retryable(req), - #[cfg(feature = "http2")] + #[cfg(feature = "http1")] PoolTx::Http1(ref mut tx) => Either::Left(tx.send_request_retryable(req)), #[cfg(feature = "http2")] PoolTx::Http2(ref mut tx) => Either::Right(tx.send_request_retryable(req)), @@ -752,6 +787,7 @@ where fn reserve(self) -> pool::Reservation { match self.tx { + #[cfg(feature = "http1")] PoolTx::Http1(tx) => pool::Reservation::Unique(PoolClient { conn_info: self.conn_info, tx: PoolTx::Http1(tx), @@ -913,7 +949,9 @@ fn is_schema_secure(uri: &Uri) -> bool { pub struct Builder { client_config: Config, exec: Exec, + #[cfg(feature = "http1")] h1_builder: hyper::client::conn::http1::Builder, + #[cfg(feature = "http2")] h2_builder: hyper::client::conn::http2::Builder, pool_config: pool::Config, } @@ -932,7 +970,9 @@ impl Builder { ver: Ver::Auto, }, exec, + #[cfg(feature = "http1")] h1_builder: hyper::client::conn::http1::Builder::new(), + #[cfg(feature = "http2")] h2_builder: hyper::client::conn::http2::Builder::new(executor), pool_config: pool::Config { idle_timeout: Some(Duration::from_secs(90)), @@ -975,6 +1015,8 @@ impl Builder { /// Note that setting this option unsets the `http1_max_buf_size` option. /// /// Default is an adaptive read buffer. + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_read_buf_exact_size(&mut self, sz: usize) -> &mut Self { self.h1_builder.read_buf_exact_size(Some(sz)); self @@ -1018,6 +1060,8 @@ impl Builder { /// Default is false. /// /// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4 + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_allow_spaces_after_header_name_in_responses(&mut self, val: bool) -> &mut Self { self.h1_builder .allow_spaces_after_header_name_in_responses(val); @@ -1055,6 +1099,8 @@ impl Builder { /// Default is false. /// /// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4 + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_allow_obsolete_multiline_headers_in_responses(&mut self, val: bool) -> &mut Self { self.h1_builder .allow_obsolete_multiline_headers_in_responses(val); @@ -1085,6 +1131,8 @@ impl Builder { /// line in the input to resume parsing the rest of the headers. An error /// will be emitted nonetheless if it finds `\0` or a lone `\r` while /// looking for the next line. + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_ignore_invalid_headers_in_responses(&mut self, val: bool) -> &mut Builder { self.h1_builder.ignore_invalid_headers_in_responses(val); self @@ -1102,6 +1150,8 @@ impl Builder { /// /// Default is `auto`. In this mode hyper will try to guess which /// mode to use + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_writev(&mut self, enabled: bool) -> &mut Builder { self.h1_builder.writev(enabled); self @@ -1113,6 +1163,8 @@ impl Builder { /// Note that this setting does not affect HTTP/2. /// /// Default is false. + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_title_case_headers(&mut self, val: bool) -> &mut Self { self.h1_builder.title_case_headers(val); self @@ -1131,6 +1183,8 @@ impl Builder { /// Note that this setting does not affect HTTP/2. /// /// Default is false. + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http1_preserve_header_case(&mut self, val: bool) -> &mut Self { self.h1_builder.preserve_header_case(val); self @@ -1139,6 +1193,8 @@ impl Builder { /// Set whether HTTP/0.9 responses should be tolerated. /// /// Default is false. + #[cfg(feature = "http1")] + #[cfg_attr(docsrs, doc(cfg(feature = "http1")))] pub fn http09_responses(&mut self, val: bool) -> &mut Self { self.h1_builder.http09_responses(val); self @@ -1356,7 +1412,9 @@ impl Builder { Client { config: self.client_config, exec: self.exec.clone(), + #[cfg(feature = "http1")] h1_builder: self.h1_builder.clone(), + #[cfg(feature = "http2")] h2_builder: self.h2_builder.clone(), connector, pool: pool::Pool::new(self.pool_config, &self.exec), diff --git a/src/client/mod.rs b/src/client/mod.rs index 906ed54d..37d33fc1 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -2,7 +2,7 @@ //mod client; pub mod connect; -#[cfg(all(feature = "http1", feature = "http2"))] +#[cfg(any(feature = "http1", feature = "http2"))] pub mod legacy; #[doc(hidden)] pub mod pool;