use crate::config::HttpConfig;
use crate::error::HttpError;
use crate::model::request::api_request::HttpRequest;
use crate::model::response::api_response::HttpResponse;
use reqwest::Client;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct HttpConnection {
client: Client,
config: HttpConfig,
}
impl HttpConnection {
pub fn new(config: HttpConfig) -> Result<Self, HttpError> {
let builder = Client::builder();
#[cfg(not(target_arch = "wasm32"))]
let builder = builder
.timeout(config.timeout)
.user_agent(&config.user_agent);
let client = builder
.build()
.map_err(|e| HttpError::NetworkError(e.to_string()))?;
Ok(Self { client, config })
}
pub async fn send_request(&self, request: &HttpRequest) -> Result<HttpResponse, HttpError> {
let mut req_builder = match request.method.as_str() {
"GET" => self.client.get(&request.endpoint),
"POST" => self.client.post(&request.endpoint),
"PUT" => self.client.put(&request.endpoint),
"DELETE" => self.client.delete(&request.endpoint),
_ => {
return Err(HttpError::RequestFailed(format!(
"Unsupported method: {}",
request.method
)));
}
};
for (key, value) in &request.headers {
req_builder = req_builder.header(key, value);
}
if let Some(body) = &request.body {
req_builder = req_builder.body(body.clone());
}
let response = req_builder
.send()
.await
.map_err(|e| HttpError::NetworkError(e.to_string()))?;
let status = response.status().as_u16();
let headers = response
.headers()
.iter()
.map(|(k, v)| (k.to_string(), v.to_str().unwrap_or("").to_string()))
.collect::<HashMap<String, String>>();
let body = response
.text()
.await
.map_err(|e| HttpError::NetworkError(e.to_string()))?;
Ok(HttpResponse {
status,
headers,
body,
})
}
pub fn config(&self) -> &HttpConfig {
&self.config
}
pub fn client(&self) -> &Client {
&self.client
}
}