Skip to content

Commit 9adf50b

Browse files
feat: upgrade to hyper-v1, use hyper-utils for now (#104)
* feat: upgrade to hyper-v1, use hyper-utils for now * chore: bump hyper-utils * chore: fix example inside lib
1 parent 5e4cb93 commit 9adf50b

File tree

5 files changed

+84
-37
lines changed

5 files changed

+84
-37
lines changed

Cargo.toml

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,17 @@ vendored = ["native-tls/vendored"]
1616
[dependencies]
1717
bytes = "1"
1818
native-tls = "0.2.1"
19-
hyper = { version = "0.14.2", default-features = false, features = ["tcp", "client"] }
19+
hyper = { version = "1.0.0-rc.4", default-features = false }
20+
hyper-util = { git = "https://github.com/hyperium/hyper-util", default-features = false, features = [
21+
"client",
22+
], rev = "11776bd742196691d03203caa0f4acd29df696bd" }
2023
tokio = "1"
2124
tokio-native-tls = "0.3"
25+
tower-service = "0.3"
26+
http-body-util = "0.1.0-rc.3"
2227

2328
[dev-dependencies]
2429
tokio = { version = "1.0.0", features = ["io-std", "macros", "io-util"] }
25-
hyper = { version = "0.14.2", default-features = false, features = ["http1"] }
30+
hyper-util = { git = "https://github.com/hyperium/hyper-util", default-features = false, features = [
31+
"http1",
32+
], rev = "11776bd742196691d03203caa0f4acd29df696bd" }

examples/client.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1-
use hyper::{body::HttpBody as _, Client};
1+
use bytes::Bytes;
2+
use http_body_util::BodyExt;
3+
4+
use http_body_util::Empty;
25
use hyper_tls::HttpsConnector;
6+
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
37
use tokio::io::{self, AsyncWriteExt as _};
48

59
#[tokio::main(flavor = "current_thread")]
610
async fn main() -> Result<(), Box<dyn std::error::Error>> {
711
let https = HttpsConnector::new();
8-
let client = Client::builder().build::<_, hyper::Body>(https);
12+
13+
let client = Client::builder(TokioExecutor::new()).build::<_, Empty<Bytes>>(https);
914

1015
let mut res = client.get("https://hyper.rs".parse()?).await?;
1116

1217
println!("Status: {}", res.status());
1318
println!("Headers:\n{:#?}", res.headers());
1419

15-
while let Some(chunk) = res.body_mut().data().await {
16-
let chunk = chunk?;
17-
io::stdout().write_all(&chunk).await?
20+
while let Some(frame) = res.body_mut().frame().await {
21+
let frame = frame?;
22+
23+
if let Some(d) = frame.data_ref() {
24+
io::stdout().write_all(d).await?;
25+
}
1826
}
27+
1928
Ok(())
2029
}

src/client.rs

+35-18
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
use hyper::{
2+
rt::{Read, Write},
3+
Uri,
4+
};
5+
use hyper_util::{client::connect::HttpConnector, rt::TokioIo};
16
use std::fmt;
27
use std::future::Future;
38
use std::pin::Pin;
49
use std::task::{Context, Poll};
5-
6-
use hyper::{client::connect::HttpConnector, service::Service, Uri};
7-
use tokio::io::{AsyncRead, AsyncWrite};
810
use tokio_native_tls::TlsConnector;
11+
use tower_service::Service;
912

1013
use crate::stream::MaybeHttpsStream;
1114

@@ -20,17 +23,17 @@ pub struct HttpsConnector<T> {
2023
}
2124

2225
impl HttpsConnector<HttpConnector> {
23-
/// Construct a new HttpsConnector.
26+
/// Construct a new `HttpsConnector`.
2427
///
2528
/// This uses hyper's default `HttpConnector`, and default `TlsConnector`.
2629
/// If you wish to use something besides the defaults, use `From::from`.
2730
///
2831
/// # Note
2932
///
3033
/// By default this connector will use plain HTTP if the URL provided uses
31-
/// the HTTP scheme (eg: http://example.com/).
34+
/// the HTTP scheme (eg: <http://example.com/>).
3235
///
33-
/// If you would like to force the use of HTTPS then call https_only(true)
36+
/// If you would like to force the use of HTTPS then call `https_only(true)`
3437
/// on the returned connector.
3538
///
3639
/// # Panics
@@ -39,10 +42,12 @@ impl HttpsConnector<HttpConnector> {
3942
///
4043
/// To handle that error yourself, you can use the `HttpsConnector::from`
4144
/// constructor after trying to make a `TlsConnector`.
45+
#[must_use]
4246
pub fn new() -> Self {
43-
native_tls::TlsConnector::new()
44-
.map(|tls| HttpsConnector::new_(tls.into()))
45-
.unwrap_or_else(|e| panic!("HttpsConnector::new() failure: {}", e))
47+
native_tls::TlsConnector::new().map_or_else(
48+
|e| panic!("HttpsConnector::new() failure: {}", e),
49+
|tls| HttpsConnector::new_(tls.into()),
50+
)
4651
}
4752

4853
fn new_(tls: TlsConnector) -> Self {
@@ -68,15 +73,22 @@ impl<T> HttpsConnector<T> {
6873

6974
/// With connector constructor
7075
///
76+
/// # Panics
77+
///
78+
/// This will panic if the underlying TLS context could not be created.
79+
///
80+
/// To handle that error yourself, you can use the `HttpsConnector::from`
81+
/// constructor after trying to make a `TlsConnector`.
7182
pub fn new_with_connector(http: T) -> Self {
72-
native_tls::TlsConnector::new()
73-
.map(|tls| HttpsConnector::from((http, tls.into())))
74-
.unwrap_or_else(|e| {
83+
native_tls::TlsConnector::new().map_or_else(
84+
|e| {
7585
panic!(
7686
"HttpsConnector::new_with_connector(<connector>) failure: {}",
7787
e
7888
)
79-
})
89+
},
90+
|tls| HttpsConnector::from((http, tls.into())),
91+
)
8092
}
8193
}
8294

@@ -95,14 +107,14 @@ impl<T: fmt::Debug> fmt::Debug for HttpsConnector<T> {
95107
f.debug_struct("HttpsConnector")
96108
.field("force_https", &self.force_https)
97109
.field("http", &self.http)
98-
.finish()
110+
.finish_non_exhaustive()
99111
}
100112
}
101113

102114
impl<T> Service<Uri> for HttpsConnector<T>
103115
where
104116
T: Service<Uri>,
105-
T::Response: AsyncRead + AsyncWrite + Send + Unpin,
117+
T::Response: Read + Write + Send + Unpin,
106118
T::Future: Send + 'static,
107119
T::Error: Into<BoxError>,
108120
{
@@ -131,11 +143,16 @@ where
131143
.trim_matches(|c| c == '[' || c == ']')
132144
.to_owned();
133145
let connecting = self.http.call(dst);
134-
let tls = self.tls.clone();
146+
147+
let tls_connector = self.tls.clone();
148+
135149
let fut = async move {
136150
let tcp = connecting.await.map_err(Into::into)?;
151+
137152
let maybe = if is_https {
138-
let tls = tls.connect(&host, tcp).await?;
153+
let stream = TokioIo::new(tcp);
154+
155+
let tls = TokioIo::new(tls_connector.connect(&host, stream).await?);
139156
MaybeHttpsStream::Https(tls)
140157
} else {
141158
MaybeHttpsStream::Http(tcp)
@@ -155,7 +172,7 @@ type BoxedFut<T> = Pin<Box<dyn Future<Output = Result<MaybeHttpsStream<T>, BoxEr
155172
/// A Future representing work to connect to a URL, and a TLS handshake.
156173
pub struct HttpsConnecting<T>(BoxedFut<T>);
157174

158-
impl<T: AsyncRead + AsyncWrite + Unpin> Future for HttpsConnecting<T> {
175+
impl<T: Read + Write + Unpin> Future for HttpsConnecting<T> {
159176
type Output = Result<MaybeHttpsStream<T>, BoxError>;
160177

161178
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
//! ## Example
88
//!
99
//! ```no_run
10+
//! use bytes::Bytes;
11+
//! use http_body_util::Empty;
1012
//! use hyper_tls::HttpsConnector;
11-
//! use hyper::Client;
13+
//! use hyper_util::{client::legacy::Client, rt::TokioExecutor};
1214
//!
1315
//! #[tokio::main(flavor = "current_thread")]
1416
//! async fn main() -> Result<(), Box<dyn std::error::Error>>{
1517
//! let https = HttpsConnector::new();
16-
//! let client = Client::builder().build::<_, hyper::Body>(https);
18+
//! let client = Client::builder(TokioExecutor::new()).build::<_, Empty<Bytes>>(https);
1719
//!
1820
//! let res = client.get("https://hyper.rs".parse()?).await?;
1921
//! assert_eq!(res.status(), 200);

src/stream.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ use std::io::IoSlice;
44
use std::pin::Pin;
55
use std::task::{Context, Poll};
66

7-
use hyper::client::connect::{Connected, Connection};
8-
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
7+
use hyper::rt::{Read, ReadBufCursor, Write};
8+
9+
use hyper_util::{
10+
client::connect::{Connected, Connection},
11+
rt::TokioIo,
12+
};
913
pub use tokio_native_tls::TlsStream;
1014

1115
/// A stream that might be protected with TLS.
1216
pub enum MaybeHttpsStream<T> {
1317
/// A stream over plain text.
1418
Http(T),
1519
/// A stream protected with TLS.
16-
Https(TlsStream<T>),
20+
Https(TokioIo<TlsStream<TokioIo<T>>>),
1721
}
1822

1923
// ===== impl MaybeHttpsStream =====
@@ -33,18 +37,24 @@ impl<T> From<T> for MaybeHttpsStream<T> {
3337
}
3438
}
3539

36-
impl<T> From<TlsStream<T>> for MaybeHttpsStream<T> {
37-
fn from(inner: TlsStream<T>) -> Self {
40+
impl<T> From<TlsStream<TokioIo<T>>> for MaybeHttpsStream<T> {
41+
fn from(inner: TlsStream<TokioIo<T>>) -> Self {
42+
MaybeHttpsStream::Https(TokioIo::new(inner))
43+
}
44+
}
45+
46+
impl<T> From<TokioIo<TlsStream<TokioIo<T>>>> for MaybeHttpsStream<T> {
47+
fn from(inner: TokioIo<TlsStream<TokioIo<T>>>) -> Self {
3848
MaybeHttpsStream::Https(inner)
3949
}
4050
}
4151

42-
impl<T: AsyncRead + AsyncWrite + Unpin> AsyncRead for MaybeHttpsStream<T> {
52+
impl<T: Read + Write + Unpin> Read for MaybeHttpsStream<T> {
4353
#[inline]
4454
fn poll_read(
4555
self: Pin<&mut Self>,
4656
cx: &mut Context,
47-
buf: &mut ReadBuf,
57+
buf: ReadBufCursor<'_>,
4858
) -> Poll<Result<(), io::Error>> {
4959
match Pin::get_mut(self) {
5060
MaybeHttpsStream::Http(s) => Pin::new(s).poll_read(cx, buf),
@@ -53,7 +63,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> AsyncRead for MaybeHttpsStream<T> {
5363
}
5464
}
5565

56-
impl<T: AsyncWrite + AsyncRead + Unpin> AsyncWrite for MaybeHttpsStream<T> {
66+
impl<T: Write + Read + Unpin> Write for MaybeHttpsStream<T> {
5767
#[inline]
5868
fn poll_write(
5969
self: Pin<&mut Self>,
@@ -101,11 +111,13 @@ impl<T: AsyncWrite + AsyncRead + Unpin> AsyncWrite for MaybeHttpsStream<T> {
101111
}
102112
}
103113

104-
impl<T: AsyncRead + AsyncWrite + Connection + Unpin> Connection for MaybeHttpsStream<T> {
114+
impl<T: Connection + Unpin> Connection for MaybeHttpsStream<T> {
105115
fn connected(&self) -> Connected {
106116
match self {
107117
MaybeHttpsStream::Http(s) => s.connected(),
108-
MaybeHttpsStream::Https(s) => s.get_ref().get_ref().get_ref().connected(),
118+
MaybeHttpsStream::Https(s) => {
119+
s.inner().get_ref().get_ref().get_ref().inner().connected()
120+
}
109121
}
110122
}
111123
}

0 commit comments

Comments
 (0)