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