greentic_setup/http_client.rs
1//! Crate-wide outbound HTTP agent constructors.
2//!
3//! Every outbound call must carry a hard deadline: a stalled remote must
4//! FAIL, never hang the wizard. Bare `ureq::get/post(...)` calls have no
5//! default timeout in ureq 3 — do not add new ones; construct an agent here
6//! instead so the deadline policy stays in one place.
7
8use std::time::Duration;
9
10/// Hard deadline for interactive API calls (OAuth token/device-code
11/// exchanges, Microsoft Graph, provider setup steps). Generous enough for
12/// slow provider backends; small enough that a wedged connection surfaces
13/// as an error while the operator is still watching.
14pub const API_TIMEOUT: Duration = Duration::from_secs(30);
15
16/// Hard deadline for potentially large downloads (bundle archives, tunnel
17/// binaries). Caps the entire transfer, not just connect.
18pub const DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(120);
19
20/// Agent for API calls with ureq's default status handling (non-2xx becomes
21/// `Err(ureq::Error::StatusCode(..))`) — drop-in for bare `ureq::` calls.
22pub fn api_agent() -> ureq::Agent {
23 ureq::Agent::config_builder()
24 .timeout_global(Some(API_TIMEOUT))
25 .build()
26 .new_agent()
27}
28
29/// Agent for API calls where non-2xx statuses are handled as regular
30/// responses (`http_status_as_error(false)`) — drop-in for call sites that
31/// inspect status codes themselves (OAuth polling, Graph error bodies).
32pub fn api_agent_any_status() -> ureq::Agent {
33 ureq::Agent::config_builder()
34 .http_status_as_error(false)
35 .timeout_global(Some(API_TIMEOUT))
36 .build()
37 .new_agent()
38}
39
40/// Agent for downloads: same failure semantics, longer transfer budget.
41pub fn download_agent() -> ureq::Agent {
42 ureq::Agent::config_builder()
43 .timeout_global(Some(DOWNLOAD_TIMEOUT))
44 .build()
45 .new_agent()
46}