diff --git a/bound/kt/src/test/kotlin/web5/sdk/vc/VerifiableCredentialTest.kt b/bound/kt/src/test/kotlin/web5/sdk/vc/VerifiableCredentialTest.kt index d708ea9e..caf0f4dd 100644 --- a/bound/kt/src/test/kotlin/web5/sdk/vc/VerifiableCredentialTest.kt +++ b/bound/kt/src/test/kotlin/web5/sdk/vc/VerifiableCredentialTest.kt @@ -292,7 +292,7 @@ class VerifiableCredentialTest { VerifiableCredential.create(ISSUER, CREDENTIAL_SUBJECT, options) } - assertTrue(exception.message.contains("get request failed")) + assertTrue(exception.message.contains("error sending request")) } @Test @@ -322,7 +322,7 @@ class VerifiableCredentialTest { VerifiableCredential.create(ISSUER, CREDENTIAL_SUBJECT, options) } - assertTrue(exception.message.contains("http error status code 500")) + assertTrue(exception.message.contains("failed to resolve status code 500")) mockWebServer.shutdown() } @@ -355,7 +355,7 @@ class VerifiableCredentialTest { VerifiableCredential.create(ISSUER, CREDENTIAL_SUBJECT, options) } - assertTrue(exception.message.contains("failed to parse json")) + assertTrue(exception.message.contains("expected value at line")) mockWebServer.shutdown() } @@ -1034,7 +1034,7 @@ class VerifiableCredentialTest { VerifiableCredential.fromVcJwt(vcJwtWithInvalidUrl, true) } - assertTrue(exception.message.contains("get request failed")) + assertTrue(exception.message.contains("error sending request")) } @Test @@ -1054,7 +1054,7 @@ class VerifiableCredentialTest { VerifiableCredential.fromVcJwt(vcJwtAtPort, true) } - assertTrue(exception.message.contains("http error status code 500")) + assertTrue(exception.message.contains("failed to resolve status code 500")) mockWebServer.shutdown() } @@ -1077,7 +1077,7 @@ class VerifiableCredentialTest { VerifiableCredential.fromVcJwt(vcJwtAtPort, true) } - assertTrue(exception.message.contains("failed to parse json")) + assertTrue(exception.message.contains("expected value at line")) mockWebServer.shutdown() } diff --git a/crates/http-std/Cargo.toml b/crates/http-std/Cargo.toml index 6dbf2ecd..9780285b 100644 --- a/crates/http-std/Cargo.toml +++ b/crates/http-std/Cargo.toml @@ -8,7 +8,11 @@ license-file.workspace = true [dependencies] lazy_static = { workspace = true } -rustls = { version = "0.23.13", default-features = false, features = ["std", "tls12"] } +reqwest = { version = "0.12.7", features = ["blocking"] } +rustls = { version = "0.23.13", default-features = false, features = [ + "std", + "tls12", +] } rustls-native-certs = "0.8.0" thiserror = { workspace = true } -url = "2.5.0" \ No newline at end of file +url = "2.5.0" diff --git a/crates/http-std/src/error.rs b/crates/http-std/src/error.rs index 4e83f51a..86b0ab73 100644 --- a/crates/http-std/src/error.rs +++ b/crates/http-std/src/error.rs @@ -1,3 +1,5 @@ +use reqwest::Error as ReqwestError; + #[derive(thiserror::Error, Debug, Clone, PartialEq)] pub enum Error { #[error("unknown error {0}")] @@ -8,6 +10,15 @@ pub enum Error { Network(String), #[error("response error {0}")] Response(String), + + #[error("reqwest error {0}")] + Reqwest(String), +} + +impl From for Error { + fn from(err: ReqwestError) -> Self { + Error::Reqwest(err.to_string()) + } } pub type Result = std::result::Result; diff --git a/crates/http-std/src/lib.rs b/crates/http-std/src/lib.rs index 97b24d68..17a4ca5f 100644 --- a/crates/http-std/src/lib.rs +++ b/crates/http-std/src/lib.rs @@ -1,6 +1,7 @@ mod client; mod default_client; mod error; +mod reqwest_client; use lazy_static::lazy_static; use std::sync::{Arc, Mutex}; @@ -9,7 +10,8 @@ pub use client::{Client, FetchOptions, Method, Response}; pub use error::{Error, Result}; lazy_static! { - static ref CLIENT: Mutex> = Mutex::new(Arc::new(default_client::DefaultClient)); + static ref CLIENT: Mutex> = + Mutex::new(Arc::new(reqwest_client::ReqwestClient::new())); } pub fn set_client(client: Arc) { diff --git a/crates/http-std/src/reqwest_client.rs b/crates/http-std/src/reqwest_client.rs new file mode 100644 index 00000000..e9391c10 --- /dev/null +++ b/crates/http-std/src/reqwest_client.rs @@ -0,0 +1,62 @@ +use crate::{Client, FetchOptions, Method, Response, Result}; +use reqwest::blocking::Client as ReqwestBlockingClient; +use reqwest::header::HeaderMap; +use std::collections::HashMap; +use std::convert::TryFrom; + +pub struct ReqwestClient { + client: ReqwestBlockingClient, +} + +impl ReqwestClient { + pub fn new() -> Self { + ReqwestClient { + client: ReqwestBlockingClient::new(), + } + } +} + +impl Client for ReqwestClient { + fn fetch(&self, url: &str, options: Option) -> Result { + let options = options.unwrap_or_default(); + let method = options.method.unwrap_or(Method::Get).to_string(); + + let mut req = match method.as_str() { + "GET" => self.client.get(url), + "POST" => self.client.post(url), + "PUT" => self.client.put(url), + _ => unreachable!(), + }; + + if let Some(headers) = options.headers { + let mut req_headers = HeaderMap::new(); + for (key, value) in headers { + req_headers.insert( + reqwest::header::HeaderName::try_from(key.as_str()).unwrap(), + value.parse().unwrap(), + ); + } + req = req.headers(req_headers); + } + + if let Some(body) = options.body { + req = req.body(body); + } + + let res = req.send().map_err(crate::Error::from)?; + + let status_code = res.status().as_u16(); + let mut headers = HashMap::new(); + for (key, value) in res.headers().iter() { + headers.insert(key.to_string(), value.to_str().unwrap().to_string()); + } + + let body = res.bytes().map_err(crate::Error::from)?.to_vec(); + + Ok(Response { + status_code, + headers, + body, + }) + } +} diff --git a/crates/web5/src/credentials/create.rs b/crates/web5/src/credentials/create.rs index 86c51b65..9ea8136e 100644 --- a/crates/web5/src/credentials/create.rs +++ b/crates/web5/src/credentials/create.rs @@ -571,7 +571,7 @@ mod tests { match result { Err(Web5Error::Http(err)) => { - assert!(err.to_string().contains("failed to connect to host")) + assert!(err.to_string().contains("error sending request")) } _ => panic!( "expected Web5Error::Http with specific message but got {:?}", diff --git a/crates/web5/src/credentials/verifiable_credential_1_1.rs b/crates/web5/src/credentials/verifiable_credential_1_1.rs index 5bd19207..6b973541 100644 --- a/crates/web5/src/credentials/verifiable_credential_1_1.rs +++ b/crates/web5/src/credentials/verifiable_credential_1_1.rs @@ -797,7 +797,7 @@ mod tests { match result { Err(Web5Error::Http(err)) => { - assert!(err.to_string().contains("failed to connect to host")) + assert!(err.to_string().contains("error sending request")) } _ => panic!( "expected Web5Error::Http with specific message but got {:?}",