diff options
| author | Marcus Michaels <marcusmmichaels@gmail.com> | 2026-02-18 12:29:08 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-18 13:29:08 +0100 |
| commit | 928708097435245d28c34d424da555b6850908d5 (patch) | |
| tree | 3b4926d20d4063d940bd90d9bc3f3fae5cdd0991 /src | |
| parent | fix grid crashes on invalid state (#4718) (diff) | |
| download | sl0ppij-928708097435245d28c34d424da555b6850908d5.tar.gz sl0ppij-928708097435245d28c34d424da555b6850908d5.tar.xz sl0ppij-928708097435245d28c34d424da555b6850908d5.zip | |
fix: add --timeout flag to zellij web --status (#4706)
* feat: add --timeout flag to zellij web --status
The HTTP client for checking web server status didn't have a timeout configured. This could cause the CLI to hang indefinitely if the server was unreachable, so I've added a 30-second default timeout and lets users override it with `--timeout <seconds>` when running `zellij web --status`. For example:
```
zellij web --status --timeout 60
```
* Update web timeout to work with --status (and add some tests to make sure everything works as expected)
Diffstat (limited to 'src')
| -rw-r--r-- | src/commands.rs | 17 | ||||
| -rw-r--r-- | src/main.rs | 2 | ||||
| -rw-r--r-- | src/tests/cli.rs | 69 | ||||
| -rw-r--r-- | src/tests/mod.rs | 1 |
4 files changed, 85 insertions, 4 deletions
diff --git a/src/commands.rs b/src/commands.rs index 898c461b..e1c4bbc8 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -323,10 +323,18 @@ pub(crate) fn list_auth_tokens() -> Result<Vec<String>, String> { std::process::exit(2); } +/// Default timeout for web server status check (in seconds) +pub const DEFAULT_WEB_SERVER_STATUS_TIMEOUT_SECS: u64 = 30; + #[cfg(feature = "web_server_capability")] -pub(crate) fn web_server_status(web_server_base_url: &str) -> Result<String, String> { +pub(crate) fn web_server_status( + web_server_base_url: &str, + timeout_secs: Option<u64>, +) -> Result<String, String> { + let timeout = + Duration::from_secs(timeout_secs.unwrap_or(DEFAULT_WEB_SERVER_STATUS_TIMEOUT_SECS)); let http_client = HttpClient::builder() - // TODO: timeout? + .timeout(timeout) .redirect_policy(RedirectPolicy::Follow) .build() .map_err(|e| e.to_string())?; @@ -346,7 +354,10 @@ pub(crate) fn web_server_status(web_server_base_url: &str) -> Result<String, Str } #[cfg(not(feature = "web_server_capability"))] -pub(crate) fn web_server_status(_web_server_base_url: &str) -> Result<String, String> { +pub(crate) fn web_server_status( + _web_server_base_url: &str, + _timeout_secs: Option<u64>, +) -> Result<String, String> { log::error!( "This version of Zellij was compiled without web server support, cannot get web server status!" ); diff --git a/src/main.rs b/src/main.rs index 2ff60a09..c5d1fbdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -323,7 +323,7 @@ fn main() { let config_options = commands::get_config_options_from_cli_args(&opts) .expect("Can't find config options"); let web_server_base_url = web_server_base_url_from_config(config_options); - match commands::web_server_status(&web_server_base_url) { + match commands::web_server_status(&web_server_base_url, web_opts.timeout) { Ok(version) => { let version = version.trim(); println!( diff --git a/src/tests/cli.rs b/src/tests/cli.rs new file mode 100644 index 00000000..95864d56 --- /dev/null +++ b/src/tests/cli.rs @@ -0,0 +1,69 @@ +use clap::Parser; +use zellij_utils::cli::{CliArgs, Command}; + +#[test] +fn web_cli_status_alone_works() { + let args = CliArgs::try_parse_from(["zellij", "web", "--status"]); + assert!(args.is_ok()); + if let Ok(CliArgs { + command: Some(Command::Web(web)), + .. + }) = args + { + assert!(web.status); + assert!(web.timeout.is_none()); + } else { + panic!("Expected Web command"); + } +} + +#[test] +fn web_cli_status_with_timeout_works() { + let args = CliArgs::try_parse_from(["zellij", "web", "--status", "--timeout", "5"]); + assert!(args.is_ok()); + if let Ok(CliArgs { + command: Some(Command::Web(web)), + .. + }) = args + { + assert!(web.status); + assert_eq!(web.timeout, Some(5)); + } else { + panic!("Expected Web command"); + } +} + +#[test] +fn web_cli_timeout_with_status_works() { + // Test with --timeout before --status (order shouldn't matter) + let args = CliArgs::try_parse_from(["zellij", "web", "--timeout", "10", "--status"]); + assert!(args.is_ok()); + if let Ok(CliArgs { + command: Some(Command::Web(web)), + .. + }) = args + { + assert!(web.status); + assert_eq!(web.timeout, Some(10)); + } else { + panic!("Expected Web command"); + } +} + +#[test] +fn web_cli_timeout_without_status_fails() { + let args = CliArgs::try_parse_from(["zellij", "web", "--timeout", "5"]); + assert!(args.is_err()); +} + +#[test] +fn web_cli_status_with_start_fails() { + let args = CliArgs::try_parse_from(["zellij", "web", "--status", "--start"]); + assert!(args.is_err()); +} + +#[test] +fn web_cli_status_with_stop_fails() { + let args = CliArgs::try_parse_from(["zellij", "web", "--status", "--stop"]); + assert!(args.is_err()); +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 08734975..cf2554ef 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1 +1,2 @@ +pub mod cli; pub mod e2e; |
