Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): deprecate client::conn::{Builder, handshake} #3156

Merged
merged 1 commit into from
Mar 7, 2023
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
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