actix_connector/
resolver.rs1use std::collections::VecDeque;
2use std::marker::PhantomData;
3use std::net::IpAddr;
4
5use actix_service::Service;
6use futures::{Async, Future, Poll};
7use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
8pub use trust_dns_resolver::error::ResolveError;
9use trust_dns_resolver::lookup_ip::LookupIpFuture;
10use trust_dns_resolver::system_conf::read_system_conf;
11use trust_dns_resolver::{AsyncResolver, Background};
12
13pub trait RequestHost {
15 fn host(&self) -> &str;
16}
17
18impl RequestHost for String {
19 fn host(&self) -> &str {
20 self.as_ref()
21 }
22}
23
24pub struct Resolver<T = String> {
25 resolver: AsyncResolver,
26 req: PhantomData<T>,
27}
28
29impl<T: RequestHost> Default for Resolver<T> {
30 fn default() -> Self {
31 let (cfg, opts) = if let Ok((cfg, opts)) = read_system_conf() {
32 (cfg, opts)
33 } else {
34 (ResolverConfig::default(), ResolverOpts::default())
35 };
36
37 Resolver::new(cfg, opts)
38 }
39}
40
41impl<T: RequestHost> Resolver<T> {
42 pub fn new(cfg: ResolverConfig, opts: ResolverOpts) -> Self {
44 let (resolver, bg) = AsyncResolver::new(cfg, opts);
45 tokio_current_thread::spawn(bg);
46 Resolver {
47 resolver,
48 req: PhantomData,
49 }
50 }
51
52 pub fn into_request<T2: RequestHost>(&self) -> Resolver<T2> {
54 Resolver {
55 resolver: self.resolver.clone(),
56 req: PhantomData,
57 }
58 }
59}
60
61impl<T> Clone for Resolver<T> {
62 fn clone(&self) -> Self {
63 Resolver {
64 resolver: self.resolver.clone(),
65 req: PhantomData,
66 }
67 }
68}
69
70impl<T: RequestHost> Service for Resolver<T> {
71 type Request = T;
72 type Response = (T, VecDeque<IpAddr>);
73 type Error = ResolveError;
74 type Future = ResolverFuture<T>;
75
76 fn poll_ready(&mut self) -> Poll<(), Self::Error> {
77 Ok(Async::Ready(()))
78 }
79
80 fn call(&mut self, req: T) -> Self::Future {
81 if let Ok(ip) = req.host().parse() {
82 let mut addrs = VecDeque::new();
83 addrs.push_back(ip);
84 ResolverFuture::new(req, &self.resolver, Some(addrs))
85 } else {
86 ResolverFuture::new(req, &self.resolver, None)
87 }
88 }
89}
90
91#[doc(hidden)]
92pub struct ResolverFuture<T> {
94 req: Option<T>,
95 lookup: Option<Background<LookupIpFuture>>,
96 addrs: Option<VecDeque<IpAddr>>,
97}
98
99impl<T: RequestHost> ResolverFuture<T> {
100 pub fn new(addr: T, resolver: &AsyncResolver, addrs: Option<VecDeque<IpAddr>>) -> Self {
101 let lookup = Some(resolver.lookup_ip(addr.host()));
103 ResolverFuture {
104 lookup,
105 addrs,
106 req: Some(addr),
107 }
108 }
109}
110
111impl<T: RequestHost> Future for ResolverFuture<T> {
112 type Item = (T, VecDeque<IpAddr>);
113 type Error = ResolveError;
114
115 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
116 if let Some(addrs) = self.addrs.take() {
117 Ok(Async::Ready((self.req.take().unwrap(), addrs)))
118 } else {
119 match self.lookup.as_mut().unwrap().poll() {
120 Ok(Async::NotReady) => Ok(Async::NotReady),
121 Ok(Async::Ready(ips)) => Ok(Async::Ready((
122 self.req.take().unwrap(),
123 ips.iter().collect(),
124 ))),
125 Err(err) => Err(err),
126 }
127 }
128 }
129}