Skip to content

Commit 0ecfad5

Browse files
authored
refactor(updater): unset request timeout, add builder setter (#3847)
1 parent f67ae6b commit 0ecfad5

5 files changed

Lines changed: 52 additions & 25 deletions

File tree

.changes/http-timeout-refactor.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
**Breaking change:** The `api::http` timeouts are now represented as `std::time::Duration` instead of a `u64`.

.changes/updater-timeout.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
The updater default timeout is now unset, and the `UpdateBuilder` has a `timeout` setter.

core/tauri/src/api/http.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use std::{collections::HashMap, path::PathBuf, time::Duration};
1919
pub struct ClientBuilder {
2020
/// Max number of redirections to follow.
2121
pub max_redirections: Option<usize>,
22-
/// Connect timeout in seconds for the request.
23-
pub connect_timeout: Option<u64>,
22+
/// Connect timeout for the request.
23+
pub connect_timeout: Option<Duration>,
2424
}
2525

2626
impl ClientBuilder {
@@ -36,10 +36,10 @@ impl ClientBuilder {
3636
self
3737
}
3838

39-
/// Sets the connection timeout in seconds.
39+
/// Sets the connection timeout.
4040
#[must_use]
41-
pub fn connect_timeout(mut self, connect_timeout: u64) -> Self {
42-
self.connect_timeout = Some(connect_timeout);
41+
pub fn connect_timeout(mut self, connect_timeout: Duration) -> Self {
42+
self.connect_timeout.replace(connect_timeout);
4343
self
4444
}
4545

@@ -59,7 +59,7 @@ impl ClientBuilder {
5959
}
6060

6161
if let Some(connect_timeout) = self.connect_timeout {
62-
client_builder = client_builder.connect_timeout(Duration::from_secs(connect_timeout));
62+
client_builder = client_builder.connect_timeout(connect_timeout);
6363
}
6464

6565
let client = client_builder.build()?;
@@ -116,7 +116,7 @@ impl Client {
116116
}
117117

118118
if let Some(timeout) = request.timeout {
119-
request_builder = request_builder.timeout(Duration::from_secs(timeout));
119+
request_builder = request_builder.timeout(timeout);
120120
}
121121

122122
let response = if let Some(body) = request.body {
@@ -163,7 +163,7 @@ impl Client {
163163
}
164164

165165
if let Some(timeout) = request.timeout {
166-
request_builder = request_builder.timeout(Duration::from_secs(timeout));
166+
request_builder = request_builder.timeout(timeout);
167167
}
168168

169169
if let Some(body) = request.body {
@@ -289,7 +289,7 @@ pub struct HttpRequestBuilder {
289289
/// The request body
290290
pub body: Option<Body>,
291291
/// Timeout for the whole request
292-
pub timeout: Option<u64>,
292+
pub timeout: Option<Duration>,
293293
/// The response type (defaults to Json)
294294
pub response_type: Option<ResponseType>,
295295
}
@@ -331,8 +331,8 @@ impl HttpRequestBuilder {
331331

332332
/// Sets the general request timeout.
333333
#[must_use]
334-
pub fn timeout(mut self, timeout: u64) -> Self {
335-
self.timeout = Some(timeout);
334+
pub fn timeout(mut self, timeout: Duration) -> Self {
335+
self.timeout.replace(timeout);
336336
self
337337
}
338338

core/tauri/src/updater/core.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::{
2525
io::{Cursor, Read},
2626
path::{Path, PathBuf},
2727
str::from_utf8,
28+
time::Duration,
2829
};
2930

3031
#[cfg(feature = "updater")]
@@ -210,6 +211,7 @@ pub struct UpdateBuilder<R: Runtime> {
210211
/// The current executable path. Default is automatically extracted.
211212
pub executable_path: Option<PathBuf>,
212213
should_install: Option<Box<dyn FnOnce(&str, &str) -> bool + Send>>,
214+
timeout: Option<Duration>,
213215
}
214216

215217
impl<R: Runtime> fmt::Debug for UpdateBuilder<R> {
@@ -220,6 +222,7 @@ impl<R: Runtime> fmt::Debug for UpdateBuilder<R> {
220222
.field("urls", &self.urls)
221223
.field("target", &self.target)
222224
.field("executable_path", &self.executable_path)
225+
.field("timeout", &self.timeout)
223226
.finish()
224227
}
225228
}
@@ -234,6 +237,7 @@ impl<R: Runtime> UpdateBuilder<R> {
234237
executable_path: None,
235238
current_version: env!("CARGO_PKG_VERSION").into(),
236239
should_install: None,
240+
timeout: None,
237241
}
238242
}
239243

@@ -286,6 +290,11 @@ impl<R: Runtime> UpdateBuilder<R> {
286290
self
287291
}
288292

293+
pub fn timeout(mut self, timeout: Duration) -> Self {
294+
self.timeout.replace(timeout);
295+
self
296+
}
297+
289298
pub async fn build(mut self) -> Result<Update<R>> {
290299
let mut remote_release: Option<RemoteRelease> = None;
291300

@@ -346,15 +355,11 @@ impl<R: Runtime> UpdateBuilder<R> {
346355
let mut headers = HashMap::new();
347356
headers.insert("Accept".into(), "application/json".into());
348357

349-
let resp = ClientBuilder::new()
350-
.build()?
351-
.send(
352-
HttpRequestBuilder::new("GET", &fixed_link)?
353-
.headers(headers)
354-
// wait 20sec for the firewall
355-
.timeout(20),
356-
)
357-
.await;
358+
let mut request = HttpRequestBuilder::new("GET", &fixed_link)?.headers(headers);
359+
if let Some(timeout) = self.timeout {
360+
request = request.timeout(timeout);
361+
}
362+
let resp = ClientBuilder::new().build()?.send(request).await;
358363

359364
// If we got a success, we stop the loop
360365
// and we set our remote_release variable
@@ -417,6 +422,7 @@ impl<R: Runtime> UpdateBuilder<R> {
417422
signature: final_release.signature,
418423
#[cfg(target_os = "windows")]
419424
with_elevated_task: final_release.with_elevated_task,
425+
timeout: self.timeout,
420426
})
421427
}
422428
}
@@ -452,6 +458,8 @@ pub struct Update<R: Runtime> {
452458
/// Optional: Windows only try to use elevated task
453459
/// Default to false
454460
with_elevated_task: bool,
461+
/// Request timeout
462+
timeout: Option<Duration>,
455463
}
456464

457465
impl<R: Runtime> Clone for Update<R> {
@@ -469,6 +477,7 @@ impl<R: Runtime> Clone for Update<R> {
469477
signature: self.signature.clone(),
470478
#[cfg(target_os = "windows")]
471479
with_elevated_task: self.with_elevated_task,
480+
timeout: self.timeout,
472481
}
473482
}
474483
}
@@ -499,10 +508,10 @@ impl<R: Runtime> Update<R> {
499508

500509
let client = ClientBuilder::new().build()?;
501510
// Create our request
502-
let req = HttpRequestBuilder::new("GET", self.download_url.as_str())?
503-
.headers(headers)
504-
// wait 20sec for the firewall
505-
.timeout(20);
511+
let mut req = HttpRequestBuilder::new("GET", self.download_url.as_str())?.headers(headers);
512+
if let Some(timeout) = self.timeout {
513+
req = req.timeout(timeout);
514+
}
506515

507516
let response = client.send(req).await?;
508517

core/tauri/src/updater/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
//!
3535
//! "active" must be a boolean. By default, it's set to false.
3636
//!
37-
//! "endpoints" must be an array. The string `{{target}}` and `{{current_version}}` are automatically replaced in the URL allowing you determine [server-side](#update-server-json-format) if an update is available. If multiple endpoints are specified, the updater will fallback if a server is not responding within the pre-defined timeout.
37+
//! "endpoints" must be an array. The string `{{target}}` and `{{current_version}}` are automatically replaced in the URL allowing you determine [server-side](#update-server-json-format) if an update is available. If multiple endpoints are specified, the updater will fallback if a server is not responding within the optional timeout.
3838
//!
3939
//! "dialog" if present must be a boolean. By default, it's set to true. If enabled, [events](#events) are turned-off as the updater will handle everything. If you need the custom events, you MUST turn off the built-in dialog.
4040
//!
@@ -444,6 +444,8 @@
444444
mod core;
445445
mod error;
446446

447+
use std::time::Duration;
448+
447449
pub use self::error::Error;
448450
/// Alias for [`std::result::Result`] using our own [`Error`].
449451
pub type Result<T> = std::result::Result<T, Error>;
@@ -547,6 +549,12 @@ impl<R: Runtime> UpdateBuilder<R> {
547549
self
548550
}
549551

552+
/// Sets the timeout for the requests to the updater endpoints.
553+
pub fn timeout(mut self, timeout: Duration) -> Self {
554+
self.inner = self.inner.timeout(timeout);
555+
self
556+
}
557+
550558
/// Check if an update is available.
551559
///
552560
/// # Examples

0 commit comments

Comments
 (0)