forked from proxmox-mirrors/proxmox
http: make post() take Read
, not &str
for more flexibility. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
parent
7863eff2a5
commit
00f5eca155
@ -1,6 +1,7 @@
|
|||||||
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;
|
||||||
|
|
||||||
@ -81,14 +82,19 @@ impl Client {
|
|||||||
self.client.request(request).map_err(Error::from).await
|
self.client.request(request).map_err(Error::from).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn post(
|
pub async fn post<R>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<String>,
|
body: Option<R>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error>
|
||||||
let body = if let Some(body) = body {
|
where
|
||||||
Body::from(body)
|
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 {
|
} else {
|
||||||
Body::empty()
|
Body::empty()
|
||||||
};
|
};
|
||||||
@ -180,13 +186,16 @@ impl crate::HttpClient<Body> for Client {
|
|||||||
proxmox_async::runtime::block_on(self.request(req))
|
proxmox_async::runtime::block_on(self.request(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post(
|
fn post<R>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<&str>,
|
body: Option<R>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
) -> Result<Response<Body>, Error> {
|
) -> Result<Response<Body>, Error>
|
||||||
proxmox_async::runtime::block_on(self.post(uri, body.map(|s| s.to_owned()), content_type))
|
where
|
||||||
|
R: Read,
|
||||||
|
{
|
||||||
|
proxmox_async::runtime::block_on(self.post(uri, body, content_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request(&self, request: Request<Body>) -> Result<Response<Body>, Error> {
|
fn request(&self, request: Request<Body>) -> Result<Response<Body>, Error> {
|
||||||
@ -218,18 +227,17 @@ impl crate::HttpClient<String> for Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post(
|
fn post<R>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<&str>,
|
body: Option<R>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
) -> 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 {
|
||||||
Self::convert_body_to_string(
|
Self::convert_body_to_string(self.post(uri, body, content_type).await).await
|
||||||
self.post(uri, body.map(|s| s.to_owned()), content_type)
|
|
||||||
.await,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,24 +29,32 @@ impl Client {
|
|||||||
Ok(builder.build())
|
Ok(builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_request(
|
fn add_user_agent(&self, req: ureq::Request) -> ureq::Request {
|
||||||
&self,
|
req.set(
|
||||||
req: ureq::Request,
|
|
||||||
body: Option<&[u8]>,
|
|
||||||
) -> Result<Response<Vec<u8>>, Error> {
|
|
||||||
let req = req.set(
|
|
||||||
"User-Agent",
|
"User-Agent",
|
||||||
self.options
|
self.options
|
||||||
.user_agent
|
.user_agent
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.unwrap_or(DEFAULT_USER_AGENT_STRING),
|
.unwrap_or(DEFAULT_USER_AGENT_STRING),
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let res = match body {
|
fn call(&self, req: ureq::Request) -> Result<Response<Vec<u8>>, Error> {
|
||||||
Some(body) => req.send_bytes(body),
|
let req = self.add_user_agent(req);
|
||||||
None => req.call(),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
|
Self::convert_response(req.call()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send<R>(&self, req: ureq::Request, body: R) -> Result<Response<Vec<u8>>, Error>
|
||||||
|
where
|
||||||
|
R: Read,
|
||||||
|
{
|
||||||
|
let req = self.add_user_agent(req);
|
||||||
|
|
||||||
|
Self::convert_response(req.send(body)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_response(res: ureq::Response) -> Result<Response<Vec<u8>>, Error> {
|
||||||
let mut builder = http::response::Builder::new()
|
let mut builder = http::response::Builder::new()
|
||||||
.status(http::status::StatusCode::from_u16(res.status())?);
|
.status(http::status::StatusCode::from_u16(res.status())?);
|
||||||
|
|
||||||
@ -83,22 +91,27 @@ impl HttpClient<String> for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.exec_request(req, None)
|
self.call(req).and_then(Self::convert_body_to_string)
|
||||||
.and_then(Self::convert_body_to_string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post(
|
fn post<R>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<&str>,
|
body: Option<R>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
) -> Result<Response<String>, Error> {
|
) -> Result<Response<String>, Error>
|
||||||
|
where
|
||||||
|
R: Read,
|
||||||
|
{
|
||||||
let mut req = self.agent()?.post(uri);
|
let mut req = self.agent()?.post(uri);
|
||||||
if let Some(content_type) = content_type {
|
if let Some(content_type) = content_type {
|
||||||
req = req.set("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),
|
||||||
|
}
|
||||||
.and_then(Self::convert_body_to_string)
|
.and_then(Self::convert_body_to_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +127,7 @@ impl HttpClient<String> 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)
|
.and_then(Self::convert_body_to_string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,21 +146,27 @@ impl HttpClient<Vec<u8>> for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.exec_request(req, None)
|
self.call(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post(
|
fn post<R>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<&str>,
|
body: Option<R>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
) -> Result<Response<Vec<u8>>, Error> {
|
) -> Result<Response<Vec<u8>>, Error>
|
||||||
|
where
|
||||||
|
R: Read,
|
||||||
|
{
|
||||||
let mut req = self.agent()?.post(uri);
|
let mut req = self.agent()?.post(uri);
|
||||||
if let Some(content_type) = content_type {
|
if let Some(content_type) = content_type {
|
||||||
req = req.set("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<Vec<u8>>) -> Result<Response<Vec<u8>>, Error> {
|
fn request(&self, request: http::Request<Vec<u8>>) -> Result<Response<Vec<u8>>, Error> {
|
||||||
@ -162,6 +181,6 @@ impl HttpClient<Vec<u8>> for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.exec_request(req, Some(request.body()))
|
self.send(req, request.body().as_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, io::Read};
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use http::{Request, Response};
|
use http::{Request, Response};
|
||||||
@ -10,12 +10,14 @@ pub trait HttpClient<T> {
|
|||||||
extra_headers: Option<&HashMap<String, String>>,
|
extra_headers: Option<&HashMap<String, String>>,
|
||||||
) -> Result<Response<T>, Error>;
|
) -> Result<Response<T>, Error>;
|
||||||
|
|
||||||
fn post(
|
fn post<R>(
|
||||||
&self,
|
&self,
|
||||||
uri: &str,
|
uri: &str,
|
||||||
body: Option<&str>,
|
body: Option<R>,
|
||||||
content_type: Option<&str>,
|
content_type: Option<&str>,
|
||||||
) -> Result<Response<T>, Error>;
|
) -> Result<Response<T>, Error>
|
||||||
|
where
|
||||||
|
R: Read;
|
||||||
|
|
||||||
fn request(&self, request: Request<T>) -> Result<Response<T>, Error>;
|
fn request(&self, request: Request<T>) -> Result<Response<T>, Error>;
|
||||||
}
|
}
|
||||||
|
@ -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(&query),
|
Some(&mut query.as_bytes()),
|
||||||
Some("application/x-www-form-urlencoded"),
|
Some("application/x-www-form-urlencoded"),
|
||||||
)?;
|
)?;
|
||||||
let body = response.into_body();
|
let body = response.into_body();
|
||||||
|
Loading…
Reference in New Issue
Block a user