diff --git a/cli/flags.rs b/cli/flags.rs index 8093f55c65..4226bb5c50 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -1,5 +1,4 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use crate::resolve_hosts::resolve_hosts; use clap::App; use clap::AppSettings; use clap::Arg; @@ -1054,7 +1053,7 @@ Grant permission to read from disk and listen to network: Grant permission to read allow-listed files from disk: deno run --allow-read=/etc https://deno.land/std/http/file_server.ts - + Deno allows specifying the filename '-' to read the file from stdin. curl https://deno.land/std/examples/welcome.ts | target/debug/deno run -", ) @@ -1376,6 +1375,41 @@ pub fn resolve_urls(urls: Vec) -> Vec { out } +/// Expands "bare port" paths (eg. ":8080") into full paths with hosts. It +/// expands to such paths into 3 paths with following hosts: `0.0.0.0:port`, +/// `127.0.0.1:port` and `localhost:port`. +fn resolve_hosts(paths: Vec) -> Vec { + let mut out: Vec = vec![]; + for host_and_port in paths.iter() { + let parts = host_and_port.split(':').collect::>(); + + match parts.len() { + // host only + 1 => { + out.push(host_and_port.to_owned()); + } + // host and port (NOTE: host might be empty string) + 2 => { + let host = parts[0]; + let port = parts[1]; + + if !host.is_empty() { + out.push(host_and_port.to_owned()); + continue; + } + + // we got bare port, let's add default hosts + for host in ["0.0.0.0", "127.0.0.1", "localhost"].iter() { + out.push(format!("{}:{}", host, port)); + } + } + _ => panic!("Bad host:port pair: {}", host_and_port), + } + } + + out +} + #[cfg(test)] mod tests { use super::*; @@ -2447,37 +2481,6 @@ mod tests { ); } - #[test] - fn allow_net_allowlist_with_ipv6_address() { - let r = flags_from_vec_safe(svec![ - "deno", - "run", - "--allow-net=deno.land,deno.land:80,::,127.0.0.1,[::1],1.2.3.4:5678,:5678,[::1]:8080", - "script.ts" - ]); - assert_eq!( - r.unwrap(), - Flags { - subcommand: DenoSubcommand::Run { - script: "script.ts".to_string(), - }, - net_allowlist: svec![ - "deno.land", - "deno.land:80", - "::", - "127.0.0.1", - "[::1]", - "1.2.3.4:5678", - "0.0.0.0:5678", - "127.0.0.1:5678", - "localhost:5678", - "[::1]:8080" - ], - ..Flags::default() - } - ); - } - #[test] fn lock_write() { let r = flags_from_vec_safe(svec![ diff --git a/cli/main.rs b/cli/main.rs index 4f327b08ef..e20435a007 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -52,7 +52,6 @@ pub mod ops; pub mod permissions; mod repl; pub mod resolve_addr; -pub mod resolve_hosts; pub mod signal; pub mod source_maps; mod startup_data; diff --git a/cli/resolve_hosts.rs b/cli/resolve_hosts.rs deleted file mode 100644 index d562af4d5d..0000000000 --- a/cli/resolve_hosts.rs +++ /dev/null @@ -1,188 +0,0 @@ -use std::net::IpAddr; -use std::str::FromStr; -use url::Url; - -#[derive(Debug, PartialEq, Eq)] -pub struct ParsePortError(String); - -#[derive(Debug, PartialEq, Eq)] -pub struct BarePort(u16); - -impl FromStr for BarePort { - type Err = ParsePortError; - fn from_str(s: &str) -> Result { - if s.starts_with(':') { - match s.split_at(1).1.parse::() { - Ok(port) => Ok(BarePort(port)), - Err(e) => Err(ParsePortError(e.to_string())), - } - } else { - Err(ParsePortError( - "Bare Port doesn't start with ':'".to_string(), - )) - } - } -} - -/// Expands "bare port" paths (eg. ":8080") into full paths with hosts. It -/// expands to such paths into 3 paths with following hosts: `0.0.0.0:port`, -/// `127.0.0.1:port` and `localhost:port`. -pub fn resolve_hosts(paths: Vec) -> Vec { - let mut out: Vec = vec![]; - for host_and_port in paths.iter() { - if Url::parse(&format!("deno://{}", host_and_port)).is_ok() - || host_and_port.parse::().is_ok() - { - out.push(host_and_port.to_owned()) - } else if let Ok(port) = host_and_port.parse::() { - // we got bare port, let's add default hosts - for host in ["0.0.0.0", "127.0.0.1", "localhost"].iter() { - out.push(format!("{}:{}", host, port.0)); - } - } else { - panic!("Bad host:port pair: {}", host_and_port) - } - } - out -} - -#[cfg(test)] -mod bare_port_tests { - use super::{BarePort, ParsePortError}; - - #[test] - fn bare_port_parsed() { - let expected = BarePort(8080); - let actual = ":8080".parse::(); - assert_eq!(actual, Ok(expected)); - } - - #[test] - fn bare_port_parse_error1() { - let expected = - ParsePortError("Bare Port doesn't start with ':'".to_string()); - let actual = "8080".parse::(); - assert_eq!(actual, Err(expected)); - } - - #[test] - fn bare_port_parse_error2() { - let actual = ":65536".parse::(); - assert!(actual.is_err()); - } - - #[test] - fn bare_port_parse_error3() { - let actual = ":14u16".parse::(); - assert!(actual.is_err()); - } - - #[test] - fn bare_port_parse_error4() { - let actual = "Deno".parse::(); - assert!(actual.is_err()); - } - - #[test] - fn bare_port_parse_error5() { - let actual = "deno.land:8080".parse::(); - assert!(actual.is_err()); - } -} - -#[cfg(test)] -mod tests { - use super::resolve_hosts; - - // Creates vector of strings, Vec - macro_rules! svec { - ($($x:expr),*) => (vec![$($x.to_string()),*]); - } - - #[test] - fn resolve_hosts_() { - let entries = svec![ - "deno.land", - "deno.land:80", - "::", - "::1", - "127.0.0.1", - "[::1]", - "1.2.3.4:5678", - "0.0.0.0:5678", - "127.0.0.1:5678", - "[::]:5678", - "[::1]:5678", - "localhost:5678", - "[::1]:8080", - "[::]:8000", - "[::1]:8000", - "localhost:8000", - "0.0.0.0:4545", - "127.0.0.1:4545", - "999.0.88.1:80" - ]; - let expected = svec![ - "deno.land", - "deno.land:80", - "::", - "::1", - "127.0.0.1", - "[::1]", - "1.2.3.4:5678", - "0.0.0.0:5678", - "127.0.0.1:5678", - "[::]:5678", - "[::1]:5678", - "localhost:5678", - "[::1]:8080", - "[::]:8000", - "[::1]:8000", - "localhost:8000", - "0.0.0.0:4545", - "127.0.0.1:4545", - "999.0.88.1:80" - ]; - let actual = resolve_hosts(entries); - assert_eq!(actual, expected); - } - - #[test] - fn resolve_hosts_expansion() { - let entries = svec![":8080"]; - let expected = svec!["0.0.0.0:8080", "127.0.0.1:8080", "localhost:8080"]; - let actual = resolve_hosts(entries); - assert_eq!(actual, expected); - } - - #[test] - fn resolve_hosts_ipv6() { - let entries = - svec!["::", "::1", "[::1]", "[::]:5678", "[::1]:5678", "::cafe"]; - let expected = - svec!["::", "::1", "[::1]", "[::]:5678", "[::1]:5678", "::cafe"]; - let actual = resolve_hosts(entries); - assert_eq!(actual, expected); - } - - #[test] - #[should_panic] - fn resolve_hosts_ipv6_error1() { - let entries = svec![":::"]; - resolve_hosts(entries); - } - - #[test] - #[should_panic] - fn resolve_hosts_ipv6_error2() { - let entries = svec!["0123:4567:890a:bcde:fg::"]; - resolve_hosts(entries); - } - - #[test] - #[should_panic] - fn resolve_hosts_ipv6_error3() { - let entries = svec!["[::q]:8080"]; - resolve_hosts(entries); - } -} diff --git a/cli/tests/complex_permissions_test.ts b/cli/tests/complex_permissions_test.ts index f4b8e6c730..ad8b5302ca 100644 --- a/cli/tests/complex_permissions_test.ts +++ b/cli/tests/complex_permissions_test.ts @@ -14,11 +14,7 @@ const test: { [key: string]: Function } = { }, netListen(endpoints: string[]): void { endpoints.forEach((endpoint) => { - const index = endpoint.lastIndexOf(":"); - const [hostname, port] = [ - endpoint.substr(0, index), - endpoint.substr(index + 1), - ]; + const [hostname, port] = endpoint.split(":"); const listener = Deno.listen({ transport: "tcp", hostname, @@ -29,11 +25,7 @@ const test: { [key: string]: Function } = { }, async netConnect(endpoints: string[]): Promise { for (const endpoint of endpoints) { - const index = endpoint.lastIndexOf(":"); - const [hostname, port] = [ - endpoint.substr(0, index), - endpoint.substr(index + 1), - ]; + const [hostname, port] = endpoint.split(":"); const listener = await Deno.connect({ transport: "tcp", hostname,