net: retry flaky archive fetches and pin index downloads via by-hash
Busy mirrors and CDNs routinely break bulk fetches: pooled keep-alive
connections get closed remotely ('error sending request'), downloads are
cut short (surfacing as bogus checksum mismatches), and index generations
momentarily drift from the Release file fetched moments before.
- shared client: short idle-pool timeout and TCP keepalive, and a
bounded-retry GET helper now used for index, Release, keyring and
Launchpad fetches (previously reqwest::get, which has no timeouts)
- downloads: retry the whole download, and check the content length so
truncation is reported as such instead of a checksum mismatch
- sources index: on a checksum mismatch against the Release file, retry
pinned to the exact listed generation via Debian's by-hash mechanism;
body-read errors are retried and reported per component instead of
aborting the whole lookup
This commit is contained in:
+4
-4
@@ -137,7 +137,7 @@ impl ChecksumKind {
|
||||
}
|
||||
|
||||
/// Human-readable algorithm name, for error messages
|
||||
fn name(self) -> &'static str {
|
||||
pub fn name(self) -> &'static str {
|
||||
match self {
|
||||
ChecksumKind::Md5 => "MD5",
|
||||
ChecksumKind::Sha1 => "SHA-1",
|
||||
@@ -782,7 +782,7 @@ pub async fn verify_suite(
|
||||
/// GET a URL, returning None on any HTTP error, non-success status, or body
|
||||
/// read failure (Release files are probed, so absence is a normal outcome)
|
||||
async fn fetch_optional(url: &str) -> Option<Vec<u8>> {
|
||||
match reqwest::get(url).await {
|
||||
match crate::distro_info::http_get_retried(url).await {
|
||||
Ok(response) if response.status().is_success() => match response.bytes().await {
|
||||
Ok(bytes) => return Some(bytes.to_vec()),
|
||||
Err(e) => debug!("Reading the body of '{url}' failed: {e}"),
|
||||
@@ -811,7 +811,7 @@ async fn fetch_keyring_cached(url: &str) -> Result<Vec<u8>, Box<dyn Error + Send
|
||||
return Ok(cached.clone());
|
||||
}
|
||||
|
||||
let response = reqwest::get(url).await?;
|
||||
let response = crate::distro_info::http_get_retried(url).await?;
|
||||
if !response.status().is_success() {
|
||||
return Err(format!(
|
||||
"downloading keyring from '{url}' failed with HTTP {}",
|
||||
@@ -887,7 +887,7 @@ pub async fn ppa_keyring_bytes(
|
||||
}
|
||||
|
||||
let api_url = format!("https://api.launchpad.net/1.0/~{owner}/+archive/ubuntu/{name}");
|
||||
let response = reqwest::get(&api_url).await?;
|
||||
let response = crate::distro_info::http_get_retried(&api_url).await?;
|
||||
if !response.status().is_success() {
|
||||
return Err(format!(
|
||||
"querying the Launchpad API for the signing key of PPA \
|
||||
|
||||
Reference in New Issue
Block a user