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};
|
2021-11-30 00:53:06 +01:00
|
|
|
use actix_tls::connect::{
|
|
|
|
ConnectError, ConnectInfo, Connection, Connector, Host, Resolve, Resolver,
|
|
|
|
};
|
2022-04-10 03:48:53 +02:00
|
|
|
use futures_core::future::LocalBoxFuture;
|
2021-01-26 09:05:19 +01:00
|
|
|
|
|
|
|
#[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() {
|
2021-11-30 00:53:06 +01:00
|
|
|
pub fn connector_factory<T: Host + 'static>(
|
|
|
|
resolver: Resolver,
|
|
|
|
) -> impl ServiceFactory<
|
|
|
|
ConnectInfo<T>,
|
|
|
|
Config = (),
|
|
|
|
Response = Connection<T, TcpStream>,
|
|
|
|
Error = ConnectError,
|
|
|
|
InitError = (),
|
|
|
|
> {
|
|
|
|
Connector::new(resolver)
|
|
|
|
}
|
|
|
|
|
2021-01-26 09:05:19 +01:00
|
|
|
use trust_dns_resolver::TokioAsyncResolver;
|
|
|
|
|
2023-07-17 04:05:39 +02:00
|
|
|
let srv = TestServer::start(|| fn_service(|_io: TcpStream| async { Ok::<_, io::Error>(()) }));
|
2021-01-26 09:05:19 +01:00
|
|
|
|
|
|
|
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(),
|
|
|
|
};
|
|
|
|
|
2021-11-30 00:53:06 +01:00
|
|
|
let factory = connector_factory(Resolver::custom(resolver));
|
2021-01-26 09:05:19 +01:00
|
|
|
|
|
|
|
let conn = factory.new_service(()).await.unwrap();
|
|
|
|
let con = conn
|
2021-11-30 00:53:06 +01:00
|
|
|
.call(ConnectInfo::with_addr("example.com", srv.addr()))
|
2021-01-26 09:05:19 +01:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(con.peer_addr().unwrap(), srv.addr());
|
|
|
|
}
|