1use crate::error::Error;
2
3pub struct HttpRequest {
4 pub url: String,
5 pub headers: Vec<(String, String)>,
6 pub body: String,
7}
8
9#[cfg(target_os = "wasi")]
10pub async fn http_post(request: &HttpRequest) -> Result<String, Error> {
11 use wstd::http::{Client, HeaderValue, Request};
12
13 let mut builder = Request::post(&request.url);
14 builder = builder.header("Content-Type", HeaderValue::from_static("application/json"));
15 for (key, value) in &request.headers {
16 let value = HeaderValue::from_str(value)
17 .map_err(|e| Error::Http(format!("Invalid header value for '{key}': {e}")))?;
18 builder = builder.header(key.as_str(), value);
19 }
20
21 let req = builder
22 .body(request.body.clone().into_bytes())
23 .map_err(|e| Error::Http(format!("Failed to build request: {e}")))?;
24
25 let client = Client::new();
26 let mut response = client
27 .send(req)
28 .await
29 .map_err(|e| Error::Http(format!("Request failed: {e}")))?;
30
31 response
32 .body_mut()
33 .str_contents()
34 .await
35 .map_err(|e| Error::Http(format!("Failed to read response: {e}")))
36 .map(|s| s.to_string())
37}
38
39#[cfg(not(target_os = "wasi"))]
40pub async fn http_post(request: &HttpRequest) -> Result<String, Error> {
41 let client = reqwest::Client::new();
42 let mut builder = client
43 .post(&request.url)
44 .header("Content-Type", "application/json");
45
46 for (key, value) in &request.headers {
47 builder = builder.header(key.as_str(), value.as_str());
48 }
49
50 let response = builder
51 .body(request.body.clone())
52 .send()
53 .await
54 .map_err(|e| Error::Http(format!("Request failed: {e}")))?;
55
56 response
57 .text()
58 .await
59 .map_err(|e| Error::Http(format!("Failed to read response: {e}")))
60}