Skip to main content

tt_provider_gemini/
client.rs

1//! HTTP client configuration for the Gemini adapter.
2//!
3//! The client has a connection timeout but intentionally does **not** configure
4//! retries — that responsibility belongs to the `tt-core` retry/backoff layer.
5//! Adapters are retry-unaware by design.
6
7use std::time::Duration;
8
9use reqwest::Client;
10
11/// Configuration supplied to [`build_client`].
12#[derive(Debug, Clone)]
13pub struct ClientConfig {
14    /// Per-read idle timeout: resets on each received chunk, so a long
15    /// streaming response is not cut off, while a stalled connection still
16    /// times out. (Not a total-request cap.) Defaults to 120 s.
17    pub timeout: Duration,
18    /// TCP connection timeout. Defaults to 10 s.
19    pub connect_timeout: Duration,
20}
21
22impl Default for ClientConfig {
23    fn default() -> Self {
24        Self {
25            timeout: Duration::from_secs(120),
26            connect_timeout: Duration::from_secs(10),
27        }
28    }
29}
30
31/// Build a [`reqwest::Client`] with the given configuration.
32///
33/// Uses rustls (no native TLS) and enables gzip decompression. The client is
34/// intended to be created once per [`crate::GeminiProvider`] and reused
35/// across all requests.
36pub fn build_client(cfg: &ClientConfig) -> Result<Client, reqwest::Error> {
37    Client::builder()
38        .read_timeout(cfg.timeout)
39        .connect_timeout(cfg.connect_timeout)
40        // Disable automatic redirects — the provider API should not redirect.
41        .redirect(reqwest::redirect::Policy::none())
42        // Use rustls (consistent with workspace default features).
43        .use_rustls_tls()
44        .gzip(true)
45        .build()
46}