use alloc::collections::BTreeMap;
use alloc::string::String;
#[allow(unused_imports)]
use alloc::string::ToString;
use alloc::vec;
use alloc::vec::Vec;
use core::time::Duration;
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::protocol::{Protocol, Proxy};
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::policy::RedirectPolicy;
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::method::Method;
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::error::ProductOSRequestError;
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::request::ProductOSRequest;
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::response::ProductOSResponse;
#[cfg(any(feature = "request", feature = "request_std"))]
use crate::client::ProductOSClient;
#[cfg(any(feature = "request", feature = "request_std"))]
pub use product_os_http::Request;
#[cfg(any(feature = "request", feature = "request_std"))]
#[derive(Clone)]
pub struct ProductOSRequester {
pub(crate) headers: product_os_http::header::HeaderMap,
pub(crate) secure: bool,
pub(crate) timeout: Duration,
pub(crate) connect_timeout: Duration,
pub(crate) certificates: Vec<Vec<u8>>,
pub(crate) trust_all_certificates: bool,
pub(crate) trust_any_certificate_for_hostname: bool,
pub(crate) proxy: Option<Proxy>,
pub(crate) redirect_policy: RedirectPolicy,
}
#[cfg(any(feature = "request", feature = "request_std"))]
impl ProductOSRequester {
pub fn new() -> Self {
Self::default()
}
pub fn add_header(&mut self, name: &str, value: &str, is_sensitive: bool) {
let header_name = match product_os_http::header::HeaderName::try_from(name) {
Ok(n) => n,
Err(e) => {
tracing::error!("Invalid header name '{}': {:?}", name, e);
return;
}
};
let mut header_value = match product_os_http::header::HeaderValue::try_from(value) {
Ok(v) => v,
Err(e) => {
tracing::error!("Invalid header value for '{}': {:?}", name, e);
return;
}
};
header_value.set_sensitive(is_sensitive);
self.headers.append(header_name, header_value);
}
pub fn set_headers(&mut self, headers: BTreeMap<String, String>) {
let mut header_map = product_os_http::header::HeaderMap::new();
for (name, value) in headers {
match product_os_http::header::HeaderName::try_from(name.clone()) {
Ok(header_name) => match product_os_http::header::HeaderValue::try_from(value) {
Ok(header_value) => {
header_map.insert(header_name, header_value);
}
Err(e) => {
tracing::warn!("Skipping invalid header value for '{}': {:?}", name, e);
}
},
Err(e) => {
tracing::warn!("Skipping invalid header name '{}': {:?}", name, e);
}
}
}
self.headers = header_map;
}
pub fn force_secure(&mut self, sec: bool) {
self.secure = sec;
}
pub fn trust_all_certificates(&mut self, trust: bool) {
self.trust_all_certificates = trust;
}
pub fn trust_any_certificate_for_hostname(&mut self, trust: bool) {
self.trust_any_certificate_for_hostname = trust;
}
pub fn set_timeout(&mut self, time: u64) {
self.timeout = Duration::from_millis(time);
}
pub fn set_connect_timeout(&mut self, time: u64) {
self.connect_timeout = Duration::from_millis(time);
}
#[deprecated(
since = "0.0.54",
note = "Renamed to add_trusted_certificate_der() to correctly reflect DER format"
)]
pub fn add_trusted_certificate_pem(&mut self, certificate: Vec<u8>) {
self.add_trusted_certificate_der(certificate);
}
pub fn add_trusted_certificate_der(&mut self, certificate: Vec<u8>) {
self.certificates.push(certificate);
}
#[deprecated(
since = "0.0.54",
note = "Use trusted_certificates() instead which returns &[Vec<u8>]"
)]
pub fn get_trusted_certificates(&self) -> &Vec<Vec<u8>> {
&self.certificates
}
pub fn trusted_certificates(&self) -> &[Vec<u8>] {
&self.certificates
}
pub fn set_redirect_policy(&mut self, policy: RedirectPolicy) {
self.redirect_policy = policy;
}
pub fn set_proxy(&mut self, proxy: Option<(Protocol, String)>) {
match proxy {
None => self.proxy = None,
Some((protocol, address)) => {
let proxy = Proxy { protocol, address };
self.proxy = Some(proxy);
}
}
}
pub fn build<DReq: product_os_http_body::Body, DRes: product_os_http_body::Body>(
&self,
client: &mut impl ProductOSClient<DReq, DRes>,
) {
client.build(self)
}
#[allow(dead_code)]
pub(crate) fn new_request<
DReq: product_os_http_body::Body,
DRes: product_os_http_body::Body,
>(
&self,
method: Method,
url: &str,
client: &mut impl ProductOSClient<DReq, DRes>,
) -> ProductOSRequest<DReq> {
client.new_request(method, url)
}
#[allow(dead_code)]
pub(crate) async fn request<
DReq: product_os_http_body::Body,
DRes: product_os_http_body::Body,
>(
&self,
r: ProductOSRequest<DReq>,
client: &mut impl ProductOSClient<DReq, DRes>,
) -> Result<ProductOSResponse<DRes>, ProductOSRequestError> {
client.request(r).await
}
#[allow(dead_code)]
pub(crate) async fn request_simple<
DReq: product_os_http_body::Body,
DRes: product_os_http_body::Body,
>(
&self,
method: Method,
url: &str,
client: &mut impl ProductOSClient<DReq, DRes>,
) -> Result<ProductOSResponse<DRes>, ProductOSRequestError> {
client.request_simple(method, url).await
}
#[allow(dead_code)]
pub(crate) async fn request_raw<
DReq: product_os_http_body::Body,
DRes: product_os_http_body::Body,
>(
&self,
r: Request<DReq>,
client: &mut impl ProductOSClient<DReq, DRes>,
) -> Result<ProductOSResponse<DRes>, ProductOSRequestError> {
client.request_raw(r).await
}
}
#[cfg(any(feature = "request", feature = "request_std"))]
impl Default for ProductOSRequester {
fn default() -> Self {
Self {
headers: product_os_http::header::HeaderMap::new(),
secure: true,
timeout: Duration::from_millis(1000),
connect_timeout: Duration::from_millis(1000),
certificates: vec![],
trust_all_certificates: false,
trust_any_certificate_for_hostname: false,
proxy: None,
redirect_policy: RedirectPolicy::Default,
}
}
}