irelia_cli/utils/
requests.rs1use crate::Error;
2
3use http_body_util::{BodyExt, Full};
4use hyper::body::{Bytes, Incoming};
5use hyper::header::AUTHORIZATION;
6use hyper::http::uri;
7use hyper::{Request, Response};
8use hyper_rustls::HttpsConnector;
9use hyper_util::client::legacy::connect::HttpConnector;
10use hyper_util::client::legacy::Client;
11use serde::de::DeserializeOwned;
12use serde::Serialize;
13
14use super::setup_tls::setup_tls_connector;
15
16pub struct RequestClient {
29 client: Client<HttpsConnector<HttpConnector>, Full<Bytes>>,
30}
31
32impl RequestClient {
33 #[must_use]
34 pub fn new() -> RequestClient {
36 let tls = setup_tls_connector();
38 let https = hyper_rustls::HttpsConnectorBuilder::new()
40 .with_tls_config(tls)
41 .https_only()
42 .enable_http1()
43 .build();
44 let client = Client::builder(hyper_util::rt::TokioExecutor::new()).build(https);
46
47 RequestClient { client }
48 }
49
50 pub(crate) async fn raw_request_template<T>(
51 &self,
52 url: &str,
53 endpoint: &str,
54 method: &str,
55 body: Option<T>,
56 auth_header: Option<&str>,
57 ) -> Result<Response<Incoming>, Error>
58 where
59 T: Serialize,
60 {
61 let built_uri = uri::Builder::new()
62 .scheme("https")
63 .authority(url.as_bytes())
64 .path_and_query(endpoint)
65 .build()?;
66
67 let body = if let Some(body) = &body {
68 let json = serde_json::value::to_value(body)?;
69 Full::from(json.to_string())
70 } else {
71 Full::default()
72 };
73
74 let builder = Request::builder().method(method).uri(built_uri);
75
76 let builder = if let Some(header) = auth_header {
77 builder.header(AUTHORIZATION, header)
78 } else {
79 builder
80 };
81
82 let request = builder.body(body)?;
83
84 Ok(self.client.request(request).await?)
85 }
86
87 pub(crate) async fn request_template<T, R>(
88 &self,
89 url: &str,
90 endpoint: &str,
91 method: &str,
92 body: Option<T>,
93 auth_header: Option<&str>,
94 return_logic: fn(bytes: Bytes) -> Result<R, Error>,
95 ) -> Result<R, Error>
96 where
97 T: Serialize,
98 R: DeserializeOwned,
99 {
100 let mut response = self
101 .raw_request_template(url, endpoint, method, body, auth_header)
102 .await?;
103
104 let body = response.body_mut();
105
106 let bytes = body.collect().await?.to_bytes();
107
108 return_logic(bytes)
109 }
110}
111
112impl Default for RequestClient {
113 fn default() -> Self {
114 Self::new()
115 }
116}