diff --git a/compiler-cli/src/http.rs b/compiler-cli/src/http.rs index a759fbc68e8..7852e979da0 100644 --- a/compiler-cli/src/http.rs +++ b/compiler-cli/src/http.rs @@ -4,8 +4,9 @@ use std::sync::OnceLock; use async_trait::async_trait; use gleam_core::{Error, Result}; use http::{Request, Response}; +use reqwest::{Certificate, Client}; -static REQWEST_CLIENT: OnceLock = OnceLock::new(); +static REQWEST_CLIENT: OnceLock = OnceLock::new(); #[derive(Debug)] pub struct HttpClient; @@ -27,7 +28,7 @@ impl gleam_core::io::HttpClient for HttpClient { .try_into() .expect("Unable to convert HTTP request for use by reqwest library"); let mut response = REQWEST_CLIENT - .get_or_init(reqwest::Client::new) + .get_or_init(|| init_client().expect("Unable to create reqwest client")) .execute(request) .await .map_err(Error::http)?; @@ -42,3 +43,22 @@ impl gleam_core::io::HttpClient for HttpClient { .map_err(Error::http) } } + +fn init_client() -> Result { + let certificate_path = std::env::var("GLEAM_CACERTS_PATH") + .map_err(|_| Error::CannotReadCertificate { path: "".into() })?; + let certificate_bytes = + std::fs::read(&certificate_path).map_err(|_| Error::CannotReadCertificate { + path: certificate_path.clone(), + })?; + let certificate = + Certificate::from_pem(&certificate_bytes).map_err(|_| Error::CannotReadCertificate { + path: certificate_path.clone(), + })?; + Client::builder() + .add_root_certificate(certificate) + .build() + .map_err(|_| Error::CannotReadCertificate { + path: certificate_path, + }) +} diff --git a/compiler-core/src/error.rs b/compiler-core/src/error.rs index 5e5a52a1403..9b21c4c19b1 100644 --- a/compiler-core/src/error.rs +++ b/compiler-core/src/error.rs @@ -312,6 +312,9 @@ file_names.iter().map(|x| x.as_str()).join(", "))] wrongfully_allowed_version: SmallVersion, }, + #[error("The certificate at {path} could not be read")] + CannotReadCertificate { path: String }, + #[error("Failed to encrypt data")] FailedToEncrypt { detail: String }, @@ -1398,6 +1401,17 @@ https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-fo }] } + Error::CannotReadCertificate { path } => { + let text = wrap_format!("An error occurred while trying to read the certificate file at: {path}"); + + vec![Diagnostic { + title: "Failed to read certificate".into(), + text, + hint: None, + level: Level::Error, + location: None, + }] + } Error::FailedToEncrypt { detail } => { let text = wrap_format!("A problem was encountered encrypting data.