- Placed all cases of "unexpected bytes" errors into the
`UnexpectedMessage` variant.
- Placed all cases of "unexpected EOF" errors into the
`IncompleteMessage` variant. Description is now generic about
"connection closed before message completed", instead of mentioning
"request" or "response.
- Added `Error::is_incomplete_message()` accessor to help checking for
unexpected closures.
- Renamed some variants to be clearer when viewing the `Debug` format.
- Collected all "user" errors into an internal `User` enum, to prevent
forgetting to update the `is_user()` method.
If the Response was received and the body finished while the Request
body was still streaming, the connection could get into a state where it
was never polled again, thus never re-inserting into the connection pool
or being dropped.
Closes#1717
- 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 introduces a `Resolve` trait to describe asynchronous DNS
resolution. The `HttpConnector` can be configured with a resolver,
allowing a user to still use all the functionality of the
`HttpConnector`, while customizing the DNS resolution.
To prevent a breaking change, the `HttpConnector` has its `Resolve`
generic set by default to `GaiResolver`. This is same as the existing
resolver, which uses `getaddrinfo` inside a thread pool.
Closes#1517
- Adds `client::connect::Connected::extra()`, which allows connectors to
specify arbitrary custom information about a connected transport.
If a connector provides this extra value, it will be set in the
`Response` extensions.
Closes#1402
While the upgrades feature enabled HTTP upgrades in both and the server and client, and the goal was for `CONNECT` requests to work as well, only the server could use them for `CONNECT`. The `Client` had some specific code rejecting `CONNECT` requests, and this removes it and prepares the `Client` to handle them correctly.
- Adds `Body::on_upgrade()` that returns an `OnUpgrade` future.
- Adds `hyper::upgrade` module containing types for dealing with
upgrades.
- Adds `server::conn::Connection::with_upgrades()` method to enable
these upgrades when using lower-level API (because of a missing
`Send` bound on the transport generic).
- Client connections are automatically enabled.
- Optimizes request parsing, to make up for extra work to look for
upgrade requests.
- Returns a smaller `DecodedLength` type instead of the fatter
`Decoder`, which should also allow a couple fewer branches.
- Removes the `Decode::Ignore` wrapper enum, and instead ignoring
1xx responses is handled directly in the response parsing code.
Ref #1563Closes#1395
When getting a `Body` from hyper, such as in a client response,
the method `Body::content_length()` now returns a value if the header
was present.
Closes#1545
This allows a client or server to indicate that the body should be cut off
in an abnormal fashion so the server doesn't simply get a "valid" but
truncated body.
- `Client::new()` no longer needs a `Handle`, and instead makes use of
tokio's implicit default.
- Changed `Client::configure()` to `Client::builder()`.
- `Builder` is a by-ref builder, since all configuration is now
cloneable pieces.
BREAKING CHANGE: `Client:new(&handle)` and `Client::configure()` are now
`Client::new()` and `Client::builder()`.
**The `Error` is now an opaque struct**, which allows for more variants to
be added freely, and the internal representation to change without being
breaking changes.
For inspecting an `Error`, there are several `is_*` methods to check for
certain classes of errors, such as `Error::is_parse()`. The `cause` can
also be inspected, like before. This likely seems like a downgrade, but
more inspection can be added as needed!
The `Error` now knows about more states, which gives much more context
around when a certain error occurs. This is also expressed in the
description and `fmt` messages.
**Most places where a user would provide an error to hyper can now pass
any error type** (`E: Into<Box<std::error::Error>>`). This error is passed
back in relevant places, and can be useful for logging. This should make
it much clearer about what error a user should provide to hyper: any it
feels is relevant!
Closes#1128Closes#1130Closes#1431Closes#1338
BREAKING CHANGE: `Error` is no longer an enum to pattern match over, or
to construct. Code will need to be updated accordingly.
For body streams or `Service`s, inference might be unable to determine
what error type you mean to return. Starting in Rust 1.26, you could
just label that as `!` if you never return an error.
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 dedicated `Entity` trait replaces the previous `Stream<Item=impl
AsRef<[u8]>, Error=hyper::Error>`. This allows for several improvements
immediately, and prepares for HTTP2 support.
- The `Entity::is_end_stream` makes up for change away from
`Option<Body>`, which was previously used to know if the body should be
empty. Since `Request` and `Response` now require a body to be set,
this method can be used to tell hyper that the body is actually empty.
It also provides the possibility of slight optimizations when polling
for data, by allowing to check `is_end_stream` before polling again.
This can allow a consumer to know that a body stream has ended without
polling for `None` afterwards.
- The `Entity::content_length` method allows a body to automatically
declare a size, in case a user doesn't set a `Content-Length` or
`Transfer-Encoding` header.
- It's now possible to send and receive trailers, though this will be
for HTTP2 connections only.
By being a trait owned by hyper, new methods can be added later as new
features are wanted (with default implementations).
The `hyper::Body` type now implements `Entity` instead of `Stream`,
provides a better channel option, and is easier to use with custom
streams via `Body::wrap_stream`.
BREAKING CHANGE: All code that was assuming the body was a `Stream` must
be adjusted to use an `Entity` instead.
Using `hyper::Body` as a `Stream` can call `Body::into_stream`
to get a stream wrapper.
Passing a custom `impl Stream` will need to either implement
`Entity`, or as an easier option, switch to `Body::wrap_stream`.
`Body::pair` has been replaced with `Body::channel`, which returns a
`hyper::body::Sender` instead of a `futures::sync::mpsc::Sender`.
Closes#1438
BREAKING CHANGE: `Method`, `Request`, `Response`, `StatusCode`,
`Version`, and `Uri` have been replaced with types from the `http`
crate. The `hyper::header` module is gone for now.
Removed `Client::get`, since it needed to construct a `Request<B>`
with an empty body. Just use `Client::request` instead.
Removed `compat` cargo feature, and `compat` related API.
The higher-level `Client` has never supported `CONNECT` requests,
but it used to send them, and then handle the responses incorrectly.
Now, it will return an error immediately instead of misbehaving.
The HttpConnector's connect future was lazy, but if any custom connector
did not use a lazy future, then a connect would always be started, even
if an idle connection was available.
If a request sees an error on a pooled connection before ever writing
any bytes, it will now retry with a new connection.
This can be configured with `Config::retry_canceled_requests(bool)`.
Currently, if the remote closes the connection at the same time that the
pool selects it to use for a new request, the connection may actually
hang. This fix will now more allow the keep-alive read to check the
socket even when the `Conn` think it's busy.
If the connection was closed before the request write happened, returns
back an `Error::Cancel`, letting the user know they could safely retry
it.
Closes#1439
This allows using a future `Executor` other than a `Handle` to execute
the background (connection) tasks needed for sending requests and
responses.
This also deprecates `Client::handle()`, since the executor may not be
a `Handle`.
Additionally fixes if there were idle connections when a `Client` is
dropped.
Only fixes with the no-proto dispatcher, as changing internals for the
tokio-proto dispatcher would be much harder, and it will replace it very
soon.
Closes#1397