Skip to content

Commit a7ee5ca

Browse files
fix(cli): look for available ports for built-in dev server, closes #6511 (#6514)
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
1 parent ff4ea1e commit a7ee5ca

File tree

3 files changed

+50
-16
lines changed

3 files changed

+50
-16
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'cli.rs': 'patch'
3+
---
4+
5+
Look for available port when using the built-in dev server for static files.

tooling/cli/src/dev.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ fn command_internal(mut options: Options) -> Result<()> {
230230
use crate::helpers::web_dev_server::start_dev_server;
231231
if path.exists() {
232232
let path = path.canonicalize()?;
233-
let server_url = start_dev_server(path, options.port);
233+
let server_url = start_dev_server(path, options.port)?;
234234
let server_url = format!("http://{server_url}");
235235
dev_path = AppUrl::Url(WindowUrl::External(server_url.parse().unwrap()));
236236

tooling/cli/src/helpers/web_dev_server.rs

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,10 @@ struct State {
3030
tx: Sender<()>,
3131
}
3232

33-
pub fn start_dev_server<P: AsRef<Path>>(path: P, port: Option<u16>) -> SocketAddr {
33+
pub fn start_dev_server<P: AsRef<Path>>(path: P, port: Option<u16>) -> crate::Result<SocketAddr> {
3434
let serve_dir = path.as_ref().to_path_buf();
35-
let server_url = SocketAddr::new(
36-
Ipv4Addr::new(127, 0, 0, 1).into(),
37-
port.unwrap_or_else(|| {
38-
std::env::var("TAURI_DEV_SERVER_PORT")
39-
.unwrap_or_else(|_| "1430".to_string())
40-
.parse()
41-
.unwrap()
42-
}),
43-
);
35+
36+
let (server_url_tx, server_url_rx) = std::sync::mpsc::channel();
4437

4538
std::thread::spawn(move || {
4639
tokio::runtime::Builder::new_current_thread()
@@ -91,14 +84,50 @@ pub fn start_dev_server<P: AsRef<Path>>(path: P, port: Option<u16>) -> SocketAdd
9184
ws.on_upgrade(|socket| async move { ws_handler(socket, state).await })
9285
}),
9386
);
94-
Server::bind(&server_url)
95-
.serve(router.into_make_service())
96-
.await
97-
.unwrap();
87+
88+
let mut auto_port = false;
89+
let mut port = port.unwrap_or_else(|| {
90+
std::env::var("TAURI_DEV_SERVER_PORT")
91+
.unwrap_or_else(|_| {
92+
auto_port = true;
93+
"1430".to_string()
94+
})
95+
.parse()
96+
.unwrap()
97+
});
98+
99+
let (server, server_url) = loop {
100+
let server_url = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), port);
101+
let server = Server::try_bind(&server_url);
102+
103+
if !auto_port {
104+
break (server, server_url);
105+
}
106+
107+
if server.is_ok() {
108+
break (server, server_url);
109+
}
110+
111+
port += 1;
112+
};
113+
114+
match server {
115+
Ok(server) => {
116+
server_url_tx.send(Ok(server_url)).unwrap();
117+
server.serve(router.into_make_service()).await.unwrap();
118+
}
119+
Err(e) => {
120+
server_url_tx
121+
.send(Err(anyhow::anyhow!(
122+
"failed to start development server on {server_url}: {e}"
123+
)))
124+
.unwrap();
125+
}
126+
}
98127
})
99128
});
100129

101-
server_url
130+
server_url_rx.recv().unwrap()
102131
}
103132

104133
async fn handler<T>(req: Request<T>, state: Arc<State>) -> impl IntoResponse {

0 commit comments

Comments
 (0)