actix_connect/
lib.rs

1//! TCP connector service for Actix ecosystem.
2//!
3//! ## Package feature
4//!
5//! * `openssl` - enables ssl support via `openssl` crate
6//! * `rustls` - enables ssl support via `rustls` crate
7
8#![deny(rust_2018_idioms)]
9#![recursion_limit = "128"]
10
11#[macro_use]
12extern crate log;
13
14mod connect;
15mod connector;
16mod error;
17mod resolve;
18mod service;
19pub mod ssl;
20
21#[cfg(feature = "uri")]
22mod uri;
23
24use actix_rt::{net::TcpStream, Arbiter};
25use actix_service::{pipeline, pipeline_factory, Service, ServiceFactory};
26use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
27use trust_dns_resolver::system_conf::read_system_conf;
28use trust_dns_resolver::TokioAsyncResolver as AsyncResolver;
29
30pub mod resolver {
31    pub use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};
32    pub use trust_dns_resolver::system_conf::read_system_conf;
33    pub use trust_dns_resolver::{error::ResolveError, AsyncResolver};
34}
35
36pub use self::connect::{Address, Connect, Connection};
37pub use self::connector::{TcpConnector, TcpConnectorFactory};
38pub use self::error::ConnectError;
39pub use self::resolve::{Resolver, ResolverFactory};
40pub use self::service::{ConnectService, ConnectServiceFactory, TcpConnectService};
41
42pub async fn start_resolver(
43    cfg: ResolverConfig,
44    opts: ResolverOpts,
45) -> Result<AsyncResolver, ConnectError> {
46    Ok(AsyncResolver::tokio(cfg, opts).await?)
47}
48
49struct DefaultResolver(AsyncResolver);
50
51pub(crate) async fn get_default_resolver() -> Result<AsyncResolver, ConnectError> {
52    if Arbiter::contains_item::<DefaultResolver>() {
53        Ok(Arbiter::get_item(|item: &DefaultResolver| item.0.clone()))
54    } else {
55        let (cfg, opts) = match read_system_conf() {
56            Ok((cfg, opts)) => (cfg, opts),
57            Err(e) => {
58                log::error!("TRust-DNS can not load system config: {}", e);
59                (ResolverConfig::default(), ResolverOpts::default())
60            }
61        };
62
63        let resolver = AsyncResolver::tokio(cfg, opts).await?;
64
65        Arbiter::set_item(DefaultResolver(resolver.clone()));
66        Ok(resolver)
67    }
68}
69
70pub async fn start_default_resolver() -> Result<AsyncResolver, ConnectError> {
71    get_default_resolver().await
72}
73
74/// Create TCP connector service.
75pub fn new_connector<T: Address + 'static>(
76    resolver: AsyncResolver,
77) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
78       + Clone {
79    pipeline(Resolver::new(resolver)).and_then(TcpConnector::new())
80}
81
82/// Create TCP connector service factory.
83pub fn new_connector_factory<T: Address + 'static>(
84    resolver: AsyncResolver,
85) -> impl ServiceFactory<
86    Config = (),
87    Request = Connect<T>,
88    Response = Connection<T, TcpStream>,
89    Error = ConnectError,
90    InitError = (),
91> + Clone {
92    pipeline_factory(ResolverFactory::new(resolver)).and_then(TcpConnectorFactory::new())
93}
94
95/// Create connector service with default parameters.
96pub fn default_connector<T: Address + 'static>(
97) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
98       + Clone {
99    pipeline(Resolver::default()).and_then(TcpConnector::new())
100}
101
102/// Create connector service factory with default parameters.
103pub fn default_connector_factory<T: Address + 'static>() -> impl ServiceFactory<
104    Config = (),
105    Request = Connect<T>,
106    Response = Connection<T, TcpStream>,
107    Error = ConnectError,
108    InitError = (),
109> + Clone {
110    pipeline_factory(ResolverFactory::default()).and_then(TcpConnectorFactory::new())
111}