aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs91
1 files changed, 43 insertions, 48 deletions
diff --git a/src/main.rs b/src/main.rs
index d34f0aa..9ea784b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
use std::io;
use std::io::Write;
-use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener};
+use std::net::{IpAddr, SocketAddr, TcpListener};
use std::thread;
use std::time::Duration;
@@ -102,23 +102,6 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), ContextualError> {
let inside_config = miniserve_config.clone();
- let interfaces = miniserve_config
- .interfaces
- .iter()
- .map(|&interface| {
- if interface == IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)) {
- // If the interface is 0.0.0.0, we'll change it to 127.0.0.1 so that clicking the link will
- // also work on Windows. Why can't Windows interpret 0.0.0.0?
- "127.0.0.1".to_string()
- } else if interface.is_ipv6() {
- // If the interface is IPv6 then we'll print it with brackets so that it is clickable.
- format!("[{}]", interface)
- } else {
- format!("{}", interface)
- }
- })
- .collect::<Vec<String>>();
-
let canon_path = miniserve_config.path.canonicalize().map_err(|e| {
ContextualError::IoError("Failed to resolve path to be served".to_string(), e)
})?;
@@ -164,37 +147,49 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), ContextualError> {
thread::sleep(Duration::from_millis(500));
}
}
- let mut addresses = String::new();
- for interface in &interfaces {
- if !addresses.is_empty() {
- addresses.push_str(", ");
- }
- let protocol = if miniserve_config.tls_rustls_config.is_some() {
- "https"
- } else {
- "http"
- };
- addresses.push_str(&format!(
- "{}",
- Color::Green
- .paint(format!(
- "{protocol}://{interface}:{port}",
- protocol = protocol,
- interface = &interface,
- port = miniserve_config.port
- ))
- .bold()
- ));
-
- if let Some(random_route) = miniserve_config.clone().random_route {
- addresses.push_str(&format!(
- "{}",
- Color::Green
- .paint(format!("/{random_route}", random_route = random_route,))
- .bold()
- ));
+
+ let addresses = {
+ let (mut ifaces, wildcard): (Vec<_>, Vec<_>) = miniserve_config
+ .interfaces
+ .clone()
+ .into_iter()
+ .partition(|addr| !addr.is_unspecified());
+
+ // Replace wildcard addresses with local interface addresses
+ if !wildcard.is_empty() {
+ let all_ipv4 = wildcard.iter().any(|addr| addr.is_ipv4());
+ let all_ipv6 = wildcard.iter().any(|addr| addr.is_ipv6());
+ ifaces = get_if_addrs::get_if_addrs()
+ .unwrap_or_else(|e| {
+ error!("Failed to get local interface addresses: {}", e);
+ Default::default()
+ })
+ .into_iter()
+ .map(|iface| iface.ip())
+ .filter(|ip| (all_ipv4 && ip.is_ipv4()) || (all_ipv6 && ip.is_ipv6()))
+ .collect();
+ ifaces.sort();
}
- }
+
+ let urls = ifaces
+ .into_iter()
+ .map(|addr| match addr {
+ IpAddr::V4(_) => format!("{}:{}", addr, miniserve_config.port),
+ IpAddr::V6(_) => format!("[{}]:{}", addr, miniserve_config.port),
+ })
+ .map(|addr| match miniserve_config.tls_rustls_config {
+ Some(_) => format!("https://{}", addr),
+ None => format!("http://{}", addr),
+ })
+ .map(|url| match miniserve_config.random_route {
+ Some(ref random_route) => format!("{}/{}", url, random_route),
+ None => url,
+ })
+ .map(|url| Color::Green.paint(url).bold().to_string())
+ .collect::<Vec<_>>();
+
+ urls.join(", ")
+ };
let socket_addresses = miniserve_config
.interfaces