Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 95 additions & 37 deletions src/client/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ where
}
}

#[cfg(any(feature = "http1", feature = "http2"))]
fn connect_to(
&self,
pool_key: PoolKey,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -604,7 +614,9 @@ impl<C: Clone, B> Clone for Client<C, B> {
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(),
Expand Down Expand Up @@ -660,14 +672,19 @@ struct PoolClient<B> {
}

enum PoolTx<B> {
#[cfg(feature = "http1")]
Http1(hyper::client::conn::http1::SendRequest<B>),
#[cfg(feature = "http2")]
Http2(hyper::client::conn::http2::SendRequest<B>),
}

impl<B> PoolClient<B> {
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Error>> {
fn poll_ready(
&mut self,
#[allow(unused_variables)] cx: &mut task::Context<'_>,
) -> Poll<Result<(), Error>> {
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(())),
Expand All @@ -680,6 +697,7 @@ impl<B> PoolClient<B> {

fn is_http2(&self) -> bool {
match self.tx {
#[cfg(feature = "http1")]
PoolTx::Http1(_) => false,
#[cfg(feature = "http2")]
PoolTx::Http2(_) => true,
Expand All @@ -688,6 +706,7 @@ impl<B> PoolClient<B> {

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(),
Expand All @@ -696,6 +715,7 @@ impl<B> PoolClient<B> {

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(),
Expand All @@ -711,15 +731,30 @@ impl<B: Body + 'static> PoolClient<B> {
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?
Expand All @@ -733,7 +768,7 @@ impl<B: Body + 'static> PoolClient<B> {
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)),
Expand All @@ -752,6 +787,7 @@ where

fn reserve(self) -> pool::Reservation<Self> {
match self.tx {
#[cfg(feature = "http1")]
PoolTx::Http1(tx) => pool::Reservation::Unique(PoolClient {
conn_info: self.conn_info,
tx: PoolTx::Http1(tx),
Expand Down Expand Up @@ -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,
}
Expand All @@ -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)),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;