]> git.proxmox.com Git - proxmox.git/commitdiff
http: client_trait: make request body generic
authorFabian Grünbichler <f.gruenbichler@proxmox.com>
Fri, 5 Aug 2022 07:42:23 +0000 (09:42 +0200)
committerFabian Grünbichler <f.gruenbichler@proxmox.com>
Wed, 7 Sep 2022 07:25:47 +0000 (09:25 +0200)
like the response body, instead of hard-coding Read.

proxmox-http/src/client/simple.rs
proxmox-http/src/client/sync.rs
proxmox-http/src/client_trait.rs
proxmox-subscription/src/check.rs

index 083f1d9938ea91522287a31cc1056df0988a2d07..e9910802213247c14ad1501b61c124eefb5f2cc4 100644 (file)
@@ -1,7 +1,6 @@
 use anyhow::{bail, format_err, Error};
 use std::collections::HashMap;
 
-use std::io::Read;
 #[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
 use std::str::FromStr;
 
@@ -82,23 +81,13 @@ impl Client {
         self.client.request(request).map_err(Error::from).await
     }
 
-    pub async fn post<R>(
+    pub async fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<Body>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<Body>, Error>
-    where
-        R: Read,
-    {
-        let body = if let Some(mut body) = body {
-            let mut body_vec = Vec::new();
-            body.read_to_end(&mut body_vec)?;
-            Body::from(body_vec)
-        } else {
-            Body::empty()
-        };
+    ) -> Result<Response<Body>, Error> {
         let content_type = content_type.unwrap_or("application/json");
 
         let mut request = Request::builder()
@@ -112,7 +101,7 @@ impl Client {
             }
         }
 
-        let request = request.body(body)?;
+        let request = request.body(body.unwrap_or_default())?;
 
         self.request(request).await
     }
@@ -173,7 +162,7 @@ impl Default for Client {
 }
 
 #[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
-impl crate::HttpClient<Body> for Client {
+impl crate::HttpClient<Body, Body> for Client {
     fn get(
         &self,
         uri: &str,
@@ -194,16 +183,13 @@ impl crate::HttpClient<Body> for Client {
         proxmox_async::runtime::block_on(self.request(req))
     }
 
-    fn post<R>(
+    fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<Body>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<Body>, Error>
-    where
-        R: Read,
-    {
+    ) -> Result<Response<Body>, Error> {
         proxmox_async::runtime::block_on(self.post(uri, body, content_type, extra_headers))
     }
 
@@ -213,7 +199,7 @@ impl crate::HttpClient<Body> for Client {
 }
 
 #[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
-impl crate::HttpClient<String> for Client {
+impl crate::HttpClient<String, String> for Client {
     fn get(
         &self,
         uri: &str,
@@ -236,17 +222,15 @@ impl crate::HttpClient<String> for Client {
         })
     }
 
-    fn post<R>(
+    fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<String>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<String>, Error>
-    where
-        R: Read,
-    {
+    ) -> Result<Response<String>, Error> {
         proxmox_async::runtime::block_on(async move {
+            let body = body.map(|s| Body::from(s.into_bytes()));
             Self::convert_body_to_string(self.post(uri, body, content_type, extra_headers).await)
                 .await
         })
index 7aa3a8e19526faae6905bce6b6a8814f57345fc7..41b9c79cabcbecbb5b57fe799053b3cfb6025585 100644 (file)
@@ -106,7 +106,7 @@ impl Client {
     }
 }
 
-impl HttpClient<String> for Client {
+impl HttpClient<String, String> for Client {
     fn get(
         &self,
         uri: &str,
@@ -118,21 +118,18 @@ impl HttpClient<String> for Client {
         self.call(req).and_then(Self::convert_response_to_string)
     }
 
-    fn post<R>(
+    fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<String>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<String>, Error>
-    where
-        R: Read,
-    {
+    ) -> Result<Response<String>, Error> {
         let req = self.agent()?.post(uri);
         let req = Self::add_headers(req, content_type, extra_headers);
 
         match body {
-            Some(body) => self.send(req, body),
+            Some(body) => self.send(req, body.as_bytes()),
             None => self.call(req),
         }
         .and_then(Self::convert_response_to_string)
@@ -157,7 +154,7 @@ impl HttpClient<String> for Client {
     }
 }
 
-impl HttpClient<Vec<u8>> for Client {
+impl HttpClient<&[u8], Vec<u8>> for Client {
     fn get(
         &self,
         uri: &str,
@@ -169,16 +166,13 @@ impl HttpClient<Vec<u8>> for Client {
         self.call(req).and_then(Self::convert_response_to_vec)
     }
 
-    fn post<R>(
+    fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<&[u8]>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<Vec<u8>>, Error>
-    where
-        R: Read,
-    {
+    ) -> Result<Response<Vec<u8>>, Error> {
         let req = self.agent()?.post(uri);
         let req = Self::add_headers(req, content_type, extra_headers);
 
@@ -189,7 +183,7 @@ impl HttpClient<Vec<u8>> for Client {
         .and_then(Self::convert_response_to_vec)
     }
 
-    fn request(&self, request: http::Request<Vec<u8>>) -> Result<Response<Vec<u8>>, Error> {
+    fn request(&self, request: http::Request<&[u8]>) -> Result<Response<Vec<u8>>, Error> {
         let mut req = self
             .agent()?
             .request(request.method().as_str(), &request.uri().to_string());
@@ -203,12 +197,12 @@ impl HttpClient<Vec<u8>> for Client {
             }
         }
 
-        self.send(req, request.body().as_slice())
+        self.send(req, *request.body())
             .and_then(Self::convert_response_to_vec)
     }
 }
 
-impl HttpClient<Box<dyn Read>> for Client {
+impl HttpClient<Box<dyn Read>, Box<dyn Read>> for Client {
     fn get(
         &self,
         uri: &str,
@@ -220,16 +214,13 @@ impl HttpClient<Box<dyn Read>> for Client {
         self.call(req).and_then(Self::convert_response_to_reader)
     }
 
-    fn post<R>(
+    fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<Box<dyn Read>>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<Box<dyn Read>>, Error>
-    where
-        R: Read,
-    {
+    ) -> Result<Response<Box<dyn Read>>, Error> {
         let req = self.agent()?.post(uri);
         let req = Self::add_headers(req, content_type, extra_headers);
 
index 772348210c17c1ef6eda586ca9744aa88c94f562..83227649f85a57775f08a05540f3344b90ccdd66 100644 (file)
@@ -1,24 +1,22 @@
-use std::{collections::HashMap, io::Read};
+use std::collections::HashMap;
 
 use anyhow::Error;
 use http::{Request, Response};
 
-pub trait HttpClient<T> {
+pub trait HttpClient<RequestBody, ResponseBody> {
     fn get(
         &self,
         uri: &str,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<T>, Error>;
+    ) -> Result<Response<ResponseBody>, Error>;
 
-    fn post<R>(
+    fn post(
         &self,
         uri: &str,
-        body: Option<R>,
+        body: Option<RequestBody>,
         content_type: Option<&str>,
         extra_headers: Option<&HashMap<String, String>>,
-    ) -> Result<Response<T>, Error>
-    where
-        R: Read;
+    ) -> Result<Response<ResponseBody>, Error>;
 
-    fn request(&self, request: Request<T>) -> Result<Response<T>, Error>;
+    fn request(&self, request: Request<RequestBody>) -> Result<Response<ResponseBody>, Error>;
 }
index 530f7cdf1cd89df0cfae281d2774e5c361109072..33fca579a4d10597c4f5f23a4e054c2823053c6b 100644 (file)
@@ -18,7 +18,7 @@ lazy_static! {
 const SHOP_URI: &str = "https://shop.proxmox.com/modules/servers/licensing/verify.php";
 
 /// (Re)-register a subscription key with the WHMCS server.
-fn register_subscription<C: HttpClient<String>>(
+fn register_subscription<C: HttpClient<String, String>>(
     key: &str,
     server_id: &str,
     checktime: i64,
@@ -39,7 +39,7 @@ fn register_subscription<C: HttpClient<String>>(
     let query = json_object_to_query(params)?;
     let response = client.post(
         SHOP_URI,
-        Some(&mut query.as_bytes()),
+        Some(query),
         Some("application/x-www-form-urlencoded"),
         None,
     )?;
@@ -164,7 +164,7 @@ fn test_parse_register_response() -> Result<(), Error> {
 
 /// Queries the WHMCS server to register/update the subscription key information, parsing the
 /// response into a [SubscriptionInfo].
-pub fn check_subscription<C: HttpClient<String>>(
+pub fn check_subscription<C: HttpClient<String, String>>(
     key: String,
     server_id: String,
     product_url: String,