wasi_net/reqwest/
request_builder.rs1#![allow(dead_code)]
2use http::StatusCode;
3use std::borrow::Cow;
4use std::collections::HashMap;
5use std::io::Write;
6
7use super::*;
8use crate::backend::utils::*;
9use crate::backend::Command as BackendCommand;
10use crate::backend::Response as BackendResponse;
11
12pub struct RequestBuilder {
13 pub(crate) method: http::Method,
14 pub(crate) url: url::Url,
15 pub(crate) client: Client,
16 pub(crate) headers: HashMap<String, String>,
17 pub(crate) request: Option<Body>,
18}
19
20impl RequestBuilder {
21 pub fn header<T>(mut self, header: http::header::HeaderName, value: T) -> Self
22 where
23 T: Into<Cow<'static, str>>,
24 {
25 self.headers
26 .insert(header.to_string(), value.into().to_string());
27 self
28 }
29
30 pub fn multipart(self, multipart: multipart::Form) -> RequestBuilder {
31 let mut builder = self.header(header::CONTENT_TYPE, "application/x-www-form-urlencoded");
32 builder.request = Some(Body::from(multipart.to_string()));
33 builder
34 }
35
36 pub fn bearer_auth<T>(self, token: T) -> RequestBuilder
37 where
38 T: std::fmt::Display,
39 {
40 let token = format!("{}", token);
41 if token.len() <= 0 {
42 return self;
43 }
44 let header_value = format!("Bearer {}", token);
45 self.header(header::AUTHORIZATION, header_value)
46 }
47
48 pub fn send(self) -> Result<Response, std::io::Error> {
49 let url = self.url.to_string();
50
51 let submit = BackendCommand::WebRequestVersion1 {
52 url,
53 method: self.method.to_string(),
54 headers: self
55 .headers
56 .iter()
57 .map(|(a, b)| (a.clone(), b.clone()))
58 .collect(),
59 body: self
60 .request
61 .iter()
62 .filter_map(|a| a.as_bytes())
63 .map(|a| a.to_vec())
64 .next(),
65 };
66 let mut submit = submit.serialize()?;
67 submit += "\n";
68
69 let mut file = std::fs::File::open("/dev/web")?;
70
71 let _ = file.write_all(submit.as_bytes());
72
73 let res = read_response(&mut file)?;
74 let (ok, redirected, status, status_text, headers, has_data) = match res {
75 BackendResponse::Error { msg } => {
76 return Err(std::io::Error::new(std::io::ErrorKind::Other, msg.as_str()));
77 }
78 BackendResponse::WebSocketVersion1 { .. } => {
79 return Err(std::io::Error::new(
80 std::io::ErrorKind::Other,
81 "server returned a web socket instead of a web request",
82 ));
83 }
84 BackendResponse::WebRequestVersion1 {
85 ok,
86 redirected,
87 status,
88 status_text,
89 headers,
90 has_data,
91 } => (ok, redirected, status, status_text, headers, has_data),
92 _ => {
93 return Err(std::io::Error::new(
94 std::io::ErrorKind::Other,
95 "the socket does not support this response type",
96 ));
97 }
98 };
99
100 let status = StatusCode::from_u16(status).map_err(|err| {
101 std::io::Error::new(
102 std::io::ErrorKind::Other,
103 format!("invalid status code returned by the server - {}", err).as_str(),
104 )
105 })?;
106
107 let data = if has_data {
108 let mut data = Vec::new();
109 read_to_end(&mut file, &mut data)?;
110 Some(data)
111 } else {
112 None
113 };
114
115 Ok(Response {
116 ok,
117 redirected,
118 status,
119 status_text,
120 headers,
121 pos: 0usize,
122 data,
123 })
124 }
125}