mirror of
https://git.proxmox.com/git/proxmox
synced 2025-04-30 03:04:46 +00:00
http: client_trait: make request body generic
like the response body, instead of hard-coding Read.
This commit is contained in:
parent
891dcfda2f
commit
08a6d56eae
@ -1,7 +1,6 @@
|
|||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use std::io::Read;
|
|
||||||
#[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
|
#[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@ -82,23 +81,13 @@ impl Client {
|
|||||||
self.client.request(request).map_err(Error::from).await
|
self.client.request(request).map_err(Error::from).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn post<R>(
|
pub async fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<Body>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<Body>, Error>
|
) -> 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()
|
|
||||||
};
|
|
||||||
let content_type = content_type.unwrap_or("application/json");
|
let content_type = content_type.unwrap_or("application/json");
|
||||||
|
|
||||||
let mut request = Request::builder()
|
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
|
self.request(request).await
|
||||||
}
|
}
|
||||||
@ -173,7 +162,7 @@ impl Default for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
|
#[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
|
||||||
impl crate::HttpClient<Body> for Client {
|
impl crate::HttpClient<Body, Body> for Client {
|
||||||
fn get(
|
fn get(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
@ -194,16 +183,13 @@ impl crate::HttpClient<Body> for Client {
|
|||||||
proxmox_async::runtime::block_on(self.request(req))
|
proxmox_async::runtime::block_on(self.request(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post<R>(
|
fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<Body>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<Body>, Error>
|
) -> Result<Response<Body>, Error> {
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
proxmox_async::runtime::block_on(self.post(uri, body, content_type, extra_headers))
|
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"))]
|
#[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
|
||||||
impl crate::HttpClient<String> for Client {
|
impl crate::HttpClient<String, String> for Client {
|
||||||
fn get(
|
fn get(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
@ -236,17 +222,15 @@ impl crate::HttpClient<String> for Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post<R>(
|
fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<String>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<String>, Error>
|
) -> Result<Response<String>, Error> {
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
proxmox_async::runtime::block_on(async move {
|
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)
|
Self::convert_body_to_string(self.post(uri, body, content_type, extra_headers).await)
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
|
@ -106,7 +106,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HttpClient<String> for Client {
|
impl HttpClient<String, String> for Client {
|
||||||
fn get(
|
fn get(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
@ -118,21 +118,18 @@ impl HttpClient<String> for Client {
|
|||||||
self.call(req).and_then(Self::convert_response_to_string)
|
self.call(req).and_then(Self::convert_response_to_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post<R>(
|
fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<String>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<String>, Error>
|
) -> Result<Response<String>, Error> {
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
let req = self.agent()?.post(uri);
|
let req = self.agent()?.post(uri);
|
||||||
let req = Self::add_headers(req, content_type, extra_headers);
|
let req = Self::add_headers(req, content_type, extra_headers);
|
||||||
|
|
||||||
match body {
|
match body {
|
||||||
Some(body) => self.send(req, body),
|
Some(body) => self.send(req, body.as_bytes()),
|
||||||
None => self.call(req),
|
None => self.call(req),
|
||||||
}
|
}
|
||||||
.and_then(Self::convert_response_to_string)
|
.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(
|
fn get(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
@ -169,16 +166,13 @@ impl HttpClient<Vec<u8>> for Client {
|
|||||||
self.call(req).and_then(Self::convert_response_to_vec)
|
self.call(req).and_then(Self::convert_response_to_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post<R>(
|
fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<&[u8]>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<Vec<u8>>, Error>
|
) -> Result<Response<Vec<u8>>, Error> {
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
let req = self.agent()?.post(uri);
|
let req = self.agent()?.post(uri);
|
||||||
let req = Self::add_headers(req, content_type, extra_headers);
|
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)
|
.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
|
let mut req = self
|
||||||
.agent()?
|
.agent()?
|
||||||
.request(request.method().as_str(), &request.uri().to_string());
|
.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)
|
.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(
|
fn get(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
@ -220,16 +214,13 @@ impl HttpClient<Box<dyn Read>> for Client {
|
|||||||
self.call(req).and_then(Self::convert_response_to_reader)
|
self.call(req).and_then(Self::convert_response_to_reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post<R>(
|
fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<Box<dyn Read>>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<Box<dyn Read>>, Error>
|
) -> Result<Response<Box<dyn Read>>, Error> {
|
||||||
where
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
let req = self.agent()?.post(uri);
|
let req = self.agent()?.post(uri);
|
||||||
let req = Self::add_headers(req, content_type, extra_headers);
|
let req = Self::add_headers(req, content_type, extra_headers);
|
||||||
|
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
use std::{collections::HashMap, io::Read};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use http::{Request, Response};
|
use http::{Request, Response};
|
||||||
|
|
||||||
pub trait HttpClient<T> {
|
pub trait HttpClient<RequestBody, ResponseBody> {
|
||||||
fn get(
|
fn get(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<T>, Error>;
|
) -> Result<Response<ResponseBody>, Error>;
|
||||||
|
|
||||||
fn post<R>(
|
fn post(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<R>,
|
body: Option<RequestBody>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<T>, Error>
|
) -> Result<Response<ResponseBody>, Error>;
|
||||||
where
|
|
||||||
R: Read;
|
|
||||||
|
|
||||||
fn request(&self, request: Request<T>) -> Result<Response<T>, Error>;
|
fn request(&self, request: Request<RequestBody>) -> Result<Response<ResponseBody>, Error>;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ lazy_static! {
|
|||||||
const SHOP_URI: &str = "https://shop.proxmox.com/modules/servers/licensing/verify.php";
|
const SHOP_URI: &str = "https://shop.proxmox.com/modules/servers/licensing/verify.php";
|
||||||
|
|
||||||
/// (Re)-register a subscription key with the WHMCS server.
|
/// (Re)-register a subscription key with the WHMCS server.
|
||||||
fn register_subscription<C: HttpClient<String>>(
|
fn register_subscription<C: HttpClient<String, String>>(
|
||||||
key: &str,
|
key: &str,
|
||||||
server_id: &str,
|
server_id: &str,
|
||||||
checktime: i64,
|
checktime: i64,
|
||||||
@ -39,7 +39,7 @@ fn register_subscription<C: HttpClient<String>>(
|
|||||||
let query = json_object_to_query(params)?;
|
let query = json_object_to_query(params)?;
|
||||||
let response = client.post(
|
let response = client.post(
|
||||||
SHOP_URI,
|
SHOP_URI,
|
||||||
Some(&mut query.as_bytes()),
|
Some(query),
|
||||||
Some("application/x-www-form-urlencoded"),
|
Some("application/x-www-form-urlencoded"),
|
||||||
None,
|
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
|
/// Queries the WHMCS server to register/update the subscription key information, parsing the
|
||||||
/// response into a [SubscriptionInfo].
|
/// response into a [SubscriptionInfo].
|
||||||
pub fn check_subscription<C: HttpClient<String>>(
|
pub fn check_subscription<C: HttpClient<String, String>>(
|
||||||
key: String,
|
key: String,
|
||||||
server_id: String,
|
server_id: String,
|
||||||
product_url: String,
|
product_url: String,
|
||||||
|
Loading…
Reference in New Issue
Block a user