use crate::pipeline::network::tcp::server::{DefaultIpResolver, IpResolver};
use local_ip_address::Error;
use std::net::IpAddr;
pub fn get_http_rpc_host_with_resolver<R: IpResolver>(resolver: R) -> String {
let resolved_ip = resolver.local_ip().or_else(|err| match err {
Error::LocalIpAddressNotFound => resolver.local_ipv6(),
_ => Err(err),
});
match resolved_ip {
Ok(addr) => addr,
Err(Error::LocalIpAddressNotFound) => IpAddr::from([127, 0, 0, 1]),
Err(_) => IpAddr::from([127, 0, 0, 1]), }
.to_string()
}
pub fn get_http_rpc_host() -> String {
get_http_rpc_host_with_resolver(DefaultIpResolver)
}
pub fn get_http_rpc_host_from_env() -> String {
std::env::var("DYN_HTTP_RPC_HOST").unwrap_or_else(|_| get_http_rpc_host())
}
pub fn get_tcp_rpc_host_from_env() -> String {
std::env::var("DYN_TCP_RPC_HOST").unwrap_or_else(|_| get_http_rpc_host())
}
#[cfg(test)]
mod tests {
use super::*;
use local_ip_address::Error;
struct MockIpResolver {
ipv4_result: Result<IpAddr, Error>,
ipv6_result: Result<IpAddr, Error>,
}
impl IpResolver for MockIpResolver {
fn local_ip(&self) -> Result<IpAddr, Error> {
match &self.ipv4_result {
Ok(addr) => Ok(*addr),
Err(Error::LocalIpAddressNotFound) => Err(Error::LocalIpAddressNotFound),
Err(_) => Err(Error::LocalIpAddressNotFound), }
}
fn local_ipv6(&self) -> Result<IpAddr, Error> {
match &self.ipv6_result {
Ok(addr) => Ok(*addr),
Err(Error::LocalIpAddressNotFound) => Err(Error::LocalIpAddressNotFound),
Err(_) => Err(Error::LocalIpAddressNotFound), }
}
}
#[test]
fn test_get_http_rpc_host_with_successful_ipv4() {
let resolver = MockIpResolver {
ipv4_result: Ok(IpAddr::from([192, 168, 1, 100])),
ipv6_result: Ok(IpAddr::from([0, 0, 0, 0, 0, 0, 0, 1])),
};
let result = get_http_rpc_host_with_resolver(resolver);
assert_eq!(result, "192.168.1.100");
}
#[test]
fn test_get_http_rpc_host_with_ipv4_fail_ipv6_success() {
let resolver = MockIpResolver {
ipv4_result: Err(Error::LocalIpAddressNotFound),
ipv6_result: Ok(IpAddr::from([0x2001, 0xdb8, 0, 0, 0, 0, 0, 1])),
};
let result = get_http_rpc_host_with_resolver(resolver);
assert_eq!(result, "2001:db8::1");
}
#[test]
fn test_get_http_rpc_host_with_both_fail() {
let resolver = MockIpResolver {
ipv4_result: Err(Error::LocalIpAddressNotFound),
ipv6_result: Err(Error::LocalIpAddressNotFound),
};
let result = get_http_rpc_host_with_resolver(resolver);
assert_eq!(result, "127.0.0.1");
}
#[test]
fn test_get_http_rpc_host_from_env_with_env_var() {
unsafe {
std::env::set_var("DYN_HTTP_RPC_HOST", "10.0.0.1");
}
let result = get_http_rpc_host_from_env();
assert_eq!(result, "10.0.0.1");
unsafe {
std::env::remove_var("DYN_HTTP_RPC_HOST");
}
}
#[test]
fn test_get_http_rpc_host_from_env_without_env_var() {
let result = get_http_rpc_host_from_env();
assert!(!result.is_empty());
let _: IpAddr = result.parse().expect("Should be a valid IP address");
}
}