From 554e2412e0b4a89f527786e67d568d9cf3842d80 Mon Sep 17 00:00:00 2001 From: Lily Foster Date: Tue, 10 Oct 2023 19:40:43 -0400 Subject: [PATCH] prefetch-npm-deps: read url bodies within the retry loop --- .../node/fetch-npm-deps/src/parse/mod.rs | 14 +++------- .../node/fetch-npm-deps/src/util.rs | 28 ++++++++++++------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs b/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs index b37652ffdf82..86e9120de02f 100644 --- a/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs +++ b/pkgs/build-support/node/fetch-npm-deps/src/parse/mod.rs @@ -4,7 +4,7 @@ use rayon::prelude::*; use serde_json::{Map, Value}; use std::{ fs, - io::{self, Read}, + io::Write, process::{Command, Stdio}, }; use tempfile::{tempdir, TempDir}; @@ -106,7 +106,7 @@ impl Package { let specifics = match get_hosted_git_url(&resolved)? { Some(hosted) => { - let mut body = util::get_url_with_retry(&hosted)?; + let body = util::get_url_body_with_retry(&hosted)?; let workdir = tempdir()?; @@ -120,7 +120,7 @@ impl Package { .stdin(Stdio::piped()) .spawn()?; - io::copy(&mut body, &mut cmd.stdin.take().unwrap())?; + cmd.stdin.take().unwrap().write_all(&body)?; let exit = cmd.wait()?; @@ -154,13 +154,7 @@ impl Package { pub fn tarball(&self) -> anyhow::Result> { match &self.specifics { - Specifics::Registry { .. } => { - let mut body = Vec::new(); - - util::get_url_with_retry(&self.url)?.read_to_end(&mut body)?; - - Ok(body) - } + Specifics::Registry { .. } => Ok(util::get_url_body_with_retry(&self.url)?), Specifics::Git { workdir } => Ok(Command::new("tar") .args([ "--sort=name", diff --git a/pkgs/build-support/node/fetch-npm-deps/src/util.rs b/pkgs/build-support/node/fetch-npm-deps/src/util.rs index 7a220f681c0d..7dd928fdc43f 100644 --- a/pkgs/build-support/node/fetch-npm-deps/src/util.rs +++ b/pkgs/build-support/node/fetch-npm-deps/src/util.rs @@ -4,7 +4,7 @@ use isahc::{ Body, Request, RequestExt, }; use serde_json::{Map, Value}; -use std::{env, path::Path}; +use std::{env, io::Read, path::Path}; use url::Url; pub fn get_url(url: &Url) -> Result { @@ -28,7 +28,7 @@ pub fn get_url(url: &Url) -> Result { if let Some(host) = url.host_str() { if let Ok(npm_tokens) = env::var("NIX_NPM_TOKENS") { if let Ok(tokens) = serde_json::from_str::>(&npm_tokens) { - if let Some(token) = tokens.get(host).and_then(|val| val.as_str()) { + if let Some(token) = tokens.get(host).and_then(serde_json::Value::as_str) { request = request.header("Authorization", format!("Bearer {token}")); } } @@ -38,15 +38,23 @@ pub fn get_url(url: &Url) -> Result { Ok(request.body(())?.send()?.into_body()) } -pub fn get_url_with_retry(url: &Url) -> Result { +pub fn get_url_body_with_retry(url: &Url) -> Result, isahc::Error> { retry(ExponentialBackoff::default(), || { - get_url(url).map_err(|err| { - if err.is_network() || err.is_timeout() { - backoff::Error::transient(err) - } else { - backoff::Error::permanent(err) - } - }) + get_url(url) + .and_then(|mut body| { + let mut buf = Vec::new(); + + body.read_to_end(&mut buf)?; + + Ok(buf) + }) + .map_err(|err| { + if err.is_network() || err.is_timeout() { + backoff::Error::transient(err) + } else { + backoff::Error::permanent(err) + } + }) }) .map_err(|backoff_err| match backoff_err { backoff::Error::Permanent(err)