Skip to content

Commit

Permalink
feat(client): deprecate client::conn types (#3156)
Browse files Browse the repository at this point in the history
`client::conn::{SendRequest, Connection, Builder, handshake}` are deprecated as they are removed in 1.0.

This adds the `deprecated` feature to Cargo, and only when `hyper/deprecated` is enabled will these warnings be emitted.

Co-authored-by: KOVACS Tamas <ktamas@fastmail.fm>
  • Loading branch information
seanmonstar and kxt committed Mar 7, 2023
1 parent 253cc74 commit 0ced15d
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 8 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ ffi = ["libc"]
# enable 1.0 backports
backports = []

# whether or not to display deprecation warnings
deprecated = []

# internal features used in CI
nightly = []
__internal_happy_eyeballs_tests = []
Expand Down
48 changes: 40 additions & 8 deletions examples/tower_client.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#![deny(warnings)]

use hyper::client::conn::Builder;
use hyper::client::connect::HttpConnector;
use hyper::client::service::Connect;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

use hyper::service::Service;
use hyper::{Body, Request};
use hyper::{Body, Request, Response};
use tokio::net::TcpStream;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
pretty_env_logger::init();

let mut mk_svc = Connect::new(HttpConnector::new(), Builder::new());

let uri = "http://127.0.0.1:8080".parse::<http::Uri>()?;

let mut svc = mk_svc.call(uri.clone()).await?;
let mut svc = Connector;

let body = Body::empty();

Expand All @@ -25,3 +25,35 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

Ok(())
}

struct Connector;

impl Service<Request<Body>> for Connector {
type Response = Response<Body>;
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;

fn poll_ready(&mut self, _cx: &mut Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, req: Request<Body>) -> Self::Future {
Box::pin(async move {
let host = req.uri().host().expect("no host in uri");
let port = req.uri().port_u16().expect("no port in uri");

let stream = TcpStream::connect(format!("{}:{}", host, port)).await?;

let (mut sender, conn) = hyper::client::conn::http1::handshake(stream).await?;

tokio::task::spawn(async move {
if let Err(err) = conn.await {
println!("Connection error: {:?}", err);
}
});

let res = sender.send_request(req).await?;
Ok(res)
})
}
}
9 changes: 9 additions & 0 deletions src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use super::HttpConnector;
#[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))]
pub struct Client<C, B = Body> {
config: Config,
#[cfg_attr(feature = "deprecated", allow(deprecated))]
conn_builder: conn::Builder,
connector: C,
pool: Pool<PoolClient<B>>,
Expand Down Expand Up @@ -327,12 +328,14 @@ where
drop(delayed_tx);
});

#[cfg_attr(feature = "deprecated", allow(deprecated))]
self.conn_builder.exec.execute(on_idle);
} else {
// There's no body to delay, but the connection isn't
// ready yet. Only re-insert when it's ready
let on_idle = future::poll_fn(move |cx| pooled.poll_ready(cx)).map(|_| ());

#[cfg_attr(feature = "deprecated", allow(deprecated))]
self.conn_builder.exec.execute(on_idle);
}

Expand Down Expand Up @@ -386,6 +389,7 @@ where
});
// An execute error here isn't important, we're just trying
// to prevent a waste of a socket...
#[cfg_attr(feature = "deprecated", allow(deprecated))]
self.conn_builder.exec.execute(bg);
}
Ok(checked_out)
Expand Down Expand Up @@ -430,6 +434,7 @@ where
&self,
pool_key: PoolKey,
) -> impl Lazy<Output = crate::Result<Pooled<PoolClient<B>>>> + Unpin {
#[cfg_attr(feature = "deprecated", allow(deprecated))]
let executor = self.conn_builder.exec.clone();
let pool = self.pool.clone();
#[cfg(not(feature = "http2"))]
Expand Down Expand Up @@ -629,6 +634,7 @@ struct PoolClient<B> {
}

enum PoolTx<B> {
#[cfg_attr(feature = "deprecated", allow(deprecated))]
Http1(conn::SendRequest<B>),
#[cfg(feature = "http2")]
Http2(conn::Http2SendRequest<B>),
Expand Down Expand Up @@ -905,6 +911,7 @@ fn is_schema_secure(uri: &Uri) -> bool {
#[derive(Clone)]
pub struct Builder {
client_config: Config,
#[cfg_attr(feature = "deprecated", allow(deprecated))]
conn_builder: conn::Builder,
pool_config: pool::Config,
}
Expand All @@ -917,6 +924,7 @@ impl Default for Builder {
set_host: true,
ver: Ver::Auto,
},
#[cfg_attr(feature = "deprecated", allow(deprecated))]
conn_builder: conn::Builder::new(),
pool_config: pool::Config {
idle_timeout: Some(Duration::from_secs(90)),
Expand Down Expand Up @@ -1381,6 +1389,7 @@ impl Builder {
B: HttpBody + Send,
B::Data: Send,
{
#[cfg_attr(feature = "deprecated", allow(deprecated))]
Client {
config: self.client_config,
conn_builder: self.conn_builder.clone(),
Expand Down
38 changes: 38 additions & 0 deletions src/client/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,30 @@ pin_project! {
///
/// This is a shortcut for `Builder::new().handshake(io)`.
/// See [`client::conn`](crate::client::conn) for more.
#[cfg_attr(
feature = "deprecated",
deprecated(
note = "This function will be replaced with `client::conn::http1::handshake` and `client::conn::http2::handshake` in 1.0, enable the \"backports\" feature to use them now."
)
)]
#[cfg_attr(feature = "deprecated", allow(deprecated))]
pub async fn handshake<T>(
io: T,
) -> crate::Result<(SendRequest<crate::Body>, Connection<T, crate::Body>)>
where
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
{
#[allow(deprecated)]
Builder::new().handshake(io).await
}

/// The sender side of an established connection.
#[cfg_attr(
feature = "deprecated",
deprecated(
note = "This type will be replaced with `client::conn::http1::SendRequest` and `client::conn::http2::SendRequest` in 1.0, enable the \"backports\" feature to use them now."
)
)]
pub struct SendRequest<B> {
dispatch: dispatch::Sender<Request<B>, Response<Body>>,
}
Expand All @@ -142,6 +156,12 @@ pub struct SendRequest<B> {
/// In most cases, this should just be spawned into an executor, so that it
/// can process incoming and outgoing messages, notice hangups, and the like.
#[must_use = "futures do nothing unless polled"]
#[cfg_attr(
feature = "deprecated",
deprecated(
note = "This type will be replaced with `client::conn::http1::Connection` and `client::conn::http2::Connection` in 1.0, enable the \"backports\" feature to use them now."
)
)]
pub struct Connection<T, B>
where
T: AsyncRead + AsyncWrite + Send + 'static,
Expand All @@ -154,6 +174,12 @@ where
///
/// After setting options, the builder is used to create a handshake future.
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "deprecated",
deprecated(
note = "This type will be replaced with `client::conn::http1::Builder` and `client::conn::http2::Builder` in 1.0, enable the \"backports\" feature to use them now."
)
)]
pub struct Builder {
pub(super) exec: Exec,
h09_responses: bool,
Expand Down Expand Up @@ -226,6 +252,7 @@ pub(super) struct Http2SendRequest<B> {

// ===== impl SendRequest

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<B> SendRequest<B> {
/// Polls to determine whether this sender can be used yet for a request.
///
Expand Down Expand Up @@ -259,6 +286,7 @@ impl<B> SendRequest<B> {
}
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<B> SendRequest<B>
where
B: HttpBody + 'static,
Expand Down Expand Up @@ -344,6 +372,7 @@ where
}
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<B> Service<Request<B>> for SendRequest<B>
where
B: HttpBody + 'static,
Expand All @@ -361,6 +390,7 @@ where
}
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<B> fmt::Debug for SendRequest<B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SendRequest").finish()
Expand Down Expand Up @@ -430,6 +460,7 @@ impl<B> Clone for Http2SendRequest<B> {

// ===== impl Connection

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<T, B> Connection<T, B>
where
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
Expand Down Expand Up @@ -513,6 +544,7 @@ where
}
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<T, B> Future for Connection<T, B>
where
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
Expand Down Expand Up @@ -541,6 +573,7 @@ where
}
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl<T, B> fmt::Debug for Connection<T, B>
where
T: AsyncRead + AsyncWrite + fmt::Debug + Send + 'static,
Expand All @@ -553,6 +586,7 @@ where

// ===== impl Builder

#[cfg_attr(feature = "deprecated", allow(deprecated))]
impl Builder {
/// Creates a new connection builder.
#[inline]
Expand Down Expand Up @@ -1090,9 +1124,11 @@ where
trait AssertSend: Send {}
trait AssertSendSync: Send + Sync {}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
#[doc(hidden)]
impl<B: Send> AssertSendSync for SendRequest<B> {}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
#[doc(hidden)]
impl<T: Send, B: Send> AssertSend for Connection<T, B>
where
Expand All @@ -1102,6 +1138,7 @@ where
{
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
#[doc(hidden)]
impl<T: Send + Sync, B: Send + Sync> AssertSendSync for Connection<T, B>
where
Expand All @@ -1111,6 +1148,7 @@ where
{
}

#[cfg_attr(feature = "deprecated", allow(deprecated))]
#[doc(hidden)]
impl AssertSendSync for Builder {}

Expand Down
5 changes: 5 additions & 0 deletions src/client/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::marker::PhantomData;

use tracing::debug;

#[cfg_attr(feature = "deprecated", allow(deprecated))]
use super::conn::{Builder, SendRequest};
use crate::{
body::HttpBody,
Expand All @@ -23,13 +24,15 @@ use crate::{
#[derive(Debug)]
pub struct Connect<C, B, T> {
inner: C,
#[cfg_attr(feature = "deprecated", allow(deprecated))]
builder: Builder,
_pd: PhantomData<fn(T, B)>,
}

impl<C, B, T> Connect<C, B, T> {
/// Create a new `Connect` with some inner connector `C` and a connection
/// builder.
#[cfg_attr(feature = "deprecated", allow(deprecated))]
pub fn new(inner: C, builder: Builder) -> Self {
Self {
inner,
Expand All @@ -49,6 +52,7 @@ where
B::Data: Send + Unpin,
B::Error: Into<Box<dyn StdError + Send + Sync>>,
{
#[cfg_attr(feature = "deprecated", allow(deprecated))]
type Response = SendRequest<B>;
type Error = crate::Error;
type Future =
Expand All @@ -68,6 +72,7 @@ where
match io.await {
Ok(io) => match builder.handshake(io).await {
Ok((sr, conn)) => {
#[cfg_attr(feature = "deprecated", allow(deprecated))]
builder.exec.execute(async move {
if let Err(e) = conn.await {
debug!("connection error: {:?}", e);
Expand Down
1 change: 1 addition & 0 deletions src/ffi/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ unsafe impl AsTaskType for hyper_clientconn {
ffi_fn! {
/// Creates a new set of HTTP clientconn options to be used in a handshake.
fn hyper_clientconn_options_new() -> *mut hyper_clientconn_options {
#[allow(deprecated)]
let builder = conn::Builder::new();

Box::into_raw(Box::new(hyper_clientconn_options {
Expand Down
2 changes: 2 additions & 0 deletions tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2181,6 +2181,7 @@ mod dispatch_impl {
}
}

#[allow(deprecated)]
mod conn {
use std::io::{self, Read, Write};
use std::net::{SocketAddr, TcpListener};
Expand Down Expand Up @@ -2246,6 +2247,7 @@ mod conn {
future::join(server, client).await;
}

#[deny(deprecated)]
#[cfg(feature = "backports")]
mod backports {
use super::*;
Expand Down
1 change: 1 addition & 0 deletions tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2536,6 +2536,7 @@ async fn http2_keep_alive_with_responsive_client() {
});

let tcp = connect_async(addr).await;
#[allow(deprecated)]
let (mut client, conn) = hyper::client::conn::Builder::new()
.http2_only(true)
.handshake::<_, Body>(tcp)
Expand Down

0 comments on commit 0ced15d

Please sign in to comment.