From a7ee5ca7c348d33bdfdc1213b6850bcf5c39d6e6 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Fri, 31 Mar 2023 15:03:38 +0200 Subject: [PATCH] fix(cli): look for available ports for built-in dev server, closes #6511 (#6514) Co-authored-by: Lucas Nogueira --- .changes/cli-dev-server-available-port.md | 5 ++ tooling/cli/src/dev.rs | 2 +- tooling/cli/src/helpers/web_dev_server.rs | 59 +++++++++++++++++------ 3 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 .changes/cli-dev-server-available-port.md diff --git a/.changes/cli-dev-server-available-port.md b/.changes/cli-dev-server-available-port.md new file mode 100644 index 000000000..e39a8fba5 --- /dev/null +++ b/.changes/cli-dev-server-available-port.md @@ -0,0 +1,5 @@ +--- +'cli.rs': 'patch' +--- + +Look for available port when using the built-in dev server for static files. diff --git a/tooling/cli/src/dev.rs b/tooling/cli/src/dev.rs index 217c0f139..b3adb3c4e 100644 --- a/tooling/cli/src/dev.rs +++ b/tooling/cli/src/dev.rs @@ -230,7 +230,7 @@ fn command_internal(mut options: Options) -> Result<()> { use crate::helpers::web_dev_server::start_dev_server; if path.exists() { let path = path.canonicalize()?; - let server_url = start_dev_server(path, options.port); + let server_url = start_dev_server(path, options.port)?; let server_url = format!("http://{server_url}"); dev_path = AppUrl::Url(WindowUrl::External(server_url.parse().unwrap())); diff --git a/tooling/cli/src/helpers/web_dev_server.rs b/tooling/cli/src/helpers/web_dev_server.rs index 795d1bcfd..e095f0b3c 100644 --- a/tooling/cli/src/helpers/web_dev_server.rs +++ b/tooling/cli/src/helpers/web_dev_server.rs @@ -30,17 +30,10 @@ struct State { tx: Sender<()>, } -pub fn start_dev_server>(path: P, port: Option) -> SocketAddr { +pub fn start_dev_server>(path: P, port: Option) -> crate::Result { let serve_dir = path.as_ref().to_path_buf(); - let server_url = SocketAddr::new( - Ipv4Addr::new(127, 0, 0, 1).into(), - port.unwrap_or_else(|| { - std::env::var("TAURI_DEV_SERVER_PORT") - .unwrap_or_else(|_| "1430".to_string()) - .parse() - .unwrap() - }), - ); + + let (server_url_tx, server_url_rx) = std::sync::mpsc::channel(); std::thread::spawn(move || { tokio::runtime::Builder::new_current_thread() @@ -91,14 +84,50 @@ pub fn start_dev_server>(path: P, port: Option) -> SocketAdd ws.on_upgrade(|socket| async move { ws_handler(socket, state).await }) }), ); - Server::bind(&server_url) - .serve(router.into_make_service()) - .await - .unwrap(); + + let mut auto_port = false; + let mut port = port.unwrap_or_else(|| { + std::env::var("TAURI_DEV_SERVER_PORT") + .unwrap_or_else(|_| { + auto_port = true; + "1430".to_string() + }) + .parse() + .unwrap() + }); + + let (server, server_url) = loop { + let server_url = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), port); + let server = Server::try_bind(&server_url); + + if !auto_port { + break (server, server_url); + } + + if server.is_ok() { + break (server, server_url); + } + + port += 1; + }; + + match server { + Ok(server) => { + server_url_tx.send(Ok(server_url)).unwrap(); + server.serve(router.into_make_service()).await.unwrap(); + } + Err(e) => { + server_url_tx + .send(Err(anyhow::anyhow!( + "failed to start development server on {server_url}: {e}" + ))) + .unwrap(); + } + } }) }); - server_url + server_url_rx.recv().unwrap() } async fn handler(req: Request, state: Arc) -> impl IntoResponse {