diff --git a/samply/src/main.rs b/samply/src/main.rs index d7387320b..10378ec9b 100644 --- a/samply/src/main.rs +++ b/samply/src/main.rs @@ -16,7 +16,9 @@ mod shared; use std::ffi::OsStr; use std::fs::File; use std::io::{BufReader, BufWriter}; +use std::net::IpAddr; use std::path::{Path, PathBuf}; +use std::str::FromStr; use std::time::Duration; use clap::{Args, Parser, Subcommand, ValueEnum}; @@ -230,6 +232,10 @@ struct ServerArgs { #[arg(short, long)] no_open: bool, + /// The address to use for the local web server + #[arg(long, default_value = "127.0.0.1")] + address: String, + /// The port to use for the local web server #[arg(short = 'P', long, default_value = "3000+")] port: String, @@ -554,7 +560,21 @@ impl ServerArgs { std::process::exit(1) } }; + + // parse address from string + let address = match IpAddr::from_str(&self.address) { + Ok(addr) => addr, + Err(e) => { + eprintln!( + "Could not parse address as IpAddr, got address {:?}, error: {}", + self.address, e + ); + std::process::exit(1) + } + }; + ServerProps { + address, port_selection, verbose: self.verbose, open_in_browser, diff --git a/samply/src/server.rs b/samply/src/server.rs index 942e6ddfd..9fb0ab443 100644 --- a/samply/src/server.rs +++ b/samply/src/server.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::ffi::OsStr; -use std::net::SocketAddr; +use std::net::{IpAddr, SocketAddr}; use std::ops::Range; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -26,6 +26,7 @@ use crate::shared::ctrl_c::CtrlC; #[derive(Clone, Debug)] pub struct ServerProps { + pub address: IpAddr, pub port_selection: PortSelection, pub verbose: bool, pub open_in_browser: bool, @@ -40,6 +41,7 @@ pub async fn start_server_main( start_server( Some(file), libinfo_map, + props.address, props.port_selection, props.verbose, props.open_in_browser, @@ -70,11 +72,12 @@ impl PortSelection { async fn start_server( profile_filename: Option<&Path>, libinfo_map: HashMap<(String, DebugId), LibraryInfo>, + address: IpAddr, port_selection: PortSelection, verbose: bool, open_in_browser: bool, ) { - let (listener, addr) = make_listener(port_selection).await; + let (listener, addr) = make_listener(address, port_selection).await; let token = generate_token(); let path_prefix = format!("/{token}"); @@ -179,10 +182,10 @@ fn generate_token() -> String { nix_base32::to_nix_base32(&bytes) } -async fn make_listener(port_selection: PortSelection) -> (TcpListener, SocketAddr) { +async fn make_listener(addr: IpAddr, port_selection: PortSelection) -> (TcpListener, SocketAddr) { match port_selection { PortSelection::OnePort(port) => { - let addr = SocketAddr::from(([127, 0, 0, 1], port)); + let addr = SocketAddr::from((addr, port)); match TcpListener::bind(&addr).await { Ok(listener) => (listener, addr), Err(e) => { @@ -194,7 +197,7 @@ async fn make_listener(port_selection: PortSelection) -> (TcpListener, SocketAdd PortSelection::TryMultiple(range) => { let mut error = None; for port in range.clone() { - let addr = SocketAddr::from(([127, 0, 0, 1], port)); + let addr = SocketAddr::from((addr, port)); match TcpListener::bind(&addr).await { Ok(listener) => return (listener, addr), Err(e) => {