Skip to content

Commit 304e642

Browse files
committed
refactor(client): re-enable http2 client
1 parent 4920f5e commit 304e642

File tree

5 files changed

+204
-238
lines changed

5 files changed

+204
-238
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ futures-util-preview = { version = "0.3.0-alpha.17" }
2929
http = "0.1.15"
3030
http-body = "0.1"
3131
httparse = "1.0"
32-
h2 = "0.1.10"
32+
h2 = { git = "https://github.com/hyperium/h2" }
3333
iovec = "0.1"
3434
itoa = "0.4.1"
3535
log = "0.4"

src/client/conn.rs

+17-49
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,19 @@ type Http1Dispatcher<T, B, R> = proto::dispatch::Dispatcher<
3232
>;
3333
type ConnEither<T, B> = Either<
3434
Http1Dispatcher<T, B, proto::h1::ClientTransaction>,
35-
proto::h2::Client<T, B>,
35+
proto::h2::ClientTask<B>,
3636
>;
3737

38-
/// Returns a `Handshake` future over some IO.
38+
/// Returns a handshake future over some IO.
3939
///
4040
/// This is a shortcut for `Builder::new().handshake(io)`.
41-
pub fn handshake<T>(io: T) -> Handshake<T, crate::Body>
41+
pub async fn handshake<T>(io: T) -> crate::Result<(SendRequest<crate::Body>, Connection<T, crate::Body>)>
4242
where
4343
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
4444
{
4545
Builder::new()
4646
.handshake(io)
47+
.await
4748
}
4849

4950
/// The sender side of an established connection.
@@ -68,7 +69,7 @@ where
6869

6970
/// A builder to configure an HTTP connection.
7071
///
71-
/// After setting options, the builder is used to create a `Handshake` future.
72+
/// After setting options, the builder is used to create a handshake future.
7273
#[derive(Clone, Debug)]
7374
pub struct Builder {
7475
pub(super) exec: Exec,
@@ -80,16 +81,6 @@ pub struct Builder {
8081
h2_builder: h2::client::Builder,
8182
}
8283

83-
/// A future setting up HTTP over an IO object.
84-
///
85-
/// If successful, yields a `(SendRequest, Connection)` pair.
86-
#[must_use = "futures do nothing unless polled"]
87-
pub struct Handshake<T, B> {
88-
builder: Builder,
89-
io: Option<T>,
90-
_marker: PhantomData<fn(B)>,
91-
}
92-
9384
/// A future returned by `SendRequest::send_request`.
9485
///
9586
/// Yields a `Response` if successful.
@@ -400,6 +391,7 @@ impl<T, B> Future for Connection<T, B>
400391
where
401392
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
402393
B: Payload + Unpin + 'static,
394+
B::Data: Unpin,
403395
{
404396
type Output = crate::Result<()>;
405397

@@ -522,70 +514,46 @@ impl Builder {
522514
}
523515

524516
/// Constructs a connection with the configured options and IO.
525-
#[inline]
526-
pub fn handshake<T, B>(&self, io: T) -> Handshake<T, B>
517+
pub async fn handshake<T, B>(self, io: T) -> crate::Result<(SendRequest<B>, Connection<T, B>)>
527518
where
528519
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
529520
B: Payload + 'static,
521+
B::Data: Unpin,
530522
{
531523
trace!("client handshake HTTP/{}", if self.http2 { 2 } else { 1 });
532-
Handshake {
533-
builder: self.clone(),
534-
io: Some(io),
535-
_marker: PhantomData,
536-
}
537-
}
538-
}
539-
540-
// ===== impl Handshake
541-
542-
impl<T, B> Future for Handshake<T, B>
543-
where
544-
T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
545-
B: Payload + 'static,
546-
{
547-
type Output = crate::Result<(SendRequest<B>, Connection<T, B>)>;
548524

549-
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
550-
let io = self.io.take().expect("polled more than once");
551525
let (tx, rx) = dispatch::channel();
552-
let either = if !self.builder.http2 {
526+
let either = if !self.http2 {
553527
let mut conn = proto::Conn::new(io);
554-
if !self.builder.h1_writev {
528+
if !self.h1_writev {
555529
conn.set_write_strategy_flatten();
556530
}
557-
if self.builder.h1_title_case_headers {
531+
if self.h1_title_case_headers {
558532
conn.set_title_case_headers();
559533
}
560-
if let Some(sz) = self.builder.h1_read_buf_exact_size {
534+
if let Some(sz) = self.h1_read_buf_exact_size {
561535
conn.set_read_buf_exact_size(sz);
562536
}
563-
if let Some(max) = self.builder.h1_max_buf_size {
537+
if let Some(max) = self.h1_max_buf_size {
564538
conn.set_max_buf_size(max);
565539
}
566540
let cd = proto::h1::dispatch::Client::new(rx);
567541
let dispatch = proto::h1::Dispatcher::new(cd, conn);
568542
Either::Left(dispatch)
569543
} else {
570-
let h2 = proto::h2::Client::new(io, rx, &self.builder.h2_builder, self.builder.exec.clone());
544+
let h2 = proto::h2::client::handshake(io, rx, &self.h2_builder, self.exec.clone())
545+
.await?;
571546
Either::Right(h2)
572547
};
573548

574-
Poll::Ready(Ok((
549+
Ok((
575550
SendRequest {
576551
dispatch: tx,
577552
},
578553
Connection {
579554
inner: Some(either),
580555
},
581-
)))
582-
}
583-
}
584-
585-
impl<T, B> fmt::Debug for Handshake<T, B> {
586-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
587-
f.debug_struct("Handshake")
588-
.finish()
556+
))
589557
}
590558
}
591559

src/client/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ where C: Connect + Sync + 'static,
163163
C::Transport: 'static,
164164
C::Future: 'static,
165165
B: Payload + Unpin + Send + 'static,
166-
B::Data: Send,
166+
B::Data: Send + Unpin,
167167
{
168168
/// Send a `GET` request to the supplied `Uri`.
169169
///
@@ -512,8 +512,10 @@ where C: Connect + Sync + 'static,
512512
connecting
513513
};
514514
let is_h2 = is_ver_h2 || connected.alpn == Alpn::H2;
515-
Either::Left(conn_builder
515+
Either::Left(Box::pin(conn_builder
516516
.http2_only(is_h2)
517+
// TODO: convert client::conn::Builder to be by-value?
518+
.clone()
517519
.handshake(io)
518520
.and_then(move |(tx, conn)| {
519521
trace!("handshake complete, spawning background dispatcher task");
@@ -541,7 +543,7 @@ where C: Connect + Sync + 'static,
541543
PoolTx::Http1(tx)
542544
},
543545
})
544-
}))
546+
})))
545547
}))
546548
})
547549
}

0 commit comments

Comments
 (0)