like the response body, instead of hard-coding Read.
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;
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()
}
}
- let request = request.body(body)?;
+ let request = request.body(body.unwrap_or_default())?;
self.request(request).await
}
}
#[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,
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))
}
}
#[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,
})
}
- 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
})
}
}
-impl HttpClient<String> for Client {
+impl HttpClient<String, String> for Client {
fn get(
&self,
uri: &str,
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)
}
}
-impl HttpClient<Vec<u8>> for Client {
+impl HttpClient<&[u8], Vec<u8>> for Client {
fn get(
&self,
uri: &str,
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);
.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());
}
}
- 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,
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);
-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>;
}
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,
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,
)?;
/// 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,