1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-01-19 22:14:40 +01:00
actix-net/src/connector.rs

281 lines
6.9 KiB
Rust
Raw Normal View History

2018-08-23 20:47:41 -07:00
use std::collections::VecDeque;
use std::io;
use std::net::SocketAddr;
2018-10-23 22:14:02 -07:00
use std::time::Duration;
2018-08-23 20:47:41 -07:00
2018-08-28 16:24:36 -07:00
use futures::{
future::{ok, FutureResult},
Async, Future, Poll,
};
2018-08-23 20:47:41 -07:00
use tokio_tcp::{ConnectFuture, TcpStream};
use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
2018-08-28 16:24:36 -07:00
use trust_dns_resolver::system_conf::read_system_conf;
2018-08-23 20:47:41 -07:00
2018-09-10 19:39:55 -07:00
use super::resolver::{HostAware, Resolver, ResolverError, ResolverFuture};
2018-09-11 09:30:22 -07:00
use super::service::{NewService, Service};
2018-08-28 16:24:36 -07:00
2018-09-10 19:39:55 -07:00
// #[derive(Fail, Debug)]
#[derive(Debug)]
2018-08-23 20:47:41 -07:00
pub enum ConnectorError {
/// Failed to resolve the hostname
2018-09-10 19:39:55 -07:00
// #[fail(display = "Failed resolving hostname: {}", _0)]
Resolver(ResolverError),
2018-08-23 20:47:41 -07:00
2018-09-10 19:39:55 -07:00
/// Not dns records
// #[fail(display = "Invalid input: {}", _0)]
NoRecords,
2018-08-23 20:47:41 -07:00
2018-10-23 22:14:02 -07:00
/// Connecting took too long
// #[fail(display = "Timeout out while establishing connection")]
Timeout,
2018-08-23 20:47:41 -07:00
/// Connection io error
2018-09-10 19:39:55 -07:00
// #[fail(display = "{}", _0)]
2018-08-23 20:47:41 -07:00
IoError(io::Error),
}
2018-09-10 19:39:55 -07:00
impl From<ResolverError> for ConnectorError {
fn from(err: ResolverError) -> Self {
ConnectorError::Resolver(err)
}
}
2018-10-23 22:14:02 -07:00
#[derive(Eq, PartialEq, Debug)]
pub struct Connect {
2018-08-28 16:24:36 -07:00
pub host: String,
2018-10-23 22:14:02 -07:00
pub port: Option<u16>,
pub timeout: Duration,
}
impl Connect {
pub fn host<T: AsRef<str>>(host: T) -> Connect {
Connect {
host: host.as_ref().to_owned(),
port: None,
timeout: Duration::from_secs(1),
}
}
pub fn host_and_port<T: AsRef<str>>(host: T, port: u16) -> Connect {
Connect {
host: host.as_ref().to_owned(),
port: Some(port),
timeout: Duration::from_secs(1),
}
}
/// Set connect timeout
///
/// By default timeout is set to a 1 second.
pub fn timeout(mut self, timeout: Duration) -> Connect {
self.timeout = timeout;
self
}
}
impl HostAware for Connect {
fn host(&self) -> &str {
&self.host
}
2018-08-28 16:24:36 -07:00
}
2018-10-23 22:14:02 -07:00
pub struct Connector {
resolver: Resolver<Connect>,
2018-08-23 20:47:41 -07:00
}
2018-10-23 22:14:02 -07:00
impl Default for Connector {
2018-08-28 16:24:36 -07:00
fn default() -> Self {
let (cfg, opts) = if let Ok((cfg, opts)) = read_system_conf() {
(cfg, opts)
} else {
(ResolverConfig::default(), ResolverOpts::default())
2018-08-23 20:47:41 -07:00
};
2018-08-28 16:24:36 -07:00
Connector::new(cfg, opts)
}
}
2018-10-23 22:14:02 -07:00
impl Connector {
2018-08-28 16:24:36 -07:00
pub fn new(cfg: ResolverConfig, opts: ResolverOpts) -> Self {
2018-08-29 15:15:24 -07:00
Connector {
2018-09-10 19:39:55 -07:00
resolver: Resolver::new(cfg, opts),
2018-08-29 15:15:24 -07:00
}
2018-08-23 20:47:41 -07:00
}
2018-08-27 20:32:49 -07:00
2018-09-10 19:42:51 -07:00
pub fn with_resolver(
2018-10-23 22:14:02 -07:00
resolver: Resolver<Connect>,
) -> impl Service<Request = Connect, Response = (Connect, TcpStream), Error = ConnectorError>
+ Clone {
2018-09-10 19:42:51 -07:00
Connector { resolver }
}
2018-08-28 16:24:36 -07:00
pub fn new_service<E>() -> impl NewService<
2018-10-23 22:14:02 -07:00
Request = Connect,
Response = (Connect, TcpStream),
2018-08-28 16:24:36 -07:00
Error = ConnectorError,
InitError = E,
> + Clone {
2018-10-23 22:14:02 -07:00
|| -> FutureResult<Connector, E> { ok(Connector::default()) }
2018-08-28 16:24:36 -07:00
}
pub fn new_service_with_config<E>(
cfg: ResolverConfig, opts: ResolverOpts,
) -> impl NewService<
2018-10-23 22:14:02 -07:00
Request = Connect,
Response = (Connect, TcpStream),
2018-08-28 16:24:36 -07:00
Error = ConnectorError,
InitError = E,
> + Clone {
2018-10-23 22:14:02 -07:00
move || -> FutureResult<Connector, E> { ok(Connector::new(cfg.clone(), opts)) }
}
2018-08-27 20:32:49 -07:00
}
2018-10-23 22:14:02 -07:00
impl Clone for Connector {
2018-08-27 20:32:49 -07:00
fn clone(&self) -> Self {
Connector {
resolver: self.resolver.clone(),
}
}
2018-08-23 20:47:41 -07:00
}
2018-10-23 22:14:02 -07:00
impl Service for Connector {
type Request = Connect;
type Response = (Connect, TcpStream);
2018-08-23 20:47:41 -07:00
type Error = ConnectorError;
2018-10-23 22:14:02 -07:00
type Future = ConnectorFuture;
2018-08-23 20:47:41 -07:00
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
2018-08-29 15:15:24 -07:00
fn call(&mut self, req: Self::Request) -> Self::Future {
2018-09-10 19:39:55 -07:00
ConnectorFuture {
fut: self.resolver.call(req),
fut2: None,
}
2018-08-23 20:47:41 -07:00
}
}
2018-09-11 14:01:51 -07:00
#[doc(hidden)]
2018-10-23 22:14:02 -07:00
pub struct ConnectorFuture {
fut: ResolverFuture<Connect>,
fut2: Option<TcpConnector>,
2018-08-23 20:47:41 -07:00
}
2018-10-23 22:14:02 -07:00
impl Future for ConnectorFuture {
type Item = (Connect, TcpStream);
2018-08-23 20:47:41 -07:00
type Error = ConnectorError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
if let Some(ref mut fut) = self.fut2 {
2018-08-28 16:24:36 -07:00
return fut.poll();
2018-08-23 20:47:41 -07:00
}
2018-09-10 19:39:55 -07:00
match self.fut.poll().map_err(ConnectorError::from)? {
2018-10-23 22:14:02 -07:00
Async::Ready((req, _, addrs)) => {
2018-09-10 19:39:55 -07:00
if addrs.is_empty() {
Err(ConnectorError::NoRecords)
} else {
2018-10-23 22:14:02 -07:00
self.fut2 = Some(TcpConnector::new(req, addrs));
2018-09-10 19:39:55 -07:00
self.poll()
}
2018-08-23 22:12:10 -07:00
}
Async::NotReady => Ok(Async::NotReady),
2018-08-23 20:47:41 -07:00
}
}
}
2018-09-11 14:01:51 -07:00
#[doc(hidden)]
2018-08-23 20:47:41 -07:00
/// Tcp stream connector
2018-10-23 22:14:02 -07:00
pub struct TcpConnector {
req: Option<Connect>,
2018-08-28 16:24:36 -07:00
addr: Option<SocketAddr>,
2018-08-23 20:47:41 -07:00
addrs: VecDeque<SocketAddr>,
stream: Option<ConnectFuture>,
}
2018-10-23 22:14:02 -07:00
impl TcpConnector {
pub fn new(req: Connect, addrs: VecDeque<SocketAddr>) -> TcpConnector {
2018-08-23 20:47:41 -07:00
TcpConnector {
addrs,
2018-08-29 15:15:24 -07:00
req: Some(req),
2018-08-28 16:24:36 -07:00
addr: None,
2018-08-23 20:47:41 -07:00
stream: None,
}
}
}
2018-10-23 22:14:02 -07:00
impl Future for TcpConnector {
type Item = (Connect, TcpStream);
2018-08-23 20:47:41 -07:00
type Error = ConnectorError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
// connect
loop {
if let Some(new) = self.stream.as_mut() {
match new.poll() {
2018-08-28 16:24:36 -07:00
Ok(Async::Ready(sock)) => {
2018-10-23 22:14:02 -07:00
return Ok(Async::Ready((self.req.take().unwrap(), sock)))
2018-08-28 16:24:36 -07:00
}
2018-08-23 20:47:41 -07:00
Ok(Async::NotReady) => return Ok(Async::NotReady),
Err(err) => {
if self.addrs.is_empty() {
return Err(ConnectorError::IoError(err));
}
}
}
}
// try to connect
let addr = self.addrs.pop_front().unwrap();
self.stream = Some(TcpStream::connect(&addr));
2018-08-28 16:24:36 -07:00
self.addr = Some(addr)
2018-08-23 20:47:41 -07:00
}
}
}
2018-10-23 22:26:16 -07:00
#[derive(Clone)]
pub struct DefaultConnector(Connector);
impl Default for DefaultConnector {
fn default() -> Self {
DefaultConnector(Connector::default())
}
}
impl DefaultConnector {
pub fn new(cfg: ResolverConfig, opts: ResolverOpts) -> Self {
DefaultConnector(Connector::new(cfg, opts))
}
}
impl Service for DefaultConnector {
type Request = Connect;
type Response = TcpStream;
type Error = ConnectorError;
type Future = DefaultConnectorFuture;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.0.poll_ready()
}
fn call(&mut self, req: Self::Request) -> Self::Future {
DefaultConnectorFuture {
fut: self.0.call(req),
}
}
}
#[doc(hidden)]
pub struct DefaultConnectorFuture {
fut: ConnectorFuture,
}
impl Future for DefaultConnectorFuture {
type Item = TcpStream;
type Error = ConnectorError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
Ok(Async::Ready(try_ready!(self.fut.poll()).1))
}
}