whatsapp_rust_ureq_http_client/
lib.rs1#![cfg(not(target_arch = "wasm32"))]
4
5use anyhow::Result;
6use async_trait::async_trait;
7use wacore::net::{HttpClient, HttpRequest, HttpResponse, StreamingHttpResponse};
8
9#[derive(Debug, Clone)]
12pub struct UreqHttpClient {
13 agent: ureq::Agent,
14}
15
16impl UreqHttpClient {
17 pub fn new() -> Self {
18 let agent = build_agent();
19 Self { agent }
20 }
21}
22
23impl Default for UreqHttpClient {
24 fn default() -> Self {
25 Self::new()
26 }
27}
28
29fn build_agent() -> ureq::Agent {
30 #[cfg(feature = "danger-skip-tls-verify")]
31 {
32 use ureq::config::Config;
33 use ureq::tls::TlsConfig;
34 Config::builder()
35 .tls_config(TlsConfig::builder().disable_verification(true).build())
36 .build()
37 .into()
38 }
39
40 #[cfg(not(feature = "danger-skip-tls-verify"))]
41 {
42 ureq::Agent::new_with_defaults()
43 }
44}
45
46#[async_trait]
47impl HttpClient for UreqHttpClient {
48 async fn execute(&self, request: HttpRequest) -> Result<HttpResponse> {
49 let agent = self.agent.clone();
50 tokio::task::spawn_blocking(move || {
52 let response = match request.method.as_str() {
53 "GET" => {
54 let mut req = agent.get(&request.url);
55 for (key, value) in &request.headers {
56 req = req.header(key, value);
57 }
58 req.call()?
59 }
60 "POST" => {
61 let mut req = agent.post(&request.url);
62 for (key, value) in &request.headers {
63 req = req.header(key, value);
64 }
65 if let Some(body) = request.body {
66 req.send(&body[..])?
67 } else {
68 req.send(&[])?
69 }
70 }
71 method => {
72 return Err(anyhow::anyhow!("Unsupported HTTP method: {}", method));
73 }
74 };
75
76 let status_code = response.status().as_u16();
77
78 let mut body = response.into_body();
80 let body_bytes = body.read_to_vec()?;
81
82 Ok(HttpResponse {
83 status_code,
84 body: body_bytes,
85 })
86 })
87 .await?
88 }
89
90 fn execute_streaming(&self, request: HttpRequest) -> Result<StreamingHttpResponse> {
91 let response = match request.method.as_str() {
95 "GET" => {
96 let mut req = self.agent.get(&request.url);
97 for (key, value) in &request.headers {
98 req = req.header(key, value);
99 }
100 req.call()?
101 }
102 method => {
103 return Err(anyhow::anyhow!(
104 "Streaming only supports GET, got: {}",
105 method
106 ));
107 }
108 };
109
110 let status_code = response.status().as_u16();
111 let reader = response.into_body().into_reader();
112
113 Ok(StreamingHttpResponse {
114 status_code,
115 body: Box::new(reader),
116 })
117 }
118}