Merge: ureq 3.4.2 + bounded reply body (supersedes Dependabot #12)

This commit is contained in:
Matthew Jackson
2026-09-20 20:15:19 -07:00
2 changed files with 22 additions and 2 deletions
Generated
+2 -2
View File
@@ -946,9 +946,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]] [[package]]
name = "ureq" name = "ureq"
version = "3.4.0" version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d" checksum = "9a7ac20be9b7726e0bbdbf974c059676d9acb1cd414961f570a4e8231cacd7fc"
dependencies = [ dependencies = [
"base64", "base64",
"cookie_store", "cookie_store",
+20
View File
@@ -287,6 +287,10 @@ fn hardened_agent(pinned: Vec<SocketAddr>) -> ureq::Agent {
.max_redirects(0) .max_redirects(0)
.timeout_connect(Some(Duration::from_secs(10))) .timeout_connect(Some(Duration::from_secs(10)))
.timeout_recv_response(Some(Duration::from_secs(TIMEOUT_SECS))) .timeout_recv_response(Some(Duration::from_secs(TIMEOUT_SECS)))
// Since ureq 3.4.1 (#1194) recv_response bounds only the HEADERS; without
// a body deadline a stalled reply hangs the POST forever. The JSON key
// answer arrives in one read, so a TOTAL cap is the right shape here.
.timeout_recv_body(Some(Duration::from_secs(TIMEOUT_SECS)))
.build(); .build();
// `with_parts`, never `new_with_config` — see [`PinnedResolver`]. // `with_parts`, never `new_with_config` — see [`PinnedResolver`].
ureq::Agent::with_parts(config, DefaultConnector::new(), PinnedResolver(pinned)) ureq::Agent::with_parts(config, DefaultConnector::new(), PinnedResolver(pinned))
@@ -917,6 +921,22 @@ mod tests {
); );
} }
// The POST reply body has its own deadline, not just the headers: ureq
// 3.4.1+ recv_response covers headers only, so without recv_body a stalled
// reply would hang the key request forever.
#[test]
fn the_reply_body_read_is_bounded_not_only_the_headers() {
let agent = hardened_agent(Vec::new());
let t = agent.config().timeouts();
assert_eq!(
t.recv_body,
Some(Duration::from_secs(TIMEOUT_SECS)),
"ureq 3.4.1+ recv_response covers headers only; without recv_body the \
reply read has no deadline at all"
);
assert_eq!(t.recv_response, Some(Duration::from_secs(TIMEOUT_SECS)));
}
#[test] #[test]
fn resolve_and_guard_accepts_public_literal() { fn resolve_and_guard_accepts_public_literal() {
// Public numeric hosts resolve without DNS — must be accepted. // Public numeric hosts resolve without DNS — must be accepted.