From 00f5eca1559c63dba55de932ab287036b5ba2c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Thu, 4 Aug 2022 13:15:47 +0200 Subject: [PATCH] http: make post() take `Read`, not &str MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for more flexibility. Signed-off-by: Fabian Grünbichler --- proxmox-http/src/client/simple.rs | 42 +++++++++++-------- proxmox-http/src/client/sync.rs | 69 ++++++++++++++++++++----------- proxmox-http/src/client_trait.rs | 10 +++-- proxmox-subscription/src/check.rs | 2 +- 4 files changed, 76 insertions(+), 47 deletions(-) diff --git a/proxmox-http/src/client/simple.rs b/proxmox-http/src/client/simple.rs index cbeac14f..6cf82304 100644 --- a/proxmox-http/src/client/simple.rs +++ b/proxmox-http/src/client/simple.rs @@ -1,6 +1,7 @@ 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; @@ -81,14 +82,19 @@ impl Client { self.client.request(request).map_err(Error::from).await } - pub async fn post( + pub async fn post( &self, uri: &str, - body: Option, + body: Option, content_type: Option<&str>, - ) -> Result, Error> { - let body = if let Some(body) = body { - Body::from(body) + ) -> Result, 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() }; @@ -180,13 +186,16 @@ impl crate::HttpClient for Client { proxmox_async::runtime::block_on(self.request(req)) } - fn post( + fn post( &self, uri: &str, - body: Option<&str>, + body: Option, content_type: Option<&str>, - ) -> Result, Error> { - proxmox_async::runtime::block_on(self.post(uri, body.map(|s| s.to_owned()), content_type)) + ) -> Result, Error> + where + R: Read, + { + proxmox_async::runtime::block_on(self.post(uri, body, content_type)) } fn request(&self, request: Request) -> Result, Error> { @@ -218,18 +227,17 @@ impl crate::HttpClient for Client { }) } - fn post( + fn post( &self, uri: &str, - body: Option<&str>, + body: Option, content_type: Option<&str>, - ) -> Result, Error> { + ) -> Result, Error> + where + R: Read, + { proxmox_async::runtime::block_on(async move { - Self::convert_body_to_string( - self.post(uri, body.map(|s| s.to_owned()), content_type) - .await, - ) - .await + Self::convert_body_to_string(self.post(uri, body, content_type).await).await }) } diff --git a/proxmox-http/src/client/sync.rs b/proxmox-http/src/client/sync.rs index 7657e348..60b5bdf6 100644 --- a/proxmox-http/src/client/sync.rs +++ b/proxmox-http/src/client/sync.rs @@ -29,24 +29,32 @@ impl Client { Ok(builder.build()) } - fn exec_request( - &self, - req: ureq::Request, - body: Option<&[u8]>, - ) -> Result>, Error> { - let req = req.set( + fn add_user_agent(&self, req: ureq::Request) -> ureq::Request { + req.set( "User-Agent", self.options .user_agent .as_deref() .unwrap_or(DEFAULT_USER_AGENT_STRING), - ); + ) + } - let res = match body { - Some(body) => req.send_bytes(body), - None => req.call(), - }?; + fn call(&self, req: ureq::Request) -> Result>, Error> { + let req = self.add_user_agent(req); + Self::convert_response(req.call()?) + } + + fn send(&self, req: ureq::Request, body: R) -> Result>, Error> + where + R: Read, + { + let req = self.add_user_agent(req); + + Self::convert_response(req.send(body)?) + } + + fn convert_response(res: ureq::Response) -> Result>, Error> { let mut builder = http::response::Builder::new() .status(http::status::StatusCode::from_u16(res.status())?); @@ -83,23 +91,28 @@ impl HttpClient for Client { } } - self.exec_request(req, None) - .and_then(Self::convert_body_to_string) + self.call(req).and_then(Self::convert_body_to_string) } - fn post( + fn post( &self, uri: &str, - body: Option<&str>, + body: Option, content_type: Option<&str>, - ) -> Result, Error> { + ) -> Result, Error> + where + R: Read, + { let mut req = self.agent()?.post(uri); if let Some(content_type) = content_type { req = req.set("Content-Type", content_type); } - self.exec_request(req, body.map(|b| b.as_bytes())) - .and_then(Self::convert_body_to_string) + match body { + Some(body) => self.send(req, body), + None => self.call(req), + } + .and_then(Self::convert_body_to_string) } fn request(&self, request: http::Request) -> Result, Error> { @@ -114,7 +127,7 @@ impl HttpClient for Client { } } - self.exec_request(req, Some(request.body().as_bytes())) + self.send(req, request.body().as_bytes()) .and_then(Self::convert_body_to_string) } } @@ -133,21 +146,27 @@ impl HttpClient> for Client { } } - self.exec_request(req, None) + self.call(req) } - fn post( + fn post( &self, uri: &str, - body: Option<&str>, + body: Option, content_type: Option<&str>, - ) -> Result>, Error> { + ) -> Result>, Error> + where + R: Read, + { let mut req = self.agent()?.post(uri); if let Some(content_type) = content_type { req = req.set("Content-Type", content_type); } - self.exec_request(req, body.map(|b| b.as_bytes())) + match body { + Some(body) => self.send(req, body), + None => self.call(req), + } } fn request(&self, request: http::Request>) -> Result>, Error> { @@ -162,6 +181,6 @@ impl HttpClient> for Client { } } - self.exec_request(req, Some(request.body())) + self.send(req, request.body().as_slice()) } } diff --git a/proxmox-http/src/client_trait.rs b/proxmox-http/src/client_trait.rs index 5b5545d3..7f5a1883 100644 --- a/proxmox-http/src/client_trait.rs +++ b/proxmox-http/src/client_trait.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, io::Read}; use anyhow::Error; use http::{Request, Response}; @@ -10,12 +10,14 @@ pub trait HttpClient { extra_headers: Option<&HashMap>, ) -> Result, Error>; - fn post( + fn post( &self, uri: &str, - body: Option<&str>, + body: Option, content_type: Option<&str>, - ) -> Result, Error>; + ) -> Result, Error> + where + R: Read; fn request(&self, request: Request) -> Result, Error>; } diff --git a/proxmox-subscription/src/check.rs b/proxmox-subscription/src/check.rs index 7ca44667..408b4f26 100644 --- a/proxmox-subscription/src/check.rs +++ b/proxmox-subscription/src/check.rs @@ -39,7 +39,7 @@ fn register_subscription>( let query = json_object_to_query(params)?; let response = client.post( SHOP_URI, - Some(&query), + Some(&mut query.as_bytes()), Some("application/x-www-form-urlencoded"), )?; let body = response.into_body();