Skip to content

Commit 389a1d6

Browse files
committed
Update sending body and headers in the wasm backend
1 parent bb516a8 commit 389a1d6

File tree

1 file changed

+33
-42
lines changed

1 file changed

+33
-42
lines changed

src/wasm.rs

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! http-client implementation for fetch
22
3-
use super::{Body, HttpClient, Request, Response};
3+
use super::{http_types::Headers, Body, HttpClient, Request, Response};
44

55
use futures::future::BoxFuture;
66
use futures::prelude::*;
@@ -34,7 +34,7 @@ impl HttpClient for WasmClient {
3434

3535
fn send(&self, req: Request) -> BoxFuture<'static, Result<Response, Self::Error>> {
3636
let fut = Box::pin(async move {
37-
let req: fetch::Request = fetch::Request::new(req)?;
37+
let req: fetch::Request = fetch::Request::new(req).await?;
3838
let mut res = req.send().await?;
3939

4040
let body = res.body_bytes();
@@ -77,12 +77,10 @@ impl Future for InnerFuture {
7777

7878
mod fetch {
7979
use futures_util::io::AsyncReadExt;
80-
use http::request::Parts;
8180
use js_sys::{Array, ArrayBuffer, Reflect, Uint8Array};
8281
use wasm_bindgen::JsCast;
8382
use wasm_bindgen_futures::JsFuture;
84-
use web_sys::window;
85-
use web_sys::RequestInit;
83+
use web_sys::{window, RequestInit};
8684

8785
use std::io;
8886
use std::iter::{IntoIterator, Iterator};
@@ -92,54 +90,28 @@ mod fetch {
9290
9391
/// An HTTP Fetch Request.
9492
pub(crate) struct Request {
95-
init: RequestInit,
96-
url: String,
93+
request: web_sys::Request,
9794
_body_buf: Pin<Vec<u8>>,
9895
}
9996

10097
impl Request {
10198
/// Create a new instance.
102-
pub(crate) fn new(req: super::Request) -> Result<Self, io::Error> {
103-
let (
104-
Parts {
105-
method,
106-
uri,
107-
headers,
108-
..
109-
},
110-
mut body,
111-
) = req.into_parts();
112-
99+
pub(crate) async fn new(mut req: super::Request) -> Result<Self, io::Error> {
113100
//create a fetch request initaliser
114-
let mut init = web_sys::RequestInit::new();
101+
let mut init = RequestInit::new();
115102

116103
//set the fetch method
117-
init.method(method.as_ref());
104+
init.method(req.method().as_ref());
118105

119-
//add any fetch headers
120-
let init_headers = web_sys::Headers::new().unwrap();
121-
for (name, value) in headers.iter() {
122-
init_headers
123-
.append(name.as_str(), value.to_str().unwrap())
124-
.map_err(|_| {
125-
io::Error::new(
126-
io::ErrorKind::Other,
127-
format!(
128-
"could not add header: {} = {}",
129-
name.as_str(),
130-
value.to_str().expect("could not stringify header value")
131-
),
132-
)
133-
})?;
134-
}
135-
init.headers(&init_headers);
106+
let uri = req.url().to_string();
107+
let mut body = req.take_body();
136108

137109
//convert the body into a uint8 array
138110
// needs to be pinned and retained inside the Request because the Uint8Array passed to
139111
// js is just a portal into WASM linear memory, and if the underlying data is moved the
140112
// js ref will become silently invalid
141113
let mut body_buf = Vec::with_capacity(1024);
142-
futures::executor::block_on(body.read_to_end(&mut body_buf)).map_err(|_| {
114+
body.read_to_end(&mut body_buf).await.map_err(|_| {
143115
io::Error::new(io::ErrorKind::Other, "could not read body into a buffer")
144116
})?;
145117
let body_pinned = Pin::new(body_buf);
@@ -150,9 +122,29 @@ mod fetch {
150122
}
151123
}
152124

125+
let request = web_sys::Request::new_with_str_and_init(&uri, &init).map_err(|e| {
126+
io::Error::new(
127+
io::ErrorKind::Other,
128+
format!("failed to create request: {:?}", e),
129+
)
130+
})?;
131+
132+
//add any fetch headers
133+
let headers: &mut super::Headers = req.as_mut();
134+
for (name, value) in headers.iter() {
135+
let name = name.as_str();
136+
let value = value.as_str();
137+
138+
request.headers().set(name, value).map_err(|_| {
139+
io::Error::new(
140+
io::ErrorKind::Other,
141+
format!("could not add header: {} = {}", name, value),
142+
)
143+
})?;
144+
}
145+
153146
Ok(Self {
154-
init,
155-
url: uri.to_string(),
147+
request,
156148
_body_buf: body_pinned,
157149
})
158150
}
@@ -162,8 +154,7 @@ mod fetch {
162154
pub(crate) async fn send(self) -> Result<Response, io::Error> {
163155
// Send the request.
164156
let window = window().expect("A global window object could not be found");
165-
let request = web_sys::Request::new_with_str_and_init(&self.url, &self.init).unwrap();
166-
let promise = window.fetch_with_request(&request);
157+
let promise = window.fetch_with_request(&self.request);
167158
let resp = JsFuture::from(promise).await.unwrap();
168159
debug_assert!(resp.is_instance_of::<web_sys::Response>());
169160
let res: web_sys::Response = resp.dyn_into().unwrap();

0 commit comments

Comments
 (0)