2021-02-24 10:48:41 +01:00
|
|
|
#![cfg(feature = "connect")]
|
|
|
|
|
2021-01-26 09:05:19 +01:00
|
|
|
use std::{
|
|
|
|
io,
|
|
|
|
net::{Ipv4Addr, SocketAddr},
|
|
|
|
};
|
|
|
|
|
|
|
|
use actix_rt::net::TcpStream;
|
|
|
|
use actix_server::TestServer;
|
|
|
|
use actix_service::{fn_service, Service, ServiceFactory};
|
|
|
|
use futures_core::future::LocalBoxFuture;
|
|
|
|
|
|
|
|
use actix_tls::connect::{new_connector_factory, Connect, Resolve, Resolver};
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn custom_resolver() {
|
|
|
|
/// Always resolves to localhost with the given port.
|
|
|
|
struct LocalOnlyResolver;
|
|
|
|
|
|
|
|
impl Resolve for LocalOnlyResolver {
|
|
|
|
fn lookup<'a>(
|
|
|
|
&'a self,
|
|
|
|
_host: &'a str,
|
|
|
|
port: u16,
|
|
|
|
) -> LocalBoxFuture<'a, Result<Vec<SocketAddr>, Box<dyn std::error::Error>>> {
|
|
|
|
Box::pin(async move {
|
|
|
|
let local = format!("127.0.0.1:{}", port).parse().unwrap();
|
|
|
|
Ok(vec![local])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let addr = LocalOnlyResolver.lookup("example.com", 8080).await.unwrap()[0];
|
|
|
|
assert_eq!(addr, SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 8080))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn custom_resolver_connect() {
|
|
|
|
use trust_dns_resolver::TokioAsyncResolver;
|
|
|
|
|
|
|
|
let srv =
|
|
|
|
TestServer::with(|| fn_service(|_io: TcpStream| async { Ok::<_, io::Error>(()) }));
|
|
|
|
|
|
|
|
struct MyResolver {
|
|
|
|
trust_dns: TokioAsyncResolver,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Resolve for MyResolver {
|
|
|
|
fn lookup<'a>(
|
|
|
|
&'a self,
|
|
|
|
host: &'a str,
|
|
|
|
port: u16,
|
|
|
|
) -> LocalBoxFuture<'a, Result<Vec<SocketAddr>, Box<dyn std::error::Error>>> {
|
|
|
|
Box::pin(async move {
|
|
|
|
let res = self
|
|
|
|
.trust_dns
|
|
|
|
.lookup_ip(host)
|
|
|
|
.await?
|
|
|
|
.iter()
|
|
|
|
.map(|ip| SocketAddr::new(ip, port))
|
|
|
|
.collect();
|
|
|
|
Ok(res)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let resolver = MyResolver {
|
|
|
|
trust_dns: TokioAsyncResolver::tokio_from_system_conf().unwrap(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let resolver = Resolver::new_custom(resolver);
|
|
|
|
let factory = new_connector_factory(resolver);
|
|
|
|
|
|
|
|
let conn = factory.new_service(()).await.unwrap();
|
|
|
|
let con = conn
|
|
|
|
.call(Connect::with_addr("example.com", srv.addr()))
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(con.peer_addr().unwrap(), srv.addr());
|
|
|
|
}
|