diff --git a/src/cli.rs b/src/cli.rs index b55dc18a5e..1329edff4d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,3 +1,4 @@ +use std::net::IpAddr; use std::path::PathBuf; use clap::{Parser, Subcommand}; @@ -54,7 +55,7 @@ pub enum Command { Serve { /// Interface to bind on #[clap(short = 'i', long, default_value = "127.0.0.1")] - interface: String, + interface: IpAddr, /// Which port to use #[clap(short = 'p', long, default_value_t = 1111)] @@ -70,8 +71,8 @@ pub enum Command { force: bool, /// Changes the base_url - #[clap(short = 'u', long, default_value = "127.0.0.1")] - base_url: String, + #[clap(short = 'u', long)] + base_url: Option, /// Include drafts when loading the site #[clap(long)] diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 2f2f718e3e..74e42f8796 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -24,7 +24,7 @@ use std::cell::Cell; use std::fs::read_dir; use std::future::IntoFuture; -use std::net::{SocketAddrV4, TcpListener}; +use std::net::{IpAddr, SocketAddr, TcpListener}; use std::path::{Path, PathBuf, MAIN_SEPARATOR}; use std::sync::mpsc::channel; use std::sync::Mutex; @@ -321,20 +321,29 @@ fn rebuild_done_handling(broadcaster: &Sender, res: Result<()>, reload_path: &st #[allow(clippy::too_many_arguments)] fn create_new_site( root_dir: &Path, - interface: &str, + interface: IpAddr, interface_port: u16, output_dir: Option<&Path>, force: bool, - base_url: &str, + base_url: Option<&str>, config_file: &Path, include_drafts: bool, - no_port_append: bool, + mut no_port_append: bool, ws_port: Option, -) -> Result<(Site, String)> { +) -> Result<(Site, SocketAddr)> { SITE_CONTENT.write().unwrap().clear(); let mut site = Site::new(root_dir, config_file)?; - let address = format!("{}:{}", interface, interface_port); + let address = SocketAddr::new(interface, interface_port); + + // if no base URL provided, use socket address + let base_url = base_url.map_or_else( + || { + no_port_append = true; + address.to_string() + }, + |u| u.to_string(), + ); let base_url = if base_url == "/" { String::from("/") @@ -381,11 +390,11 @@ fn create_new_site( #[allow(clippy::too_many_arguments)] pub fn serve( root_dir: &Path, - interface: &str, + interface: IpAddr, interface_port: u16, output_dir: Option<&Path>, force: bool, - base_url: &str, + base_url: Option<&str>, config_file: &Path, open: bool, include_drafts: bool, @@ -394,7 +403,7 @@ pub fn serve( utc_offset: UtcOffset, ) -> Result<()> { let start = Instant::now(); - let (mut site, address) = create_new_site( + let (mut site, bind_address) = create_new_site( root_dir, interface, interface_port, @@ -409,12 +418,8 @@ pub fn serve( messages::report_elapsed_time(start); // Stop right there if we can't bind to the address - let bind_address: SocketAddrV4 = match address.parse() { - Ok(a) => a, - Err(_) => return Err(anyhow!("Invalid address: {}.", address)), - }; if (TcpListener::bind(bind_address)).is_err() { - return Err(anyhow!("Cannot start server on address {}.", address)); + return Err(anyhow!("Cannot start server on address {}.", bind_address)); } let config_path = PathBuf::from(config_file); @@ -466,8 +471,6 @@ pub fn serve( let static_root = output_path.clone(); let broadcaster = { thread::spawn(move || { - let addr = address.parse().unwrap(); - let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() @@ -484,11 +487,11 @@ pub fn serve( } }); - let server = Server::bind(&addr).serve(make_service); + let server = Server::bind(&bind_address).serve(make_service); - println!("Web server is available at http://{}\n", &address); + println!("Web server is available at http://{}\n", bind_address); if open { - if let Err(err) = open::that(format!("http://{}", &address)) { + if let Err(err) = open::that(format!("http://{}", bind_address)) { eprintln!("Failed to open URL in your browser: {}", err); } } diff --git a/src/main.rs b/src/main.rs index 59bc80df5c..48e95b9693 100644 --- a/src/main.rs +++ b/src/main.rs @@ -102,11 +102,11 @@ fn main() { console::info("Building site..."); if let Err(e) = cmd::serve( &root_dir, - &interface, + interface, port, output_dir.as_deref(), force, - &base_url, + base_url.as_deref(), &config_file, open, drafts,