diff --git a/tsp_sdk/src/http_client.rs b/tsp_sdk/src/http_client.rs new file mode 100644 index 0000000..0916496 --- /dev/null +++ b/tsp_sdk/src/http_client.rs @@ -0,0 +1,38 @@ +#[cfg(feature = "resolve")] +use once_cell::sync::OnceCell; + +#[cfg(feature = "resolve")] +#[derive(Debug)] +pub(crate) struct ReqwestClientError { + pub(crate) context: &'static str, + pub(crate) source: reqwest::Error, +} + +#[cfg(feature = "resolve")] +pub(crate) fn reqwest_client() -> Result<&'static reqwest::Client, ReqwestClientError> { + static CLIENT: OnceCell = OnceCell::new(); + + CLIENT.get_or_try_init(|| { + let client = reqwest::Client::builder(); + + #[cfg(feature = "use_local_certificate")] + let client = { + #[cfg(feature = "async")] + tracing::warn!("Using local root CA! (should only be used for local testing)"); + + let cert = + reqwest::Certificate::from_pem(include_bytes!("../../examples/test/root-ca.pem")) + .map_err(|e| ReqwestClientError { + context: "Local root CA", + source: e, + })?; + + client.add_root_certificate(cert) + }; + + client.build().map_err(|e| ReqwestClientError { + context: "Client build error", + source: e, + }) + }) +} diff --git a/tsp_sdk/src/lib.rs b/tsp_sdk/src/lib.rs index d7378be..6c4cb2f 100644 --- a/tsp_sdk/src/lib.rs +++ b/tsp_sdk/src/lib.rs @@ -94,6 +94,8 @@ pub mod crypto; /// Defines several common data structures, traits and error types that are used throughout the project. pub mod definitions; mod error; +#[cfg(feature = "resolve")] +mod http_client; mod store; /// Contains code for handling *verified identifiers* and identities. diff --git a/tsp_sdk/src/transport/http.rs b/tsp_sdk/src/transport/http.rs index 771f4f1..c56a1c4 100644 --- a/tsp_sdk/src/transport/http.rs +++ b/tsp_sdk/src/transport/http.rs @@ -20,23 +20,11 @@ pub(crate) const SCHEME_WS: &str = "ws"; pub(crate) const SCHEME_WSS: &str = "wss"; pub(crate) async fn send_message(tsp_message: &[u8], url: &Url) -> Result<(), TransportError> { - let client = reqwest::Client::builder(); - - #[cfg(feature = "use_local_certificate")] - let cert = { - warn!("Using local root CA! (should only be used for local testing)"); - let cert = include_bytes!("../../../examples/test/root-ca.pem"); - reqwest::Certificate::from_pem(cert).unwrap() - }; - - #[cfg(feature = "use_local_certificate")] - let client = client.add_root_certificate(cert); - let url = url.clone(); + let client = crate::http_client::reqwest_client() + .map_err(|e| TransportError::Http(e.context.to_string(), e.source))?; let response = client - .build() - .map_err(|e| TransportError::Http("Client build error".to_string(), e))? .post(url.clone()) .body(tsp_message.to_vec()) .send() diff --git a/tsp_sdk/src/vid/did/web.rs b/tsp_sdk/src/vid/did/web.rs index 87365af..d2ca814 100644 --- a/tsp_sdk/src/vid/did/web.rs +++ b/tsp_sdk/src/vid/did/web.rs @@ -173,21 +173,10 @@ pub async fn resolve(id: &str, parts: Vec<&str>) -> Result { { let url = resolve_url(&parts)?; - let client = reqwest::Client::builder(); - - #[cfg(feature = "use_local_certificate")] - let cert = { - tracing::warn!("Using local root CA! (should only be used for local testing)"); - reqwest::Certificate::from_pem(include_bytes!("../../../../examples/test/root-ca.pem")) - .unwrap() - }; - - #[cfg(feature = "use_local_certificate")] - let client = client.add_root_certificate(cert); + let client = crate::http_client::reqwest_client() + .map_err(|e| VidError::Http(e.context.to_string(), e.source))?; let response = client - .build() - .map_err(|e| VidError::Http("Client build error".to_string(), e))? .get(url.as_ref()) .send() .await