use crate::io::{empty, Empty};
use super::{
fields::header_map_to_wasi, method::to_wasi_method, Body, Error, HeaderMap, IntoBody, Method,
Result,
};
use http::uri::Uri;
use wasi::http::outgoing_handler::OutgoingRequest;
use wasi::http::types::Scheme;
#[derive(Debug)]
pub struct Request<B: Body> {
method: Method,
uri: Uri,
headers: HeaderMap,
body: B,
}
impl Request<Empty> {
pub fn new(method: Method, uri: Uri) -> Self {
Self {
body: empty(),
method,
uri,
headers: HeaderMap::new(),
}
}
}
impl<B: Body> Request<B> {
pub fn headers(&self) -> &HeaderMap {
&self.headers
}
pub fn headers_mut(&mut self) -> &mut HeaderMap {
&mut self.headers
}
pub fn set_body<C: IntoBody>(self, body: C) -> Request<C::IntoBody> {
let Self {
method,
uri,
headers,
..
} = self;
Request {
method,
uri,
headers,
body: body.into_body(),
}
}
pub(crate) fn into_outgoing(self) -> Result<(OutgoingRequest, B)> {
let wasi_req = OutgoingRequest::new(header_map_to_wasi(&self.headers)?);
let method = to_wasi_method(self.method);
wasi_req
.set_method(&method)
.map_err(|()| Error::other(format!("method rejected by wasi-http: {method:?}",)))?;
let scheme = match self.uri.scheme().map(|s| s.as_str()) {
Some("http") => Scheme::Http,
Some("https") | None => Scheme::Https,
Some(other) => Scheme::Other(other.to_owned()),
};
wasi_req
.set_scheme(Some(&scheme))
.map_err(|()| Error::other(format!("scheme rejected by wasi-http: {scheme:?}")))?;
let authority = self.uri.authority().map(|a| a.as_str());
wasi_req
.set_authority(authority)
.map_err(|()| Error::other(format!("authority rejected by wasi-http {authority:?}")))?;
if let Some(p_and_q) = self.uri.path_and_query() {
wasi_req
.set_path_with_query(Some(&p_and_q.to_string()))
.map_err(|()| {
Error::other(format!("path and query rejected by wasi-http {p_and_q:?}"))
})?;
}
Ok((wasi_req, self.body))
}
}