aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml3
-rw-r--r--src/args.rs8
-rw-r--r--tests/serve_request.rs25
4 files changed, 35 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ddcdb74..96fe95f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1753,6 +1753,7 @@ dependencies = [
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"port_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rstest 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"select 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 909ec59..7d687f3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,7 @@ actix-web = "0.7"
simplelog = "0.8"
base64 = "0.12"
percent-encoding = "2.1"
+port_check = "0.1"
htmlescape = "0.3.1"
bytesize = "1.0.0"
nanoid = "0.3"
@@ -53,7 +54,7 @@ assert_cmd = "1.0"
reqwest = { version = "0.10", features = ["blocking"] }
assert_fs = "1.0"
select = "0.4"
-port_check = "0.1"
rstest = "0.6"
+regex = "1.3.9"
pretty_assertions = "0.6"
url = "2.1"
diff --git a/src/args.rs b/src/args.rs
index 7e30ee1..a5bcfea 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -1,6 +1,7 @@
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::path::PathBuf;
use structopt::StructOpt;
+use port_check::free_local_port;
use crate::auth;
use crate::errors::ContextualError;
@@ -170,10 +171,15 @@ pub fn parse_args() -> crate::MiniserveConfig {
let path_explicitly_chosen = args.path.is_some();
+ let port = match args.port {
+ 0 => free_local_port().expect("no free ports available"),
+ _ => args.port,
+ };
+
crate::MiniserveConfig {
verbose: args.verbose,
path: args.path.unwrap_or_else(|| PathBuf::from(".")),
- port: args.port,
+ port,
interfaces,
auth: args.auth,
path_explicitly_chosen,
diff --git a/tests/serve_request.rs b/tests/serve_request.rs
index 5761a65..ad9dc2c 100644
--- a/tests/serve_request.rs
+++ b/tests/serve_request.rs
@@ -9,6 +9,7 @@ use select::node::Node;
use std::process::{Command, Stdio};
use std::thread::sleep;
use std::time::Duration;
+use regex::Regex;
#[rstest]
fn serves_requests_with_no_options(tmpdir: TempDir) -> Result<(), Error> {
@@ -70,6 +71,30 @@ fn serves_requests_with_non_default_port(tmpdir: TempDir, port: u16) -> Result<(
}
#[rstest]
+fn serves_requests_with_randomly_assigned_port(tmpdir: TempDir) -> Result<(), Error> {
+ let mut child = Command::cargo_bin("miniserve")?
+ .arg(tmpdir.path())
+ .arg("-p")
+ .arg("0".to_string())
+ .stdout(Stdio::piped())
+ .spawn()?;
+
+ sleep(Duration::from_secs(1));
+ child.kill()?;
+
+ let output = child.wait_with_output().expect("Failed to read stdout");
+ let all_text = String::from_utf8(output.stdout)?;
+
+ let re = Regex::new(r"http://127.0.0.1:(\d+)").unwrap();
+ let caps = re.captures(all_text.as_str()).unwrap();
+ let port_num = caps.get(1).unwrap().as_str().parse::<u16>().unwrap();
+
+ assert!(port_num > 0);
+
+ Ok(())
+}
+
+#[rstest]
fn serves_requests_custom_index_notice(tmpdir: TempDir, port: u16) -> Result<(), Error> {
let mut child = Command::cargo_bin("miniserve")?
.arg("--index=not.html")