feat(client): add ALPN h2 support for client connectors

- Adds `Connected::negotiated_h2()` method to signal the connection must
  use HTTP2. `Connect` implementations should set this if using ALPN.

If a connection to a host is detected to have been upgraded via ALPN,
any other oustanding connect futures will be canceled, and the waiting
requests will make use of the single HTTP2 connection.

The `http2_only` builder configuration still works the same, not
requiring ALPN at all, and always using only a single connection.
This commit is contained in:
Sean McArthur
2018-10-26 18:55:03 -07:00
parent bf188b28fe
commit 976a77a673
7 changed files with 200 additions and 95 deletions

View File

@@ -36,7 +36,6 @@ pub trait Connect: Send + Sync {
/// A set of properties to describe where and how to try to connect.
#[derive(Clone, Debug)]
pub struct Destination {
//pub(super) alpn: Alpn,
pub(super) uri: Uri,
}
@@ -46,21 +45,18 @@ pub struct Destination {
/// was used, or if connected to an HTTP proxy.
#[derive(Debug)]
pub struct Connected {
//alpn: Alpn,
pub(super) alpn: Alpn,
pub(super) is_proxied: bool,
pub(super) extra: Option<Extra>,
}
pub(super) struct Extra(Box<ExtraInner>);
/*TODO: when HTTP1 Upgrades to H2 are added, this will be needed
#[derive(Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) enum Alpn {
Http1,
//H2,
//Http1OrH2
H2,
None,
}
*/
impl Destination {
/// Get the protocol scheme.
@@ -246,7 +242,7 @@ impl Connected {
/// Create new `Connected` type with empty metadata.
pub fn new() -> Connected {
Connected {
//alpn: Alpn::Http1,
alpn: Alpn::None,
is_proxied: false,
extra: None,
}
@@ -274,19 +270,18 @@ impl Connected {
self
}
/*
/// Set that the connected transport negotiated HTTP/2 as it's
/// next protocol.
pub fn h2(mut self) -> Connected {
pub fn negotiated_h2(mut self) -> Connected {
self.alpn = Alpn::H2;
self
}
*/
// Don't public expose that `Connected` is `Clone`, unsure if we want to
// keep that contract...
pub(super) fn clone(&self) -> Connected {
Connected {
alpn: self.alpn.clone(),
is_proxied: self.is_proxied,
extra: self.extra.clone(),
}