Skip to content

Commit 8ab15d5

Browse files
committed
feat!(client): expose whether a connection is reused from the pool
This introduces a new type `ErrorConnectInfo` that contains information about connection pool as well as transport-related data. This new type can now be obtained from the `Error::connect_info()` method, which means that this is a breaking change as the return type from the method has changed. That said, all information that was available on the previous return type is available on the new type through various getter methods.
1 parent df55aba commit 8ab15d5

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

Diff for: src/client/legacy/client.rs

+41-9
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub struct Error {
5757
kind: ErrorKind,
5858
source: Option<Box<dyn StdError + Send + Sync>>,
5959
#[cfg(any(feature = "http1", feature = "http2"))]
60-
connect_info: Option<Connected>,
60+
connect_info: Option<ErroredConnectInfo>,
6161
}
6262

6363
#[derive(Debug)]
@@ -71,6 +71,34 @@ enum ErrorKind {
7171
SendRequest,
7272
}
7373

74+
/// Extra information about a failed connection.
75+
pub struct ErroredConnectInfo {
76+
conn_info: Connected,
77+
is_reused: bool,
78+
}
79+
80+
impl ErroredConnectInfo {
81+
/// Determines if the connected transport is to an HTTP proxy.
82+
pub fn is_proxied(&self) -> bool {
83+
self.conn_info.is_proxied()
84+
}
85+
86+
/// Copies the extra connection information into an `Extensions` map.
87+
pub fn get_extras(&self, extensions: &mut http::Extensions) {
88+
self.conn_info.get_extras(extensions);
89+
}
90+
91+
/// Determines if the connected transport negotiated HTTP/2 as its next protocol.
92+
pub fn is_negotiated_h2(&self) -> bool {
93+
self.conn_info.is_negotiated_h2()
94+
}
95+
96+
/// Determines if the connection is a reused one from the connection pool.
97+
pub fn is_reused(&self) -> bool {
98+
self.is_reused
99+
}
100+
}
101+
74102
macro_rules! e {
75103
($kind:ident) => {
76104
Error {
@@ -282,7 +310,7 @@ where
282310
if req.version() == Version::HTTP_2 {
283311
warn!("Connection is HTTP/1, but request requires HTTP/2");
284312
return Err(TrySendError::Nope(
285-
e!(UserUnsupportedVersion).with_connect_info(pooled.conn_info.clone()),
313+
e!(UserUnsupportedVersion).with_connect_info(&pooled),
286314
));
287315
}
288316

@@ -317,14 +345,12 @@ where
317345
Err(mut err) => {
318346
return if let Some(req) = err.take_message() {
319347
Err(TrySendError::Retryable {
320-
error: e!(Canceled, err.into_error())
321-
.with_connect_info(pooled.conn_info.clone()),
348+
error: e!(Canceled, err.into_error()).with_connect_info(&pooled),
322349
req,
323350
})
324351
} else {
325352
Err(TrySendError::Nope(
326-
e!(SendRequest, err.into_error())
327-
.with_connect_info(pooled.conn_info.clone()),
353+
e!(SendRequest, err.into_error()).with_connect_info(&pooled),
328354
))
329355
}
330356
}
@@ -1619,14 +1645,20 @@ impl Error {
16191645

16201646
/// Returns the info of the client connection on which this error occurred.
16211647
#[cfg(any(feature = "http1", feature = "http2"))]
1622-
pub fn connect_info(&self) -> Option<&Connected> {
1648+
pub fn connect_info(&self) -> Option<&ErroredConnectInfo> {
16231649
self.connect_info.as_ref()
16241650
}
16251651

16261652
#[cfg(any(feature = "http1", feature = "http2"))]
1627-
fn with_connect_info(self, connect_info: Connected) -> Self {
1653+
fn with_connect_info<B>(self, pooled: &pool::Pooled<PoolClient<B>, PoolKey>) -> Self
1654+
where
1655+
B: Send + 'static,
1656+
{
16281657
Self {
1629-
connect_info: Some(connect_info),
1658+
connect_info: Some(ErroredConnectInfo {
1659+
conn_info: pooled.conn_info.clone(),
1660+
is_reused: pooled.is_reused(),
1661+
}),
16301662
..self
16311663
}
16321664
}

0 commit comments

Comments
 (0)