#![deny(clippy::pedantic, missing_docs)]
#![allow(clippy::module_name_repetitions)]
#![cfg_attr(docsrs, feature(doc_cfg))]
use std::{
future::Future,
net::SocketAddr,
pin::Pin,
sync::Arc,
task::{self, Poll},
};
use hyper::{
client::{connect::dns::Name, HttpConnector},
service::Service,
};
use trust_dns_resolver::{
config::{ResolverConfig, ResolverOpts},
error::ResolveError,
lookup_ip::LookupIpIntoIter,
TokioAsyncResolver, TokioHandle,
};
#[cfg(feature = "native-tls")]
pub use crate::native_tls::{new_native_tls_https_connector, NativeTlsHttpsConnector};
#[cfg(feature = "__rustls")]
pub use crate::rustls::*;
#[cfg(feature = "native-tls")]
mod native_tls;
#[cfg(feature = "__rustls")]
mod rustls;
#[derive(Clone)]
pub struct TrustDnsResolver {
resolver: Arc<TokioAsyncResolver>,
}
pub struct SocketAddrs {
iter: LookupIpIntoIter,
}
impl Iterator for SocketAddrs {
type Item = SocketAddr;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|ip_addr| SocketAddr::new(ip_addr, 0))
}
}
impl TrustDnsResolver {
#[allow(clippy::missing_panics_doc)]
#[must_use]
pub fn new() -> Self {
let resolver = Arc::new(
TokioAsyncResolver::new(
ResolverConfig::default(),
ResolverOpts::default(),
TokioHandle,
)
.unwrap(),
);
Self { resolver }
}
}
impl Default for TrustDnsResolver {
fn default() -> Self {
Self::new()
}
}
impl Service<Name> for TrustDnsResolver {
type Response = SocketAddrs;
type Error = ResolveError;
#[allow(clippy::type_complexity)]
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, name: Name) -> Self::Future {
let resolver = self.resolver.clone();
Box::pin(async move {
let response = resolver.lookup_ip(name.as_str()).await?;
let addresses = response.into_iter();
Ok(SocketAddrs { iter: addresses })
})
}
}
pub type TrustDnsHttpConnector = HttpConnector<TrustDnsResolver>;
#[must_use]
pub fn new_trust_dns_http_connector() -> TrustDnsHttpConnector {
TrustDnsHttpConnector::new_with_resolver(TrustDnsResolver::new())
}