diff --git a/src/client/connect.rs b/src/client/connect.rs index a1214bb8..d9c918e0 100644 --- a/src/client/connect.rs +++ b/src/client/connect.rs @@ -186,9 +186,18 @@ impl Future for HttpConnecting { let state; match self.state { State::Lazy(ref executor, ref mut host, port) => { - let host = mem::replace(host, String::new()); - let work = dns::Work::new(host, port); - state = State::Resolving(oneshot::spawn(work, executor)); + // If the host is already an IP addr (v4 or v6), + // skip resolving the dns and start connecting right away. + if let Some(addrs) = dns::IpAddrs::try_parse(host, port) { + state = State::Connecting(ConnectingTcp { + addrs: addrs, + current: None + }) + } else { + let host = mem::replace(host, String::new()); + let work = dns::Work::new(host, port); + state = State::Resolving(oneshot::spawn(work, executor)); + } }, State::Resolving(ref mut future) => { match try!(future.poll()) { diff --git a/src/client/dns.rs b/src/client/dns.rs index cf522801..5bf1ccc2 100644 --- a/src/client/dns.rs +++ b/src/client/dns.rs @@ -1,5 +1,9 @@ use std::io; -use std::net::{SocketAddr, ToSocketAddrs}; +use std::net::{ + Ipv4Addr, Ipv6Addr, + SocketAddr, ToSocketAddrs, + SocketAddrV4, SocketAddrV6, +}; use std::vec; use ::futures::{Async, Future, Poll}; @@ -30,6 +34,20 @@ pub struct IpAddrs { iter: vec::IntoIter, } +impl IpAddrs { + pub fn try_parse(host: &str, port: u16) -> Option { + if let Ok(addr) = host.parse::() { + let addr = SocketAddrV4::new(addr, port); + return Some(IpAddrs { iter: vec![SocketAddr::V4(addr)].into_iter() }) + } + if let Ok(addr) = host.parse::() { + let addr = SocketAddrV6::new(addr, port, 0, 0); + return Some(IpAddrs { iter: vec![SocketAddr::V6(addr)].into_iter() }) + } + None + } +} + impl Iterator for IpAddrs { type Item = SocketAddr; #[inline]