about summary refs log tree commit diff
path: root/pkgs/build-support/node/fetch-npm-deps/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support/node/fetch-npm-deps/src/util.rs')
-rw-r--r--pkgs/build-support/node/fetch-npm-deps/src/util.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/pkgs/build-support/node/fetch-npm-deps/src/util.rs b/pkgs/build-support/node/fetch-npm-deps/src/util.rs
new file mode 100644
index 0000000000000..a165461fa71a2
--- /dev/null
+++ b/pkgs/build-support/node/fetch-npm-deps/src/util.rs
@@ -0,0 +1,45 @@
+use backoff::{retry, ExponentialBackoff};
+use isahc::{
+    config::{CaCertificate, Configurable, RedirectPolicy, SslOption},
+    Body, Request, RequestExt,
+};
+use std::{env, path::Path};
+use url::Url;
+
+pub fn get_url(url: &Url) -> Result<Body, isahc::Error> {
+    let mut request = Request::get(url.as_str()).redirect_policy(RedirectPolicy::Limit(10));
+
+    // Respect SSL_CERT_FILE if environment variable exists
+    if let Ok(ssl_cert_file) = env::var("SSL_CERT_FILE") {
+        if Path::new(&ssl_cert_file).exists() {
+            // When file exists, use it. NIX_SSL_CERT_FILE will still override.
+            request = request.ssl_ca_certificate(CaCertificate::file(ssl_cert_file));
+        } else if env::var("outputHash").is_ok() {
+            // When file does not exist, assume we are downloading in a FOD and
+            // therefore do not need to check certificates, since the output is
+            // already hashed.
+            request = request.ssl_options(SslOption::DANGER_ACCEPT_INVALID_CERTS);
+        }
+    }
+
+    Ok(request.body(())?.send()?.into_body())
+}
+
+pub fn get_url_with_retry(url: &Url) -> Result<Body, 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)
+            }
+        })
+    })
+    .map_err(|backoff_err| match backoff_err {
+        backoff::Error::Permanent(err)
+        | backoff::Error::Transient {
+            err,
+            retry_after: _,
+        } => err,
+    })
+}