http: add "raw" sync client

and switch String one over to use it.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2022-08-04 11:29:44 +02:00
parent 9c444d7a94
commit 7ffb895062

View File

@ -1,4 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Read;
use anyhow::{format_err, Error}; use anyhow::{format_err, Error};
use http::Response; use http::Response;
@ -31,8 +32,8 @@ impl Client {
fn exec_request( fn exec_request(
&self, &self,
req: ureq::Request, req: ureq::Request,
body: Option<&str>, body: Option<&[u8]>,
) -> Result<Response<String>, Error> { ) -> Result<Response<Vec<u8>>, Error> {
let req = req.set( let req = req.set(
"User-Agent", "User-Agent",
self.options self.options
@ -42,7 +43,7 @@ impl Client {
); );
let res = match body { let res = match body {
Some(body) => req.send_string(body), Some(body) => req.send_bytes(body),
None => req.call(), None => req.call(),
}?; }?;
@ -54,10 +55,18 @@ impl Client {
builder = builder.header(header, value); builder = builder.header(header, value);
} }
} }
let mut body = Vec::new();
res.into_reader().read_to_end(&mut body)?;
builder builder
.body(res.into_string()?) .body(body)
.map_err(|err| format_err!("Failed to convert HTTP response - {err}")) .map_err(|err| format_err!("Failed to convert HTTP response - {err}"))
} }
fn convert_body_to_string(res: Response<Vec<u8>>) -> Result<Response<String>, Error> {
let (parts, body) = res.into_parts();
let body = String::from_utf8(body)?;
Ok(Response::from_parts(parts, body))
}
} }
impl HttpClient<String> for Client { impl HttpClient<String> for Client {
@ -75,6 +84,7 @@ impl HttpClient<String> for Client {
} }
self.exec_request(req, None) self.exec_request(req, None)
.and_then(Self::convert_body_to_string)
} }
fn post( fn post(
@ -88,7 +98,8 @@ impl HttpClient<String> for Client {
req = req.set("Content-Type", content_type); req = req.set("Content-Type", content_type);
} }
self.exec_request(req, body) self.exec_request(req, body.map(|b| b.as_bytes()))
.and_then(Self::convert_body_to_string)
} }
fn request(&self, request: http::Request<String>) -> Result<Response<String>, Error> { fn request(&self, request: http::Request<String>) -> Result<Response<String>, Error> {
@ -103,6 +114,54 @@ impl HttpClient<String> for Client {
} }
} }
self.exec_request(req, Some(request.body().as_str())) self.exec_request(req, Some(request.body().as_bytes()))
.and_then(Self::convert_body_to_string)
}
}
impl HttpClient<Vec<u8>> for Client {
fn get(
&self,
uri: &str,
extra_headers: Option<&HashMap<String, String>>,
) -> Result<Response<Vec<u8>>, Error> {
let mut req = self.agent()?.get(uri);
if let Some(extra_headers) = extra_headers {
for (header, value) in extra_headers {
req = req.set(header, value);
}
}
self.exec_request(req, None)
}
fn post(
&self,
uri: &str,
body: Option<&str>,
content_type: Option<&str>,
) -> Result<Response<Vec<u8>>, Error> {
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()))
}
fn request(&self, request: http::Request<Vec<u8>>) -> Result<Response<Vec<u8>>, Error> {
let mut req = self
.agent()?
.request(request.method().as_str(), &request.uri().to_string());
let orig_headers = request.headers();
for header in orig_headers.keys() {
for value in orig_headers.get_all(header) {
req = req.set(header.as_str(), value.to_str()?);
}
}
self.exec_request(req, Some(request.body()))
} }
} }