Skip to content

Commit ecac232

Browse files
Make it easier to configure request timeouts
1 parent 73b226f commit ecac232

File tree

3 files changed

+124
-10
lines changed

3 files changed

+124
-10
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66

77
* Logging via the `log` crate. Both clients now emit trace-level logs for HTTP operations, including request/response details and retry attempts.
88

9+
* HTTP request timeout support. Both `ClientBuilder` implementations now provide a `with_request_timeout` method
10+
for configuring request timeouts:
11+
12+
```rust
13+
use std::time::Duration;
14+
use rabbitmq_http_client::api::ClientBuilder;
15+
16+
let client = ClientBuilder::new()
17+
.with_endpoint("http://localhost:15672/api")
18+
.with_basic_auth_credentials("user", "pass")
19+
.with_request_timeout(Duration::from_secs(30))
20+
.build();
21+
```
22+
23+
The timeout applies to the entire request/response cycle.
24+
If a request takes longer than the configured duration, it will be aborted and return a timeout error.
25+
26+
Note that this new setting is ignored if a custom HTTP client is provided via `ClientBuilder#with_client`.
27+
In that case, configure the timeout directly on the custom client instead.
28+
929
## v0.60.0 (Sep 28, 2025)
1030

1131
### Enhancements

src/api/client.rs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ pub struct ClientBuilder<E = &'static str, U = &'static str, P = &'static str> {
5050
endpoint: E,
5151
username: U,
5252
password: P,
53-
client: HttpClient,
53+
client: Option<HttpClient>,
5454
retry_settings: RetrySettings,
55+
request_timeout: Option<Duration>,
5556
}
5657

5758
impl Default for ClientBuilder {
@@ -69,13 +70,13 @@ impl ClientBuilder {
6970
/// Note that the default credentials are [limited to local connections](https://www.rabbitmq.com/docs/access-control)
7071
/// for security reasons.
7172
pub fn new() -> Self {
72-
let client = HttpClient::new();
7373
Self {
7474
endpoint: "http://localhost:15672/api",
7575
username: "guest",
7676
password: "guest",
77-
client,
77+
client: None,
7878
retry_settings: RetrySettings::default(),
79+
request_timeout: None,
7980
}
8081
}
8182
}
@@ -102,6 +103,7 @@ where
102103
password,
103104
client: self.client,
104105
retry_settings: self.retry_settings,
106+
request_timeout: self.request_timeout,
105107
}
106108
}
107109

@@ -119,14 +121,48 @@ where
119121
password: self.password,
120122
client: self.client,
121123
retry_settings: self.retry_settings,
124+
request_timeout: self.request_timeout,
122125
}
123126
}
124127

125128
/// Sets a custom HTTP client.
126129
///
127130
/// Use a custom HTTP client to configure custom timeouts, proxy settings, TLS configuration.
131+
///
132+
/// Note: If you provide a custom client, the timeout set via [`with_request_timeout`]
133+
/// will be ignored. Configure timeouts directly on your custom client instead.
128134
pub fn with_client(self, client: HttpClient) -> Self {
129-
ClientBuilder { client, ..self }
135+
ClientBuilder {
136+
client: Some(client),
137+
..self
138+
}
139+
}
140+
141+
/// Sets the request timeout for HTTP operations.
142+
///
143+
/// This timeout applies to the entire request/response cycle, including connection establishment,
144+
/// request transmission, and response receipt. If a request takes longer than this duration,
145+
/// it will be aborted and return a timeout error.
146+
///
147+
/// **Important**: this setting is ignored if a custom HTTP client is used via [`with_client`].
148+
/// In that case, configure the timeout on the custom client instead.
149+
///
150+
/// # Example
151+
/// ```rust
152+
/// use std::time::Duration;
153+
/// use rabbitmq_http_client::api::ClientBuilder;
154+
///
155+
/// let client = ClientBuilder::new()
156+
/// .with_endpoint("http://localhost:15672/api")
157+
/// .with_basic_auth_credentials("user", "password")
158+
/// .with_request_timeout(Duration::from_secs(30))
159+
/// .build();
160+
/// ```
161+
pub fn with_request_timeout(self, timeout: Duration) -> Self {
162+
ClientBuilder {
163+
request_timeout: Some(timeout),
164+
..self
165+
}
130166
}
131167

132168
/// Sets retry settings for HTTP requests. See [`RetrySettings`].
@@ -143,8 +179,19 @@ where
143179
///
144180
/// This consumes the `ClientBuilder`.
145181
pub fn build(self) -> Client<E, U, P> {
182+
let client = match self.client {
183+
Some(c) => c,
184+
None => {
185+
let mut builder = HttpClient::builder();
186+
if let Some(timeout) = self.request_timeout {
187+
builder = builder.timeout(timeout);
188+
}
189+
builder.build().unwrap()
190+
}
191+
};
192+
146193
Client::from_http_client_with_retry(
147-
self.client,
194+
client,
148195
self.endpoint,
149196
self.username,
150197
self.password,

src/blocking_api/client.rs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ pub struct ClientBuilder<E = &'static str, U = &'static str, P = &'static str> {
4949
endpoint: E,
5050
username: U,
5151
password: P,
52-
client: HttpClient,
52+
client: Option<HttpClient>,
5353
retry_settings: RetrySettings,
54+
request_timeout: Option<Duration>,
5455
}
5556

5657
impl Default for ClientBuilder {
@@ -68,13 +69,13 @@ impl ClientBuilder {
6869
/// Note that the default credentials are [limited to local connections](https://www.rabbitmq.com/docs/access-control)
6970
/// for security reasons.
7071
pub fn new() -> Self {
71-
let client = HttpClient::new();
7272
Self {
7373
endpoint: "http://localhost:15672/api",
7474
username: "guest",
7575
password: "guest",
76-
client,
76+
client: None,
7777
retry_settings: RetrySettings::default(),
78+
request_timeout: None,
7879
}
7980
}
8081
}
@@ -105,6 +106,7 @@ where
105106
password,
106107
client: self.client,
107108
retry_settings: self.retry_settings,
109+
request_timeout: self.request_timeout,
108110
}
109111
}
110112

@@ -122,14 +124,48 @@ where
122124
password: self.password,
123125
client: self.client,
124126
retry_settings: self.retry_settings,
127+
request_timeout: self.request_timeout,
125128
}
126129
}
127130

128131
/// Sets a custom HTTP client.
129132
///
130133
/// Use a custom HTTP client to configure custom timeouts, proxy settings, TLS configuration.
134+
///
135+
/// Note: If you provide a custom client, the timeout set via [`with_request_timeout`]
136+
/// will be ignored. Configure timeouts directly on your custom client instead.
131137
pub fn with_client(self, client: HttpClient) -> Self {
132-
ClientBuilder { client, ..self }
138+
ClientBuilder {
139+
client: Some(client),
140+
..self
141+
}
142+
}
143+
144+
/// Sets the request timeout for HTTP operations.
145+
///
146+
/// This timeout applies to the entire request/response cycle, including connection establishment,
147+
/// request transmission, and response receipt. If a request takes longer than this duration,
148+
/// it will be aborted and return a timeout error.
149+
///
150+
/// **Important**: this setting is ignored if a custom HTTP client is used via [`with_client`].
151+
/// In that case, configure the timeout on the custom client instead.
152+
///
153+
/// # Example
154+
/// ```rust
155+
/// use std::time::Duration;
156+
/// use rabbitmq_http_client::blocking_api::ClientBuilder;
157+
///
158+
/// let client = ClientBuilder::new()
159+
/// .with_endpoint("http://localhost:15672/api")
160+
/// .with_basic_auth_credentials("user", "password")
161+
/// .with_request_timeout(Duration::from_secs(30))
162+
/// .build();
163+
/// ```
164+
pub fn with_request_timeout(self, timeout: Duration) -> Self {
165+
ClientBuilder {
166+
request_timeout: Some(timeout),
167+
..self
168+
}
133169
}
134170

135171
/// Sets retry settings for HTTP requests. See [`RetrySettings`].
@@ -146,8 +182,19 @@ where
146182
///
147183
/// This consumes the `ClientBuilder`.
148184
pub fn build(self) -> Client<E, U, P> {
185+
let client = match self.client {
186+
Some(c) => c,
187+
None => {
188+
let mut builder = HttpClient::builder();
189+
if let Some(timeout) = self.request_timeout {
190+
builder = builder.timeout(timeout);
191+
}
192+
builder.build().unwrap()
193+
}
194+
};
195+
149196
Client::from_http_client_with_retry(
150-
self.client,
197+
client,
151198
self.endpoint,
152199
self.username,
153200
self.password,

0 commit comments

Comments
 (0)