diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2021-06-29 01:43:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-29 01:43:03 +0200 |
commit | 38a7128cdd6f3308ba3c13cfb0b0d4ef925a44c3 (patch) | |
tree | 8f0c86028d9ba0266f1846e7f3611f7049cb43a8 /extensions/net/resolve_addr.rs | |
parent | 30cba2484815f712502ae8937a25afa13aba0818 (diff) |
feat: Add "deno_net" extension (#11150)
This commits moves implementation of net related APIs available on "Deno"
namespace to "deno_net" extension.
Following APIs were moved:
- Deno.listen()
- Deno.connect()
- Deno.listenTls()
- Deno.serveHttp()
- Deno.shutdown()
- Deno.resolveDns()
- Deno.listenDatagram()
- Deno.startTls()
- Deno.Conn
- Deno.Listener
- Deno.DatagramConn
Diffstat (limited to 'extensions/net/resolve_addr.rs')
-rw-r--r-- | extensions/net/resolve_addr.rs | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/extensions/net/resolve_addr.rs b/extensions/net/resolve_addr.rs new file mode 100644 index 000000000..ebf1374d1 --- /dev/null +++ b/extensions/net/resolve_addr.rs @@ -0,0 +1,156 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::AnyError; +use std::net::SocketAddr; +use std::net::ToSocketAddrs; +use tokio::net::lookup_host; + +/// Resolve network address *asynchronously*. +pub async fn resolve_addr( + hostname: &str, + port: u16, +) -> Result<impl Iterator<Item = SocketAddr> + '_, AnyError> { + let addr_port_pair = make_addr_port_pair(hostname, port); + let result = lookup_host(addr_port_pair).await?; + Ok(result) +} + +/// Resolve network address *synchronously*. +pub fn resolve_addr_sync( + hostname: &str, + port: u16, +) -> Result<impl Iterator<Item = SocketAddr>, AnyError> { + let addr_port_pair = make_addr_port_pair(hostname, port); + let result = addr_port_pair.to_socket_addrs()?; + Ok(result) +} + +fn make_addr_port_pair(hostname: &str, port: u16) -> (&str, u16) { + // Default to localhost if given just the port. Example: ":80" + if hostname.is_empty() { + return ("0.0.0.0", port); + } + + // If this looks like an ipv6 IP address. Example: "[2001:db8::1]" + // Then we remove the brackets. + let addr = hostname.trim_start_matches('[').trim_end_matches(']'); + (addr, port) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::net::Ipv4Addr; + use std::net::Ipv6Addr; + use std::net::SocketAddrV4; + use std::net::SocketAddrV6; + + #[tokio::test] + async fn resolve_addr1() { + let expected = vec![SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(127, 0, 0, 1), + 80, + ))]; + let actual = resolve_addr("127.0.0.1", 80) + .await + .unwrap() + .collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[tokio::test] + async fn resolve_addr2() { + let expected = vec![SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(0, 0, 0, 0), + 80, + ))]; + let actual = resolve_addr("", 80).await.unwrap().collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[tokio::test] + async fn resolve_addr3() { + let expected = vec![SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(192, 0, 2, 1), + 25, + ))]; + let actual = resolve_addr("192.0.2.1", 25) + .await + .unwrap() + .collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[tokio::test] + async fn resolve_addr_ipv6() { + let expected = vec![SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), + 8080, + 0, + 0, + ))]; + let actual = resolve_addr("[2001:db8::1]", 8080) + .await + .unwrap() + .collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[tokio::test] + async fn resolve_addr_err() { + assert!(resolve_addr("INVALID ADDR", 1234).await.is_err()); + } + + #[test] + fn resolve_addr_sync1() { + let expected = vec![SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(127, 0, 0, 1), + 80, + ))]; + let actual = resolve_addr_sync("127.0.0.1", 80) + .unwrap() + .collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[test] + fn resolve_addr_sync2() { + let expected = vec![SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(0, 0, 0, 0), + 80, + ))]; + let actual = resolve_addr_sync("", 80).unwrap().collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[test] + fn resolve_addr_sync3() { + let expected = vec![SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(192, 0, 2, 1), + 25, + ))]; + let actual = resolve_addr_sync("192.0.2.1", 25) + .unwrap() + .collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[test] + fn resolve_addr_sync_ipv6() { + let expected = vec![SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), + 8080, + 0, + 0, + ))]; + let actual = resolve_addr_sync("[2001:db8::1]", 8080) + .unwrap() + .collect::<Vec<_>>(); + assert_eq!(actual, expected); + } + + #[test] + fn resolve_addr_sync_err() { + assert!(resolve_addr_sync("INVALID ADDR", 1234).is_err()); + } +} |