vertx_rust/http/
client.rs

1use futures::TryStreamExt;
2use hyper::client::{HttpConnector, ResponseFuture};
3use hyper::{Body, Client, Error, Request, Response, Uri};
4use tokio::runtime::Runtime;
5use hyper_tls::HttpsConnector;
6
7#[cfg(test)]
8mod test {
9    use crate::http::client::WebClient;
10    extern crate pretty_env_logger;
11    use hyper::{Body, Request};
12    use log::info;
13    use tokio::runtime::Runtime;
14
15    #[test]
16    fn test_blocking_get() {
17        std::env::set_var("RUST_LOG", "info");
18        pretty_env_logger::init_timed();
19
20        let client = WebClient::new();
21        let response = client.blocking_get("http://127.0.0.1:9092");
22        info!("{:?}", response);
23    }
24
25    #[test]
26    fn test_blocking_request() {
27        std::env::set_var("RUST_LOG", "info");
28        pretty_env_logger::init_timed();
29
30        let client = WebClient::new();
31        let body = Body::from("test_blocking_request");
32        let request = Request::post("http://127.0.0.1:9092").body(body).unwrap();
33
34        let response = client.blocking_request(request);
35        let _ = response.map(|r| WebClient::blocking_body(r.into_body())
36            .map(|b| {
37                info!("{:?}", std::str::from_utf8(&*b));
38                b
39            })
40        );
41    }
42
43    #[test]
44    fn test_get() {
45        std::env::set_var("RUST_LOG", "info");
46        pretty_env_logger::init_timed();
47        let rt = Runtime::new().unwrap();
48        let client = WebClient::new();
49
50        let response = rt.block_on(client.get("https://github.com"));
51        info!(
52            "{:?}",
53            WebClient::blocking_body(response.unwrap().into_body())
54        );
55    }
56}
57
58pub struct WebClient {
59    client: Client<HttpConnector, Body>,
60    tls_client: Client<HttpsConnector<HttpConnector>, Body>,
61    runtime: Runtime,
62}
63
64#[allow(dead_code)]
65impl WebClient {
66    pub fn new() -> Self {
67        let runtime = Runtime::new().unwrap();
68        let https = HttpsConnector::new();
69        let tls_client = Client::builder().build::<_, Body>(https);
70        WebClient {
71            client: Client::new(),
72            runtime,
73            tls_client
74        }
75    }
76
77    #[inline]
78    pub fn blocking_body(body: Body) -> Result<Vec<u8>, Error> {
79        futures::executor::block_on(WebClient::get_body(body))
80    }
81
82    #[inline]
83    pub async fn get_body(body: Body) -> Result<Vec<u8>, Error> {
84        let body = body.try_fold(Vec::new(), |mut data, chunk| async move {
85            data.extend_from_slice(&chunk);
86            Ok(data)
87        });
88        body.await
89    }
90
91    #[inline]
92    pub fn blocking_get(&self, url: &'static str) -> Result<Response<Body>, Error> {
93        self.runtime.block_on(self.get(url))
94    }
95
96    #[inline]
97    pub fn blocking_request(&self, request: Request<Body>) -> Result<Response<Body>, Error> {
98        self.runtime.block_on(self.request(request))
99    }
100
101    #[inline]
102    pub fn request(&self, request: Request<Body>) -> ResponseFuture {
103        if request.uri().scheme_str() == Some("https") {
104            self.tls_client.request(request)
105        } else {
106            self.client.request(request)
107        }
108    }
109
110    #[inline]
111    pub fn get(&self, url: &'static str) -> ResponseFuture {
112        let uri = Uri::from_static(url);
113        if uri.scheme_str() == Some("https") {
114            self.tls_client.get(uri)
115        } else {
116            self.client.get(uri)
117        }
118    }
119}