mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-27 20:12:58 +01:00
Expose Connect addrs (#30)
This commit is contained in:
parent
da302d4b7a
commit
1b3cd0d88c
@ -1,5 +1,6 @@
|
|||||||
use std::collections::VecDeque;
|
use std::collections::{vec_deque, VecDeque};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::iter::{FromIterator, FusedIterator};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
@ -77,6 +78,20 @@ impl<T: Address> Connect<T> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use addresses.
|
||||||
|
pub fn set_addrs<I>(mut self, addrs: I) -> Self
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = SocketAddr>,
|
||||||
|
{
|
||||||
|
let mut addrs = VecDeque::from_iter(addrs);
|
||||||
|
self.addr = if addrs.len() < 2 {
|
||||||
|
addrs.pop_front().map(Either::Left)
|
||||||
|
} else {
|
||||||
|
Some(Either::Right(addrs))
|
||||||
|
};
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Host name
|
/// Host name
|
||||||
pub fn host(&self) -> &str {
|
pub fn host(&self) -> &str {
|
||||||
self.req.host()
|
self.req.host()
|
||||||
@ -86,6 +101,28 @@ impl<T: Address> Connect<T> {
|
|||||||
pub fn port(&self) -> u16 {
|
pub fn port(&self) -> u16 {
|
||||||
self.req.port().unwrap_or(self.port)
|
self.req.port().unwrap_or(self.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Preresolved addresses of the request.
|
||||||
|
pub fn addrs(&self) -> ConnectAddrsIter<'_> {
|
||||||
|
let inner = match self.addr {
|
||||||
|
None => Either::Left(None),
|
||||||
|
Some(Either::Left(addr)) => Either::Left(Some(addr)),
|
||||||
|
Some(Either::Right(ref addrs)) => Either::Right(addrs.iter()),
|
||||||
|
};
|
||||||
|
|
||||||
|
ConnectAddrsIter { inner }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Takes preresolved addresses of the request.
|
||||||
|
pub fn take_addrs(&mut self) -> ConnectTakeAddrsIter {
|
||||||
|
let inner = match self.addr.take() {
|
||||||
|
None => Either::Left(None),
|
||||||
|
Some(Either::Left(addr)) => Either::Left(Some(addr)),
|
||||||
|
Some(Either::Right(addrs)) => Either::Right(addrs.into_iter()),
|
||||||
|
};
|
||||||
|
|
||||||
|
ConnectTakeAddrsIter { inner }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> From<T> for Connect<T> {
|
impl<T: Address> From<T> for Connect<T> {
|
||||||
@ -100,6 +137,70 @@ impl<T: Address> fmt::Display for Connect<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterator over addresses in a [`Connect`](struct.Connect.html) request.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ConnectAddrsIter<'a> {
|
||||||
|
inner: Either<Option<SocketAddr>, vec_deque::Iter<'a, SocketAddr>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for ConnectAddrsIter<'_> {
|
||||||
|
type Item = SocketAddr;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
match self.inner {
|
||||||
|
Either::Left(ref mut opt) => opt.take(),
|
||||||
|
Either::Right(ref mut iter) => iter.next().copied(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
match self.inner {
|
||||||
|
Either::Left(Some(_)) => (1, Some(1)),
|
||||||
|
Either::Left(None) => (0, Some(0)),
|
||||||
|
Either::Right(ref iter) => iter.size_hint(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for ConnectAddrsIter<'_> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_list().entries(self.clone()).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExactSizeIterator for ConnectAddrsIter<'_> {}
|
||||||
|
|
||||||
|
impl FusedIterator for ConnectAddrsIter<'_> {}
|
||||||
|
|
||||||
|
/// Owned iterator over addresses in a [`Connect`](struct.Connect.html) request.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ConnectTakeAddrsIter {
|
||||||
|
inner: Either<Option<SocketAddr>, vec_deque::IntoIter<SocketAddr>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for ConnectTakeAddrsIter {
|
||||||
|
type Item = SocketAddr;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
match self.inner {
|
||||||
|
Either::Left(ref mut opt) => opt.take(),
|
||||||
|
Either::Right(ref mut iter) => iter.next(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
match self.inner {
|
||||||
|
Either::Left(Some(_)) => (1, Some(1)),
|
||||||
|
Either::Left(None) => (0, Some(0)),
|
||||||
|
Either::Right(ref iter) => iter.size_hint(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExactSizeIterator for ConnectTakeAddrsIter {}
|
||||||
|
|
||||||
|
impl FusedIterator for ConnectTakeAddrsIter {}
|
||||||
|
|
||||||
fn parse(host: &str) -> (&str, Option<u16>) {
|
fn parse(host: &str) -> (&str, Option<u16>) {
|
||||||
let mut parts_iter = host.splitn(2, ':');
|
let mut parts_iter = host.splitn(2, ':');
|
||||||
if let Some(host) = parts_iter.next() {
|
if let Some(host) = parts_iter.next() {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::collections::VecDeque;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
@ -162,23 +161,20 @@ impl<T: Address> Future for ResolverFuture<T> {
|
|||||||
})? {
|
})? {
|
||||||
Async::NotReady => Ok(Async::NotReady),
|
Async::NotReady => Ok(Async::NotReady),
|
||||||
Async::Ready(ips) => {
|
Async::Ready(ips) => {
|
||||||
let mut req = self.req.take().unwrap();
|
let req = self.req.take().unwrap();
|
||||||
let mut addrs: VecDeque<_> = ips
|
|
||||||
.iter()
|
let port = req.port();
|
||||||
.map(|ip| SocketAddr::new(ip, req.port()))
|
let req = req.set_addrs(ips.iter().map(|ip| SocketAddr::new(ip, port)));
|
||||||
.collect();
|
|
||||||
trace!(
|
trace!(
|
||||||
"DNS resolver: host {:?} resolved to {:?}",
|
"DNS resolver: host {:?} resolved to {:?}",
|
||||||
req.host(),
|
req.host(),
|
||||||
addrs
|
req.addrs()
|
||||||
);
|
);
|
||||||
if addrs.is_empty() {
|
|
||||||
|
if req.addr.is_none() {
|
||||||
Err(ConnectError::NoRecords)
|
Err(ConnectError::NoRecords)
|
||||||
} else if addrs.len() == 1 {
|
|
||||||
req.addr = Some(either::Either::Left(addrs.pop_front().unwrap()));
|
|
||||||
Ok(Async::Ready(req))
|
|
||||||
} else {
|
} else {
|
||||||
req.addr = Some(either::Either::Right(addrs));
|
|
||||||
Ok(Async::Ready(req))
|
Ok(Async::Ready(req))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user