diff --git a/bottlecap/src/http.rs b/bottlecap/src/http.rs index e7dae2623..c969ed6f7 100644 --- a/bottlecap/src/http.rs +++ b/bottlecap/src/http.rs @@ -8,8 +8,8 @@ use bytes::Bytes; use core::time::Duration; use datadog_fips::reqwest_adapter::create_reqwest_client_builder; use std::sync::Arc; -use std::{collections::HashMap, error::Error}; -use tracing::error; +use std::{collections::HashMap, error::Error, fs::File, io::BufReader}; +use tracing::{debug, error}; #[must_use] pub fn get_client(config: &Arc) -> reqwest::Client { @@ -47,6 +47,28 @@ fn build_client(config: &Arc) -> Result { + let cert_count = certs.len(); + for cert in certs { + client = client.add_root_certificate(cert); + } + debug!( + "HTTP | Added {} root certificate(s) from {}", + cert_count, cert_path + ); + } + Err(e) => { + error!( + "Failed to load TLS certificate from {}: {}, continuing without custom cert", + cert_path, e + ); + } + } + } + // This covers DD_PROXY_HTTPS and HTTPS_PROXY if let Some(https_uri) = &config.proxy_https { let proxy = reqwest::Proxy::https(https_uri.clone())?; @@ -56,6 +78,24 @@ fn build_client(config: &Arc) -> Result Result, Box> { + let file = File::open(cert_path)?; + let mut reader = BufReader::new(file); + + // Parse PEM certificates + let certs = rustls_pemfile::certs(&mut reader).collect::, _>>()?; + + if certs.is_empty() { + return Err("No certificates found in file".into()); + } + + // Convert all certificates found in the file + certs + .into_iter() + .map(|cert| reqwest::Certificate::from_der(&cert).map_err(Into::into)) + .collect() +} + pub async fn handler_not_found() -> Response { (StatusCode::NOT_FOUND, "Not Found").into_response() }