feat(client): redesign the Connect trait

The original `Connect` trait had some limitations:

- There was no way to provide more details to the connector about how to
  connect, other than the `Uri`.
- There was no way for the connector to return any extra information
  about the connected transport.
- The `Error` was forced to be an `std::io::Error`.
- The transport and future had `'static` requirements.

As hyper gains HTTP/2 support, some of these things needed to be
changed. We want to allow the user to configure whether they hope to
us ALPN to start an HTTP/2 connection, and the connector needs to be
able to return back to hyper if it did so.

The new `Connect` trait is meant to solve this.

- The `connect` method now receives a `Destination` type, instead of a
  `Uri`. This allows us to include additional data about how to connect.
- The `Future` returned from `connect` now must be a tuple of the
  transport, and a `Connected` metadata value. The `Connected` includes
  possibly extra data about what happened when connecting.

BREAKING CHANGE: Custom connectors should now implement `Connect`
  directly, instead of `Service`.

  Calls to `connect` no longer take `Uri`s, but `Destination`. There
  are `scheme`, `host`, and `port` methods to query relevant
  information.

  The returned future must be a tuple of the transport and `Connected`.
  If no relevant extra information is needed, simply return
  `Connected::new()`.

Closes #1428
This commit is contained in:
Sean McArthur
2018-03-14 14:12:36 -07:00
parent fbc449e49c
commit 8c52c2dfd3
5 changed files with 277 additions and 110 deletions

View File

@@ -14,8 +14,8 @@ fn retryable_request() {
let mut connector = MockConnector::new();
let sock1 = connector.mock("http://mock.local/a");
let sock2 = connector.mock("http://mock.local/b");
let sock1 = connector.mock("http://mock.local");
let sock2 = connector.mock("http://mock.local");
let client = Client::configure()
.connector(connector)
@@ -62,7 +62,7 @@ fn conn_reset_after_write() {
let mut connector = MockConnector::new();
let sock1 = connector.mock("http://mock.local/a");
let sock1 = connector.mock("http://mock.local");
let client = Client::configure()
.connector(connector)