umbral_socket/http/
client.rs

1use http_body_util::BodyExt;
2use http_body_util::Empty;
3use http_body_util::Full;
4use hyper::Method;
5use hyper::Request;
6use hyper::body::{Buf, Bytes};
7use hyper::header;
8use hyper_util::client::legacy::Client;
9use hyper_util::rt::tokio::TokioExecutor;
10use hyperlocal::UnixConnector;
11use hyperlocal::Uri;
12use serde::Serialize;
13use serde::de::DeserializeOwned;
14
15use std::error::Error;
16
17pub struct HttpSocketResponse<T: DeserializeOwned> {
18    pub status: u16,
19    pub response: Option<T>,
20}
21
22impl<T: DeserializeOwned> HttpSocketResponse<T> {
23    fn new(status: u16, response: Option<T>) -> Self {
24        return HttpSocketResponse {
25            status: status,
26            response: response,
27        };
28    }
29}
30
31type EmptyClient = Client<UnixConnector, Empty<Bytes>>;
32type FullClient = Client<UnixConnector, Full<Bytes>>;
33
34#[derive(Clone)]
35pub struct HttpClient {
36    socket: String,
37    empty: EmptyClient,
38    full: FullClient,
39}
40
41impl HttpClient {
42    pub fn new(socket: &str) -> HttpClient {
43        let connector = UnixConnector;
44        return HttpClient {
45            socket: String::from(socket),
46            empty: Client::builder(TokioExecutor::new()).build(connector),
47            full: Client::builder(TokioExecutor::new()).build(connector),
48        };
49    }
50
51    pub async fn get<U: DeserializeOwned>(
52        &self,
53        endpoint: &str,
54    ) -> Result<HttpSocketResponse<U>, Box<dyn Error>> {
55        let uri = hyperlocal::Uri::new(&self.socket, endpoint).into();
56        let response = self.empty.get(uri).await?;
57        let status = response.status().as_u16();
58        let body_bytes = response.into_body().collect().await?.to_bytes();
59        let data: U = serde_json::from_reader(body_bytes.reader())?;
60        return Ok(HttpSocketResponse::new(status, Some(data)));
61    }
62
63    pub async fn post<T: Serialize, U: DeserializeOwned>(
64        &self,
65        endpoint: &str,
66        request: &T,
67    ) -> Result<HttpSocketResponse<U>, Box<dyn Error>> {
68        let body_bytes = serde_json::to_vec(&*request).unwrap();
69        let request_body = Full::new(Bytes::from(body_bytes));
70
71        let request = Request::builder()
72            .method(Method::POST)
73            .uri(Uri::new(&self.socket, endpoint))
74            .header(header::CONTENT_TYPE, "application/json")
75            .body(request_body)?;
76
77        let response = self.full.request(request).await?;
78        let status = response.status().as_u16();
79        let body_bytes = response.into_body().collect().await?.to_bytes();
80        let data: U = serde_json::from_reader(body_bytes.reader())?;
81        return Ok(HttpSocketResponse::new(status, Some(data)));
82    }
83
84    pub async fn post_raw<T: Serialize>(
85        &self,
86        endpoint: &str,
87        request: &T,
88    ) -> Result<HttpSocketResponse<()>, Box<dyn Error>> {
89        let body_bytes = serde_json::to_vec(&*request)?;
90        let request_body = Full::new(Bytes::from(body_bytes));
91
92        let request = Request::builder()
93            .method(Method::POST)
94            .uri(Uri::new(&self.socket, endpoint))
95            .header(header::CONTENT_TYPE, "application/json")
96            .body(request_body)?;
97
98        let response = self.full.request(request).await?;
99        let status = response.status().as_u16();
100        response.into_body().collect().await?;
101        return Ok(HttpSocketResponse::new(status, None));
102    }
103
104    pub async fn post_trigger(
105        &self,
106        endpoint: &str,
107    ) -> Result<HttpSocketResponse<()>, Box<dyn Error>> {
108        let request_body = Empty::<Bytes>::new();
109        let request = Request::builder()
110            .method(Method::POST)
111            .uri(Uri::new(&self.socket, endpoint))
112            .header(header::CONTENT_LENGTH, "0")
113            .body(request_body)?;
114
115        let response = self.empty.request(request).await?;
116        let status = response.status().as_u16();
117        response.into_body().collect().await?;
118        return Ok(HttpSocketResponse::new(status, None));
119    }
120
121    pub async fn post_raw_bytes(
122        &self,
123        endpoint: &str,
124        body: Bytes,
125    ) -> Result<HttpSocketResponse<()>, Box<dyn Error>> {
126        let request_body = Full::new(body);
127        let request = Request::builder()
128            .method(Method::POST)
129            .uri(Uri::new(&self.socket, endpoint))
130            .header(header::CONTENT_TYPE, "application/json")
131            .body(request_body)?;
132        let response = self.full.request(request).await?;
133        let status = response.status();
134        response.into_body().collect().await?;
135        Ok(HttpSocketResponse::new(status.as_u16(), None))
136    }
137}