This removes the `tcp` feature from hyper's `Cargo.toml`, and the code it enabled:
- `HttpConnector`
- `GaiResolver`
- `AddrStream`
And parts of `Client` and `Server` that used those types. Alternatives will be available in the `hyper-util` crate.
Closes#2856
Co-authored-by: MrGunflame <mrgunflame@protonmail.com>
Use Box<str> in hyper::client::connect::dns::Name, so
its size is 16 bytes, not 24 bytes. As Name never
change its contents, read-only Box<str> is perfectly OK.
The DNS resolver part of `HttpConnector` used to require resolving to
`IpAddr`s, and this changes it so that they resolve to `SocketAddr`s.
The main benefit here is allowing for resolvers to set the IPv6 zone ID
when resolving, but it also just more closely matches
`std::net::ToSocketAddrs`.
Closes#1937
BREAKING CHANGE: Custom resolvers used with `HttpConnector` must change
to resolving to an iterator of `SocketAddr`s instead of `IpAddr`s.
Currently HttpConnector::set_local_address method accepts a single
argument. Server might not support IPv6 or IPv4. Therefore, the only
solution at the moment is to manually perform DNS resolution and pick
appropriate local address family. This is inefficient, as leads to
2 DNS lookups per request. This commit allows specifying both IPv4
and IPv6, so connector can decide which one to use based on DNS
resolution results.
If the runtime is dropped while a DNS request is being made, it can
lead to a panic. This patch checks if the task was cancelled, and
returns a generic IO error instead of panicking in that case.
The following code reproduces the problem on my macOS machine:
```
use hyper::Client;
use tokio::runtime;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
fn main() {
let rt = runtime::Builder::new()
.threaded_scheduler()
.core_threads(1)
.enable_all()
.build()
.unwrap();
// spawn a request and then drop the runtime immediately
rt.spawn(fetch_url());
}
async fn fetch_url() -> Result<()> {
let url: hyper::Uri = "http://example.com".parse()?;
let client = Client::builder().build_http::<hyper::Body>();
let res = client.get(url).await?;
println!("Response: {}", res.status());
Ok(())
}
```
It is not possible to connect to an IPv4 address from an IPv6 address or
vice-versa so don't waste time trying. If no remote addresses match then a
"missing connect error" will now occur.
Closes#1903
BREAKING CHANGE: The `Resolve` trait is gone. All custom resolves should
implement `tower::Service` instead.
The error type of `HttpConnector` has been changed away from
`std::io::Error`.
This takes the same strategy as golang, where the timeout value is
divided equally between the candidate socket addresses.
If happy eyeballs is enabled, the division takes place "below" the
IPv4/IPv6 partitioning.
The `HttpConnector` and `AddrListener` types which make use of
`tokio::tcp` have been made their own optional feature. This allows
using them without requiring the *full* tokio runtime.
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