1#![no_std]
2extern crate no_std_compat as std;
3
4use core::fmt::Debug;
5use std::prelude::v1::*;
6
7use async_trait::async_trait;
8use std::collections::BTreeMap;
9use std::str::FromStr;
10use std::time::Duration;
11
12#[cfg(any(feature = "method", feature = "method_std"))]
13use serde::{ Serialize, Deserialize };
14
15#[cfg(any(feature = "request", feature = "response", feature = "request_std", feature = "response_std"))]
16pub use product_os_http::{
17 Request, Response,
18 header::{ HeaderMap, HeaderName, HeaderValue },
19 StatusCode,
20 Uri,
21 response::Parts
22};
23
24#[cfg(any(feature = "request", feature = "response", feature = "request_std", feature = "response_std"))]
25pub use product_os_http_body::*;
26
27
28#[cfg(any(feature = "method", feature = "method_std"))]
29pub use product_os_http::method::Method as HttpMethod;
30
31#[cfg(any(feature = "request", feature = "request_std"))]
32use product_os_http::request;
33
34#[cfg(any(feature = "request", feature = "request_std"))]
35use bytes::Bytes;
36
37#[cfg(any(feature = "request", feature = "request_std"))]
38use futures_core::Stream;
39
40
41#[cfg(any(feature = "request", feature = "request_std"))]
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub enum Protocol {
44 SOCKS5,
45 HTTP,
46 HTTPS,
47 ALL
48}
49
50#[cfg(any(feature = "request", feature = "request_std"))]
51#[derive(Clone, Debug, PartialEq, Eq)]
52pub struct Proxy {
53 pub protocol: Protocol,
54 pub address: String
55}
56
57
58#[cfg(any(feature = "request", feature = "request_std"))]
59#[derive(Clone, Debug, PartialEq, Eq)]
60pub enum RedirectPolicy {
61 None,
62 Limit(usize),
63 Default
64}
65
66#[cfg(any(feature = "method", feature = "method_std"))]
67#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
68pub enum Method {
69 GET,
70 POST,
71 PATCH,
72 PUT,
73 DELETE,
74 TRACE,
75 HEAD,
76 OPTIONS,
77 CONNECT,
78 ANY
79}
80
81#[cfg(any(feature = "method", feature = "method_std"))]
82impl Method {
83 pub fn to_http_method(&self) -> product_os_http::method::Method {
84 match self {
85 Method::GET => product_os_http::method::Method::GET,
86 Method::POST => product_os_http::method::Method::POST,
87 Method::PATCH => product_os_http::method::Method::PATCH,
88 Method::PUT => product_os_http::method::Method::PUT,
89 Method::DELETE => product_os_http::method::Method::DELETE,
90 Method::TRACE => product_os_http::method::Method::TRACE,
91 Method::HEAD => product_os_http::method::Method::HEAD,
92 Method::OPTIONS => product_os_http::method::Method::OPTIONS,
93 Method::CONNECT => product_os_http::method::Method::CONNECT,
94 Method::ANY => product_os_http::method::Method::GET
95 }
96 }
97
98 pub fn from_http_method(method: &product_os_http::Method) -> Self {
99 match method {
100 &product_os_http::method::Method::GET => Method::GET,
101 &product_os_http::method::Method::POST => Method::POST,
102 &product_os_http::method::Method::PATCH => Method::PATCH,
103 &product_os_http::method::Method::PUT => Method::PUT,
104 &product_os_http::method::Method::DELETE => Method::DELETE,
105 &product_os_http::method::Method::TRACE => Method::TRACE,
106 &product_os_http::method::Method::HEAD => Method::HEAD,
107 &product_os_http::method::Method::OPTIONS => Method::OPTIONS,
108 &product_os_http::method::Method::CONNECT => Method::CONNECT,
109 _ => Method::ANY
110 }
111 }
112
113 pub fn from_str(method: &str) -> Self {
114 match method {
115 "GET" => Method::GET,
116 "POST" => Method::POST,
117 "PATCH" => Method::PATCH,
118 "PUT" => Method::PUT,
119 "DELETE" => Method::DELETE,
120 "TRACE" => Method::TRACE,
121 "HEAD" => Method::HEAD,
122 "OPTIONS" => Method::OPTIONS,
123 "CONNECT" => Method::CONNECT,
124 _ => Method::ANY
125 }
126 }
127}
128
129
130
131
132#[cfg(any(feature = "request", feature = "request_std"))]
133pub enum BodyType {
134 Json,
135 Form
136}
137
138
139
140#[cfg(any(feature = "request", feature = "request_std"))]
141#[derive(Debug)]
142pub enum ProductOSRequestError {
143 Error(String),
144 None
145}
146
147#[cfg(any(feature = "request", feature = "request_std"))]
148impl std::fmt::Display for ProductOSRequestError {
149 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
150 match &self {
151 ProductOSRequestError::Error(m) => write!(f, "{}", m),
152 ProductOSRequestError::None => write!(f, "No error")
153 }
154 }
155}
156
157
158#[cfg(any(feature = "request", feature = "request_std"))]
159pub struct ProductOSRequest<DReq> {
160 url: Uri,
161 method: Method,
162
163 headers: BTreeMap<String, HeaderValue>,
164 bearer_auth: Option<String>,
165
166 query: BTreeMap<String, String>,
167
168 body: Option<DReq>,
169
170 content_type: Option<BodyType>,
171}
172
173
174#[cfg(any(feature = "request", feature = "request_std"))]
175impl<DReq: product_os_http_body::Body> ProductOSRequest<DReq> {
176 fn new(method: Method, url: &str) -> Self {
177 let uri = match Uri::from_str(url) {
178 Ok(u) => u,
179 Err(e) => {
180 tracing::error!("Uri is invalid: {:?}", e);
181 Uri::default()
182 }
183 };
184
185 Self {
186 url: uri,
187 method,
188
189 headers: BTreeMap::new(),
190 bearer_auth: None,
191
192 query: BTreeMap::new(),
193
194 body: None,
195
196 content_type: None,
197 }
198 }
199
200 fn from_request(r: Request<DReq>) -> Self {
201 let uri = r.uri().to_owned();
202 let method = Method::from_http_method(r.method());
203
204 let mut headers = BTreeMap::new();
205 let mut bearer_auth = None;
206 let mut content_type = None;
207
208 for (name, value) in r.headers() {
209 let name = name.to_string();
210
211 if name.as_str().to_lowercase() == "authorization" {
212 match value.to_str() {
213 Ok(val) => { bearer_auth = Some(val.to_string()); }
214 Err(_) => {}
215 }
216 }
217 else if name.as_str().to_lowercase() == "content-type" {
218 match value.to_str() {
219 Ok(val) => {
220 content_type = match val {
221 "application/json" => Some(BodyType::Json),
222 "application/www-form-url-encoded" => Some(BodyType::Form),
223 _ => None
224 }
225 }
226 Err(_) => {}
227 }
228 }
229 else {
230 headers.insert(name.to_string(), value.to_owned());
231 }
232 }
233
234 let query = match uri.query() {
235 None => BTreeMap::new(),
236 Some(query) => {
237 let mut query_tree = BTreeMap::new();
238
239 let query_parts = query.split("&").collect::<Vec<&str>>();
240 for query_part in query_parts {
241 let query_sub_parts = query_part.split("=").collect::<Vec<&str>>();
242 match query_sub_parts.get(0) {
243 None => {}
244 Some(key) => {
245 match query_sub_parts.get(1) {
246 None => {}
247 Some(value) => { query_tree.insert(key.to_string(), value.to_string()); }
248 }
249 }
250 }
251 }
252
253 query_tree
254 }
255 };
256
257 let body = r.into_body();
258
259 Self {
260 url: uri,
261 method,
262
263 headers,
264 bearer_auth,
265
266 query,
267
268 body: Some(body),
269
270 content_type
271 }
272 }
273
274 pub fn add_header(&mut self, name: &str, value: &str, is_sensitive: bool) {
275 let header_name = HeaderName::try_from(name).unwrap();
276 let mut header_value = HeaderValue::try_from(value).unwrap();
277 header_value.set_sensitive(is_sensitive);
278
279 self.headers.insert(header_name.as_str().to_string(), header_value);
280 }
281
282 pub fn add_headers(&mut self, headers: BTreeMap<String, String>, are_sensitive: bool) {
283 for (name, value) in headers {
284 self.add_header(name.as_str(), value.as_str(), are_sensitive.to_owned());
285 }
286 }
287
288 pub fn bearer_auth(&mut self, token: String) {
289 self.bearer_auth = Some(token);
290 }
291
292 pub fn add_param(&mut self, key: String, value: String) {
293 self.query.insert(key, value);
294 }
295
296 pub fn add_params(&mut self, params: BTreeMap<String, String>) {
297 for (name, value) in params {
298 self.add_param(name, value);
299 }
300 }
301
302 pub fn set_query(&mut self, query: BTreeMap<String, String>) {
303 self.query = query;
304 }
305
306 pub fn set_body(&mut self, data: DReq) {
307 self.body = Some(data);
308 }
309
310 fn build(self) -> Result<Request<impl product_os_http_body::Body>, ProductOSRequestError> {
311 let mut request = Request::builder();
312
313 let mut query_string = String::new();
314 for (key, value) in self.query {
315 query_string.push_str(key.as_str());
316 query_string.push_str("=");
317 query_string.push_str(value.as_str());
318 query_string.push_str("&");
319 }
320
321 match query_string.strip_suffix("&") {
322 None => {},
323 Some(q) => { query_string = q.to_string(); }
324 };
325
326 let url = if self.url.to_string().contains("?") {
327 let mut u = self.url.to_string();
328 u.push_str("&");
329 u.push_str(query_string.as_str());
330 u
331 }
332 else {
333 let mut u = self.url.to_string();
334 u.push_str("?");
335 u.push_str(query_string.as_str());
336 u
337 };
338
339 let mut uri = match Uri::from_str(url.as_str()) {
340 Ok(u) => u,
341 Err(e) => {
342 tracing::error!("Invalid uri: {:?}", e);
343 Uri::default()
344 }
345 };
346
347 request = request.uri(uri);
348
349 let method = self.method.to_http_method();
350 request = request.method(method);
351
352 for (name, value) in self.headers {
353 request = request.header(name, value);
354 }
355
356 match self.bearer_auth.clone() {
357 Some(a) => {
358 match HeaderValue::from_str(a.as_str()) {
359 Ok(auth) => { request = request.header(String::from("authorization"), auth); }
360 Err(e) => { tracing::error!("Invalid bearer auth for header"); }
361 }
362 },
363 None => {}
364 }
365
366 match self.body {
367 Some(body) => {
368 match self.content_type {
369 Some(BodyType::Json) => { request = request.header("content-type", "application/json"); },
370 Some(BodyType::Form) => { request = request.header("content-type", "application/www-form-url-encoded"); },
371 _ => ()
372 };
373
374 match request.body(body) {
375 Ok(req) => Ok(req),
376 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
377 }
378 },
379 None => Err(ProductOSRequestError::Error(String::from("No body provided")))
380 }
381 }
382}
383
384#[cfg(any(feature = "request", feature = "request_std"))]
385impl ProductOSRequest<BodyBytes> {
386 pub fn into_body(self) -> Option<BodyBytes> {
387 match self.body {
388 Some(body) => Some(body),
389 None => None
390 }
391 }
392}
393
394
395
396
397#[cfg(any(feature = "response", feature = "response_std"))]
398pub struct ProductOSResponse<DRes: product_os_http_body::Body> {
399 response_url: String,
400 response_async: Option<Response<DRes>>,
401}
402
403
404#[cfg(any(feature = "response", feature = "response_std"))]
405impl<DRes: product_os_http_body::Body> ProductOSResponse<DRes> {
406 pub fn new<D>(r: DRes, url: String) -> Self {
407 Self {
408 response_url: url,
409 response_async: Some(Response::new(r)),
410 }
411 }
412
413 pub fn parts(self) -> (Parts, DRes) {
414 self.response_async.unwrap().into_parts()
415 }
416
417 pub fn status(&self) -> StatusCode {
418 self.response_async.as_ref().unwrap().status()
419 }
420
421 pub fn status_code(&self) -> u16 {
422 self.status().as_u16()
423 }
424
425 pub fn get_headers(&self) -> BTreeMap<String, String> {
426 let mut map = BTreeMap::new();
427
428 let headers = self.response_async.as_ref().unwrap().headers();
429
430 for (name, value) in headers {
431 map.insert(name.to_string(), value.to_str().unwrap().to_string());
432 }
433
434 map
435 }
436
437 pub fn response_url(&self) -> &str {
438 &self.response_url
439 }
440
441 pub fn into_body(self) -> Option<DRes> {
442 match self.response_async {
443 None => None,
444 Some(response) => Some(response.into_body()),
445 }
446 }
447
448 }
486
487
488
489
490
491#[cfg(any(feature = "request", feature = "request_std"))]
492#[derive(Clone)]
493pub struct ProductOSRequester {
494 headers: product_os_http::header::HeaderMap,
495 secure: bool,
496
497 timeout: Duration,
498 connect_timeout: Duration,
499
500 certificates: Vec<Vec<u8>>,
501
502 trust_all_certificates: bool,
503 trust_any_certificate_for_hostname: bool,
504
505 proxy: Option<Proxy>,
506
507 redirect_policy: RedirectPolicy
508}
509
510
511#[cfg(any(feature = "request", feature = "request_std"))]
512impl ProductOSRequester {
513 pub fn new() -> Self {
514 Self {
515 headers: product_os_http::header::HeaderMap::new(),
516 secure: true,
517 timeout: Duration::from_millis(1000),
518 connect_timeout: Duration::from_millis(1000),
519 certificates: vec!(),
520 trust_all_certificates: false,
521 trust_any_certificate_for_hostname: false,
522 proxy: None,
523 redirect_policy: RedirectPolicy::Default
524 }
525 }
526
527 pub fn add_header(&mut self, name: &str, value: &str, is_sensitive: bool) {
528 let header_name = product_os_http::header::HeaderName::try_from(name).unwrap();
529 let mut header_value = product_os_http::header::HeaderValue::try_from(value).unwrap();
530 header_value.set_sensitive(is_sensitive);
531
532 self.headers.append(header_name, header_value);
533 }
534
535 pub fn set_headers(&mut self, headers: BTreeMap<String, String>) {
536 let mut header_map = product_os_http::header::HeaderMap::new();
537
538 for (name, value) in headers {
539 let header_name = product_os_http::header::HeaderName::try_from(name).unwrap();
540 header_map.insert(header_name, product_os_http::header::HeaderValue::try_from(value).unwrap());
541 }
542
543 self.headers = header_map;
544 }
545
546 pub fn force_secure(&mut self, sec: bool) {
547 self.secure = sec;
548 }
549
550 pub fn trust_all_certificates(&mut self, trust: bool) {
551 self.trust_all_certificates = trust;
552 }
553
554 pub fn trust_any_certificate_for_hostname(&mut self, trust: bool) {
555 self.trust_any_certificate_for_hostname = trust;
556 }
557
558 pub fn set_timeout(&mut self, time: u64) {
559 self.timeout = Duration::from_millis(time);
560 }
561
562 pub fn set_connect_timeout(&mut self, time: u64) {
563 self.connect_timeout = Duration::from_millis(time);
564 }
565
566 pub fn add_trusted_certificate_pem(&mut self, certificate: Vec<u8>) {
567 self.certificates.push(certificate);
568 }
569
570 pub fn get_trusted_certificates(&self) -> &Vec<Vec<u8>> {
571 &self.certificates
572 }
573
574 pub fn set_redirect_policy(&mut self, policy: RedirectPolicy) {
575 self.redirect_policy = policy;
576 }
577
578 pub fn set_proxy(&mut self, proxy: Option<(Protocol, String)>) {
579 match proxy {
580 None => self.proxy = None,
581 Some((protocol, address)) => {
582 let proxy = Proxy {
583 protocol,
584 address
585 };
586
587 self.proxy = Some(proxy);
588 }
589 }
590 }
591
592 pub fn build<DReq: product_os_http_body::Body, DRes: product_os_http_body::Body>(&self, client: &mut impl ProductOSClient<DReq, DRes>) {
593 client.build(&self)
594 }
595
596 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> {
597 client.new_request(method, url)
598 }
599
600 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> {
601 client.request(r).await
602 }
603
604 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> {
605 client.request_simple(method, url).await
606 }
607
608 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> {
609 client.request_raw(r).await
610 }
611}
612
613
614#[cfg(any(feature = "request", feature = "request_std"))]
615#[async_trait]
616pub trait ProductOSClient<DReq: product_os_http_body::Body, DRes: product_os_http_body::Body> {
617 fn build(&mut self, requester: &ProductOSRequester);
618
619 fn new_request(&self, method: Method, url: &str) -> ProductOSRequest<DReq>;
620 async fn request(&self, r: ProductOSRequest<DReq>) -> Result<ProductOSResponse<DRes>, ProductOSRequestError>;
621 #[cfg(feature = "stream")]
622 async fn request_stream(&self, r: ProductOSRequest<DReq>) -> Result<ProductOSResponse<DRes>, ProductOSRequestError>;
623 async fn request_simple(&self, method: Method, url: &str) -> Result<ProductOSResponse<DRes>, ProductOSRequestError>;
624 async fn request_raw(&self, r: Request<DReq>) -> Result<ProductOSResponse<DRes>, ProductOSRequestError>;
625 #[cfg(feature = "stream")]
626 async fn request_stream_raw(&self, r: Request<DReq>) -> Result<ProductOSResponse<DRes>, ProductOSRequestError>;
627
628 #[cfg(feature = "json")]
629 async fn set_body_json(&self, r: &mut ProductOSRequest<DReq>, json: serde_json::Value);
630
631 #[cfg(feature = "form")]
632 async fn set_body_form(&self, r: &mut ProductOSRequest<DReq>, form: &str);
633
634 async fn text(&self, r: ProductOSResponse<DRes>) -> Result<String, ProductOSRequestError>;
635 #[cfg(feature = "json")]
636 async fn json(&self, r: ProductOSResponse<DRes>) -> Result<serde_json::Value, ProductOSRequestError>;
637
638 async fn bytes(&self, r: ProductOSResponse<DRes>) -> Result<bytes::Bytes, ProductOSRequestError>;
639 async fn next_bytes(&self, r: &mut ProductOSResponse<DRes>) -> Result<Option<bytes::Bytes>, ProductOSRequestError>;
640 async fn to_stream(&self, r: ProductOSResponse<product_os_http_body::BodyBytes>) -> Result<impl Stream<Item = Result<bytes::Bytes, BodyError>>, ProductOSRequestError>;
641}
642
643
644
645#[cfg(all(feature = "request_std", feature = "std"))]
650#[derive(Clone)]
651pub struct ProductOSRequestClient {
652 client: reqwest::Client
653}
654
655#[cfg(all(feature = "request_std", feature = "std"))]
656impl ProductOSRequestClient {
657 pub fn new() -> Self {
658 Self {
659 client: reqwest::Client::new()
660 }
661 }
662
663 fn build_request<DReq: product_os_http_body::Body>(&self, request: ProductOSRequest<DReq>) -> Result<reqwest::Request, ProductOSRequestError> {
664 let method = match request.method {
665 Method::GET => reqwest::Method::GET,
666 Method::POST => reqwest::Method::POST,
667 Method::PATCH => reqwest::Method::PATCH,
668 Method::PUT => reqwest::Method::PUT,
669 Method::DELETE => reqwest::Method::DELETE,
670 Method::TRACE => reqwest::Method::TRACE,
671 Method::HEAD => reqwest::Method::HEAD,
672 Method::OPTIONS => reqwest::Method::OPTIONS,
673 Method::CONNECT => reqwest::Method::CONNECT,
674 Method::ANY => reqwest::Method::GET
675 };
676
677 let mut r = self.client.request(method, request.url.to_string());
678
679 let mut query = vec![];
680 for (key, value) in &request.query {
681 query.push((key.to_owned(), value.to_owned()));
682 }
683 r = r.query(query.as_slice());
684
685 let mut headers = reqwest::header::HeaderMap::new();
686 for (key, value) in &request.headers {
687 match reqwest::header::HeaderName::from_str(key.as_str()) {
688 Ok(k) => {
689 match value.to_str() {
690 Ok(val) => {
691 match reqwest::header::HeaderValue::from_str(val) {
692 Ok(v) => { headers.insert(k, v); }
693 Err(_) => {}
694 }
695 }
696 Err(_) => {}
697 }
698 }
699 Err(_) => {}
700 }
701 }
702
703 r = r.headers(headers);
704
705 match r.build() {
706 Ok(req) => Ok(req),
707 Err(e) => {
708 tracing::error!("Failed to create request: {:?}", e);
709 Err(ProductOSRequestError::Error(e.to_string()))
710 }
711 }
712 }
713
714 fn build_request_with_body(&self, request: ProductOSRequest<BodyBytes>) -> Result<reqwest::Request, ProductOSRequestError> {
715 let method = match request.method {
716 Method::GET => reqwest::Method::GET,
717 Method::POST => reqwest::Method::POST,
718 Method::PATCH => reqwest::Method::PATCH,
719 Method::PUT => reqwest::Method::PUT,
720 Method::DELETE => reqwest::Method::DELETE,
721 Method::TRACE => reqwest::Method::TRACE,
722 Method::HEAD => reqwest::Method::HEAD,
723 Method::OPTIONS => reqwest::Method::OPTIONS,
724 Method::CONNECT => reqwest::Method::CONNECT,
725 Method::ANY => reqwest::Method::GET
726 };
727
728 let mut r = self.client.request(method, request.url.to_string());
729
730 let mut query = vec![];
731 for (key, value) in &request.query {
732 query.push((key.to_owned(), value.to_owned()));
733 }
734 r = r.query(query.as_slice());
735
736 let mut headers = reqwest::header::HeaderMap::new();
737 for (key, value) in &request.headers {
738 match reqwest::header::HeaderName::from_str(key.as_str()) {
739 Ok(k) => {
740 match value.to_str() {
741 Ok(val) => {
742 match reqwest::header::HeaderValue::from_str(val) {
743 Ok(v) => { headers.insert(k, v); }
744 Err(_) => {}
745 }
746 }
747 Err(_) => {}
748 }
749 }
750 Err(_) => {}
751 }
752 }
753
754 r = r.headers(headers);
755
756 match request.body {
757 None => {}
758 Some(b) => {
759 r = r.body(reqwest::Body::wrap(b));
760 }
761 }
762
763 match r.build() {
764 Ok(req) => Ok(req),
765 Err(e) => {
766 tracing::error!("Failed to create request: {:?}", e);
767 Err(ProductOSRequestError::Error(e.to_string()))
768 }
769 }
770 }
771}
772
773#[cfg(all(feature = "request_std", feature = "std"))]
774#[async_trait]
775impl ProductOSClient<product_os_http_body::BodyBytes, product_os_http_body::BodyBytes> for ProductOSRequestClient {
776 fn build(&mut self, requester: &ProductOSRequester) {
777 let mut header_map = reqwest::header::HeaderMap::new();
778 for (name, value) in requester.headers.iter() {
779 let name = name.to_string();
780 match value.to_str() {
781 Ok(val) => {
782 match reqwest::header::HeaderName::from_bytes(name.as_bytes()) {
783 Ok(name) => {
784 match reqwest::header::HeaderValue::from_str(val) {
785 Ok(value) => { header_map.insert(name, value); }
786 Err(_) => {}
787 }
788 }
789 Err(_) => {}
790 }
791 }
792 Err(_) => {}
793 };
794 }
795
796 let mut builder = reqwest::ClientBuilder::new()
797 .default_headers(header_map)
798 .https_only(requester.secure.to_owned())
799
800 .timeout(requester.timeout)
801 .connect_timeout(requester.connect_timeout)
802
803 .danger_accept_invalid_certs(requester.trust_all_certificates.to_owned())
804 .cookie_store(true)
807 .gzip(true)
808 .brotli(true);
809
810 for cert in &requester.certificates {
811 let certificate = reqwest::Certificate::from_der(cert.as_slice()).unwrap();
812 builder = builder.add_root_certificate(certificate);
813 }
814
815 match &requester.proxy {
816 None => {}
817 Some(proxy) => {
818 match proxy.protocol {
819 Protocol::SOCKS5 => {
820 let mut address_string = String::from("socks5://");
821 address_string.push_str(proxy.address.as_str());
822
823 match reqwest::Proxy::http(address_string.to_owned()) {
824 Ok(proxy) => {
825 tracing::trace!("Async proxy set successfully: {:?}", address_string);
826 builder = builder.proxy(proxy.to_owned());
827 },
828 Err(e) => {
829 tracing::error!("Failed to setup proxy: {:?}", e);
830 }
831 }
832 }
833 Protocol::HTTP => {
834 let mut address_string = String::from("product_os_http://");
835 address_string.push_str(proxy.address.as_str());
836
837 match reqwest::Proxy::http(address_string.to_owned()) {
838 Ok(proxy) => {
839 tracing::info!("Async proxy set successfully: {:?}", address_string);
840 builder = builder.proxy(proxy.to_owned());
841 },
842 Err(e) => {
843 tracing::error!("Failed to setup proxy: {:?}", e);
844 }
845 }
846 }
847 Protocol::HTTPS => {
848 let mut address_string = String::from("https://");
849 address_string.push_str(proxy.address.as_str());
850
851 match reqwest::Proxy::https(address_string.to_owned()) {
852 Ok(proxy) => {
853 tracing::info!("Async proxy set successfully: {:?}", address_string);
854 builder = builder.proxy(proxy.to_owned());
855 },
856 Err(e) => {
857 tracing::error!("Failed to setup proxy: {:?}", e);
858 }
859 }
860 },
861 Protocol::ALL => {
862 let mut address_string = String::from("product_os_http://");
863 address_string.push_str(proxy.address.as_str());
864
865 match reqwest::Proxy::all(address_string.to_owned()) {
866 Ok(proxy) => {
867 tracing::info!("Async proxy set successfully: {:?}", address_string);
868 builder = builder.proxy(proxy.to_owned());
869 },
870 Err(e) => {
871 tracing::error!("Failed to setup proxy: {:?}", e);
872 }
873 }
874 }
875 }
876 }
877 }
878
879 let redirect_policy = match requester.redirect_policy.to_owned() {
880 RedirectPolicy::None => reqwest::redirect::Policy::none(),
881 RedirectPolicy::Limit(hops) => reqwest::redirect::Policy::limited(hops),
882 RedirectPolicy::Default => reqwest::redirect::Policy::default()
883 };
884
885 builder = builder.redirect(redirect_policy);
886
887 tracing::trace!("Updated async client with configuration: {:?}", builder);
888
889 self.client = builder.build().unwrap();
890 }
891
892 fn new_request(&self, method: Method, url: &str) -> ProductOSRequest<product_os_http_body::BodyBytes> {
893 ProductOSRequest::new(method, url)
894 }
895
896 async fn request(&self, r: ProductOSRequest<product_os_http_body::BodyBytes>) -> Result<ProductOSResponse<product_os_http_body::BodyBytes>, ProductOSRequestError> {
897 match self.build_request_with_body(r) {
898 Ok(request) => {
899 match self.client.execute(request).await {
900 Ok(response) => {
901 let url = response.url().to_string();
902 let body = match response.bytes().await {
903 Ok(b) => { product_os_http_body::BodyBytes::new(Bytes::from(b)) }
904 Err(e) => { product_os_http_body::BodyBytes::new(Bytes::new()) }
905 };
906 Ok(ProductOSResponse::new::<Bytes>(body, url))
907 },
908 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
909 }
910 }
911 Err(e) => Err(e)
912 }
913 }
914
915
916 #[cfg(feature = "stream")]
917 async fn request_stream(&self, r: ProductOSRequest<product_os_http_body::BodyBytes>) -> Result<ProductOSResponse<product_os_http_body::BodyBytes>, ProductOSRequestError> {
918 match self.build_request_with_body(r) {
919 Ok(request) => {
920 match self.client.execute(request).await {
921 Ok(response) => {
922 let url = response.url().to_string();
923 let stream = response.bytes_stream();
924 let body = BodyBytes::new_stream(stream);
925
926 Ok(ProductOSResponse::new::<Bytes>(body, url))
927 },
928 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
929 }
930 }
931 Err(e) => Err(e)
932 }
933 }
934
935 async fn request_simple(&self, method: Method, url: &str) -> Result<ProductOSResponse<product_os_http_body::BodyBytes>, ProductOSRequestError> {
936 let r = ProductOSRequest::<product_os_http_body::BodyBytes>::new(method, url);
937 match self.build_request_with_body(r) {
938 Ok(request) => {
939 match self.client.execute(request).await {
940 Ok(response) => {
941 let url = response.url().to_string();
942 let body = match response.bytes().await {
943 Ok(b) => { product_os_http_body::BodyBytes::new(Bytes::from(b)) }
944 Err(e) => { product_os_http_body::BodyBytes::new(Bytes::new()) }
945 };
946 Ok(ProductOSResponse::new::<Bytes>(body, url))
947 },
948 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
949 }
950 }
951 Err(e) => Err(e)
952 }
953 }
954
955 async fn request_raw(&self, r: Request<product_os_http_body::BodyBytes>) -> Result<ProductOSResponse<product_os_http_body::BodyBytes>, ProductOSRequestError> {
956 let req = ProductOSRequest::from_request(r);
957 match self.build_request_with_body(req) {
958 Ok(request) => {
959 match self.client.execute(request).await {
960 Ok(response) => {
961 let url = response.url().to_string();
962 let body = match response.bytes().await {
963 Ok(b) => { product_os_http_body::BodyBytes::new(Bytes::from(b)) }
964 Err(e) => { product_os_http_body::BodyBytes::new(Bytes::new()) }
965 };
966 Ok(ProductOSResponse::new::<Bytes>(body, url))
967 },
968 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
969 }
970 }
971 Err(e) => Err(e)
972 }
973 }
974
975 #[cfg(feature = "stream")]
976 async fn request_stream_raw(&self, r: Request<product_os_http_body::BodyBytes>) -> Result<ProductOSResponse<product_os_http_body::BodyBytes>, ProductOSRequestError> {
977 let req = ProductOSRequest::from_request(r);
978 match self.build_request_with_body(req) {
979 Ok(request) => {
980 match self.client.execute(request).await {
981 Ok(response) => {
982 let url = response.url().to_string();
983 let stream = response.bytes_stream();
984 let body = BodyBytes::new_stream(stream);
985
986 Ok(ProductOSResponse::new::<Bytes>(body, url))
987 },
988 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
989 }
990 }
991 Err(e) => Err(e)
992 }
993 }
994
995 #[cfg(feature = "json")]
996 async fn set_body_json(&self, r: &mut ProductOSRequest::<product_os_http_body::BodyBytes>, json: serde_json::Value) {
997 let json_string = json.to_string();
998 let body = product_os_http_body::BodyBytes::new(bytes::Bytes::from(json_string));
999 r.body = Some(body);
1000 }
1001
1002 #[cfg(feature = "form")]
1003 async fn set_body_form(&self, r: &mut ProductOSRequest::<product_os_http_body::BodyBytes>, form: &str) {
1004 let form_string = serde_urlencoded::to_string(form).unwrap();
1005 let body = product_os_http_body::BodyBytes::new(bytes::Bytes::from(form_string));
1006 r.body = Some(body);
1007 }
1008
1009 async fn text(&self, r: ProductOSResponse<product_os_http_body::BodyBytes>) -> Result<String, ProductOSRequestError> {
1010 match r.response_async {
1011 Some(res) => {
1012 match <product_os_http_body::BodyBytes as Clone>::clone(&res.body()).collect().await {
1013 Ok(body) => {
1014 match String::from_utf8(body.to_bytes().as_ref().to_vec()) {
1015 Ok(res) => Ok(res),
1016 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
1017 }
1018 }
1019 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
1020 }
1021 }
1022 None => Err(ProductOSRequestError::Error(String::from("No response found")))
1023 }
1024 }
1025
1026 #[cfg(feature = "json")]
1027 async fn json(&self, r: ProductOSResponse<product_os_http_body::BodyBytes>) -> Result<serde_json::Value, ProductOSRequestError> {
1028 match r.response_async {
1029 Some(res) => {
1030 match <product_os_http_body::BodyBytes as Clone>::clone(&res.body()).collect().await {
1031 Ok(body) => {
1032 match String::from_utf8(body.to_bytes().as_ref().to_vec()) {
1033 Ok(res) => {
1034 match serde_json::Value::try_from(res) {
1035 Ok(res) => Ok(res),
1036 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
1037 }
1038 },
1039 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
1040 }
1041 }
1042 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
1043 }
1044 }
1045 None => Err(ProductOSRequestError::Error(String::from("No response found")))
1046 }
1047 }
1048
1049 async fn bytes(&self, r: ProductOSResponse<product_os_http_body::BodyBytes>) -> Result<bytes::Bytes, ProductOSRequestError> {
1050 match r.response_async {
1051 Some(res) => {
1052 match <product_os_http_body::BodyBytes as Clone>::clone(&res.body()).collect().await {
1053 Ok(body) => Ok(Bytes::from(body.to_bytes())),
1054 Err(e) => Err(ProductOSRequestError::Error(e.to_string()))
1055 }
1056 }
1057 None => Err(ProductOSRequestError::Error(String::from("No response found")))
1058 }
1059 }
1060
1061 async fn next_bytes(&self, r: &mut ProductOSResponse<product_os_http_body::BodyBytes>) -> Result<Option<bytes::Bytes>, ProductOSRequestError> {
1062 match r.response_async {
1063 Some(ref mut res) => {
1064 loop {
1066 if let Some(res) = res.body_mut().frame().await {
1067 let frame = match res {
1068 Ok(frame) => frame,
1069 Err(e) => return Err(ProductOSRequestError::Error(e.to_string()))
1070 };
1071 if let Ok(buf) = frame.into_data() {
1072 return Ok(Some(buf));
1073 }
1074 } else {
1076 return Ok(None);
1077 }
1078 }
1079 }
1080 None => Err(ProductOSRequestError::Error(String::from("No response found")))
1081 }
1082 }
1083
1084 async fn to_stream(&self, r: ProductOSResponse<product_os_http_body::BodyBytes>) -> Result<impl Stream<Item = Result<bytes::Bytes, BodyError>>, ProductOSRequestError> {
1085 match r.response_async {
1086 Some(res) => {
1087 Ok(BodyDataStream::new(res.into_body()))
1088 }
1089 None => Err(ProductOSRequestError::Error(String::from("No response found")))
1090 }
1091 }
1092}
1093
1094
1095