mirror of https://github.com/fafhrd91/actix-net
remove tokio dep from actix-tls. use static future for default dnslookup
This commit is contained in:
parent
8e30a1d643
commit
de2f8e0c62
|
@ -29,7 +29,7 @@ default = ["accept", "connect", "uri"]
|
||||||
accept = []
|
accept = []
|
||||||
|
|
||||||
# enable connector services
|
# enable connector services
|
||||||
connect = ["tokio/net"]
|
connect = []
|
||||||
|
|
||||||
# use openssl impls
|
# use openssl impls
|
||||||
openssl = ["tls-openssl", "tokio-openssl"]
|
openssl = ["tls-openssl", "tokio-openssl"]
|
||||||
|
@ -53,7 +53,6 @@ derive_more = "0.99.5"
|
||||||
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
|
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
|
||||||
http = { version = "0.2.3", optional = true }
|
http = { version = "0.2.3", optional = true }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
tokio = { version = "1", optional = true }
|
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
tls-openssl = { package = "openssl", version = "0.10", optional = true }
|
tls-openssl = { package = "openssl", version = "0.10", optional = true }
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
|
io,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
|
vec::IntoIter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use actix_rt::task::{spawn_blocking, JoinHandle};
|
||||||
use actix_service::{Service, ServiceFactory};
|
use actix_service::{Service, ServiceFactory};
|
||||||
use futures_core::future::LocalBoxFuture;
|
use futures_core::{future::LocalBoxFuture, ready};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
use super::connect::{Address, Connect};
|
use super::connect::{Address, Connect};
|
||||||
|
@ -115,46 +118,24 @@ impl Resolver {
|
||||||
Self::Custom(Rc::new(resolver))
|
Self::Custom(Rc::new(resolver))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn lookup<T: Address>(
|
// look up with default resolver variant.
|
||||||
&self,
|
fn look_up<T: Address>(req: &Connect<T>) -> JoinHandle<io::Result<IntoIter<SocketAddr>>> {
|
||||||
req: &Connect<T>,
|
let host = req.host();
|
||||||
) -> Result<Vec<SocketAddr>, ConnectError> {
|
// TODO: Connect should always return host with port if possible.
|
||||||
match self {
|
let host = if req
|
||||||
Self::Default => {
|
.host()
|
||||||
let host = req.host();
|
.splitn(2, ':')
|
||||||
// TODO: Connect should always return host with port if possible.
|
.last()
|
||||||
let host = if req
|
.and_then(|p| p.parse::<u16>().ok())
|
||||||
.host()
|
.map(|p| p == req.port())
|
||||||
.splitn(2, ':')
|
.unwrap_or(false)
|
||||||
.last()
|
{
|
||||||
.and_then(|p| p.parse::<u16>().ok())
|
host.to_string()
|
||||||
.map(|p| p == req.port())
|
} else {
|
||||||
.unwrap_or(false)
|
format!("{}:{}", host, req.port())
|
||||||
{
|
};
|
||||||
host.to_string()
|
|
||||||
} else {
|
|
||||||
format!("{}:{}", host, req.port())
|
|
||||||
};
|
|
||||||
|
|
||||||
let res = tokio::net::lookup_host(host)
|
spawn_blocking(move || std::net::ToSocketAddrs::to_socket_addrs(&host))
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
trace!(
|
|
||||||
"DNS resolver: failed to resolve host {:?} err: {}",
|
|
||||||
req.host(),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
ConnectError::Resolver(Box::new(e))
|
|
||||||
})?
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
Self::Custom(resolver) => resolver
|
|
||||||
.lookup(req.host(), req.port())
|
|
||||||
.await
|
|
||||||
.map_err(ConnectError::Resolver),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,31 +156,41 @@ impl<T: Address> Service<Connect<T>> for Resolver {
|
||||||
} else {
|
} else {
|
||||||
trace!("DNS resolver: resolving host {:?}", req.host());
|
trace!("DNS resolver: resolving host {:?}", req.host());
|
||||||
|
|
||||||
let resolver = self.clone();
|
match self {
|
||||||
ResolverFuture::Lookup(Box::pin(async move {
|
Self::Default => {
|
||||||
let addrs = resolver.lookup(&req).await?;
|
let fut = Self::look_up(&req);
|
||||||
|
ResolverFuture::LookUp(fut, Some(req))
|
||||||
let req = req.set_addrs(addrs);
|
|
||||||
|
|
||||||
trace!(
|
|
||||||
"DNS resolver: host {:?} resolved to {:?}",
|
|
||||||
req.host(),
|
|
||||||
req.addrs()
|
|
||||||
);
|
|
||||||
|
|
||||||
if req.addr.is_none() {
|
|
||||||
Err(ConnectError::NoRecords)
|
|
||||||
} else {
|
|
||||||
Ok(req)
|
|
||||||
}
|
}
|
||||||
}))
|
|
||||||
|
Self::Custom(resolver) => {
|
||||||
|
let resolver = Rc::clone(&resolver);
|
||||||
|
ResolverFuture::LookupCustom(Box::pin(async move {
|
||||||
|
let addrs = resolver
|
||||||
|
.lookup(req.host(), req.port())
|
||||||
|
.await
|
||||||
|
.map_err(ConnectError::Resolver)?;
|
||||||
|
|
||||||
|
let req = req.set_addrs(addrs);
|
||||||
|
|
||||||
|
if req.addr.is_none() {
|
||||||
|
Err(ConnectError::NoRecords)
|
||||||
|
} else {
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ResolverFuture<T: Address> {
|
pub enum ResolverFuture<T: Address> {
|
||||||
Connected(Option<Connect<T>>),
|
Connected(Option<Connect<T>>),
|
||||||
Lookup(LocalBoxFuture<'static, Result<Connect<T>, ConnectError>>),
|
LookUp(
|
||||||
|
JoinHandle<io::Result<IntoIter<SocketAddr>>>,
|
||||||
|
Option<Connect<T>>,
|
||||||
|
),
|
||||||
|
LookupCustom(LocalBoxFuture<'static, Result<Connect<T>, ConnectError>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> Future for ResolverFuture<T> {
|
impl<T: Address> Future for ResolverFuture<T> {
|
||||||
|
@ -210,7 +201,39 @@ impl<T: Address> Future for ResolverFuture<T> {
|
||||||
Self::Connected(conn) => Poll::Ready(Ok(conn
|
Self::Connected(conn) => Poll::Ready(Ok(conn
|
||||||
.take()
|
.take()
|
||||||
.expect("ResolverFuture polled after finished"))),
|
.expect("ResolverFuture polled after finished"))),
|
||||||
Self::Lookup(fut) => fut.as_mut().poll(cx),
|
Self::LookUp(fut, req) => {
|
||||||
|
let res = match ready!(Pin::new(fut).poll(cx)) {
|
||||||
|
Ok(Ok(res)) => Ok(res),
|
||||||
|
Ok(Err(e)) => Err(ConnectError::Resolver(Box::new(e))),
|
||||||
|
Err(e) => Err(ConnectError::Io(e.into())),
|
||||||
|
};
|
||||||
|
|
||||||
|
let req = req.take().unwrap();
|
||||||
|
|
||||||
|
let addrs = res.map_err(|e| {
|
||||||
|
trace!(
|
||||||
|
"DNS resolver: failed to resolve host {:?} err: {:?}",
|
||||||
|
req.host(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let req = req.set_addrs(addrs);
|
||||||
|
|
||||||
|
trace!(
|
||||||
|
"DNS resolver: host {:?} resolved to {:?}",
|
||||||
|
req.host(),
|
||||||
|
req.addrs()
|
||||||
|
);
|
||||||
|
|
||||||
|
if req.addr.is_none() {
|
||||||
|
Poll::Ready(Err(ConnectError::NoRecords))
|
||||||
|
} else {
|
||||||
|
Poll::Ready(Ok(req))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::LookupCustom(fut) => fut.as_mut().poll(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue