From cb7ed63a9d5fff1e9790d1e9077d66b162e977db Mon Sep 17 00:00:00 2001 From: Andres Olivares Date: Sun, 3 May 2026 22:25:30 -0400 Subject: [PATCH 1/2] Passing request/response extras to retry_policy.should_retry() --- reqwest-retry/Cargo.toml | 2 +- reqwest-retry/src/middleware.rs | 41 ++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/reqwest-retry/Cargo.toml b/reqwest-retry/Cargo.toml index 9afded0f..22ebe4dc 100644 --- a/reqwest-retry/Cargo.toml +++ b/reqwest-retry/Cargo.toml @@ -21,7 +21,7 @@ async-trait = "0.1.51" futures = "0.3.0" http = "1.0" reqwest = { version = "0.13.1", default-features = false } -retry-policies = "0.5" +retry-policies = { git = "https://github.com/andyolivares/retry-policies.git", branch = "retry_policy_with_extras" } thiserror = "2.0" tracing = { version = "0.1.26", optional = true } diff --git a/reqwest-retry/src/middleware.rs b/reqwest-retry/src/middleware.rs index a8339c1c..b2cd60c5 100644 --- a/reqwest-retry/src/middleware.rs +++ b/reqwest-retry/src/middleware.rs @@ -1,4 +1,6 @@ //! `RetryTransientMiddleware` implements retrying requests on transient errors. +use std::collections::HashMap; +use std::hash::Hash; use std::time::{Duration, SystemTime}; use crate::retryable_strategy::RetryableStrategy; @@ -161,7 +163,9 @@ where if let Some(Retryable::Transient) = self.retryable_strategy.handle(&result) { // If the response failed and the error type was transient // we can safely try to retry the request. - let retry_decision = self.retry_policy.should_retry(start_time, n_past_retries); + let res = result.as_ref().ok(); + let extras = get_extras(&req, res); + let retry_decision = self.retry_policy.should_retry(start_time, n_past_retries, Some(extras)); if let retry_policies::RetryDecision::Retry { execute_after } = retry_decision { let duration = execute_after .duration_since(SystemTime::now()) @@ -201,3 +205,38 @@ where } } } + +fn get_request_extras(request: &reqwest::Request) -> HashMap { + let mut extras = HashMap::new(); + + extras.insert("request:method".to_string(), request.method().to_string()); + extras.insert("request:url".to_string(), request.url().to_string()); + + for (name, value) in request.headers().iter() { + extras.insert(format!("request:header:{}", name), value.to_str().unwrap_or("").to_string()); + } + + extras +} + +fn get_response_extras(response: &reqwest::Response) -> HashMap { + let mut extras = HashMap::new(); + + extras.insert("response:status".to_string(), response.status().to_string()); + + for (name, value) in response.headers().iter() { + extras.insert(format!("response:header:{}", name), value.to_str().unwrap_or("").to_string()); + } + + extras +} + +fn get_extras(request: &reqwest::Request, response: Option<&reqwest::Response>) -> HashMap { + let mut extras = get_request_extras(request); + + if let Some(resp) = response { + extras.extend(get_response_extras(resp)); + } + + extras +} \ No newline at end of file From 58cf1b743482481c2eab87408bf177891a70d2ec Mon Sep 17 00:00:00 2001 From: Andres Olivares Date: Mon, 4 May 2026 00:30:07 -0400 Subject: [PATCH 2/2] Added headers as lower-case strings --- reqwest-retry/src/middleware.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reqwest-retry/src/middleware.rs b/reqwest-retry/src/middleware.rs index b2cd60c5..5e0f16c6 100644 --- a/reqwest-retry/src/middleware.rs +++ b/reqwest-retry/src/middleware.rs @@ -213,7 +213,7 @@ fn get_request_extras(request: &reqwest::Request) -> HashMap { extras.insert("request:url".to_string(), request.url().to_string()); for (name, value) in request.headers().iter() { - extras.insert(format!("request:header:{}", name), value.to_str().unwrap_or("").to_string()); + extras.insert(format!("request:headers:{}", name), value.to_str().unwrap_or("").to_string().to_lowercase()); } extras @@ -225,7 +225,7 @@ fn get_response_extras(response: &reqwest::Response) -> HashMap extras.insert("response:status".to_string(), response.status().to_string()); for (name, value) in response.headers().iter() { - extras.insert(format!("response:header:{}", name), value.to_str().unwrap_or("").to_string()); + extras.insert(format!("response:headers:{}", name), value.to_str().unwrap_or("").to_string().to_lowercase()); } extras