wasm: Add request body in the form of Bytes (#696)
* Add body bytes * Add example and header creation code
This commit is contained in:
committed by
Sean McArthur
parent
b24b0be461
commit
f6f81f9cc1
@@ -1,3 +1,59 @@
|
||||
/// dox
|
||||
#[derive(Debug)]
|
||||
pub struct Body(());
|
||||
use bytes::Bytes;
|
||||
use std::fmt;
|
||||
|
||||
/// The body of a `Request`.
|
||||
///
|
||||
/// In most cases, this is not needed directly, as the
|
||||
/// [`RequestBuilder.body`][builder] method uses `Into<Body>`, which allows
|
||||
/// passing many things (like a string or vector of bytes).
|
||||
///
|
||||
/// [builder]: ./struct.RequestBuilder.html#method.body
|
||||
pub struct Body(Bytes);
|
||||
|
||||
impl Body {
|
||||
pub(crate) fn bytes(&self) -> &Bytes {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Bytes> for Body {
|
||||
#[inline]
|
||||
fn from(bytes: Bytes) -> Body {
|
||||
Body(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for Body {
|
||||
#[inline]
|
||||
fn from(vec: Vec<u8>) -> Body {
|
||||
Body(vec.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static [u8]> for Body {
|
||||
#[inline]
|
||||
fn from(s: &'static [u8]) -> Body {
|
||||
Body(Bytes::from_static(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Body {
|
||||
#[inline]
|
||||
fn from(s: String) -> Body {
|
||||
Body(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for Body {
|
||||
#[inline]
|
||||
fn from(s: &'static str) -> Body {
|
||||
s.as_bytes().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Body {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Body").finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::future::Future;
|
||||
use http::Method;
|
||||
use js_sys::Uint8Array;
|
||||
use std::future::Future;
|
||||
use wasm_bindgen::UnwrapThrowExt as _;
|
||||
|
||||
use crate::IntoUrl;
|
||||
use super::{Request, RequestBuilder, Response};
|
||||
use crate::IntoUrl;
|
||||
|
||||
/// dox
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -91,7 +92,10 @@ impl Client {
|
||||
RequestBuilder::new(self.clone(), req)
|
||||
}
|
||||
|
||||
pub(super) fn execute_request(&self, req: Request) -> impl Future<Output = crate::Result<Response>> {
|
||||
pub(super) fn execute_request(
|
||||
&self,
|
||||
req: Request,
|
||||
) -> impl Future<Output = crate::Result<Response>> {
|
||||
fetch(req)
|
||||
}
|
||||
}
|
||||
@@ -107,12 +111,21 @@ async fn fetch(req: Request) -> crate::Result<Response> {
|
||||
|
||||
for (name, value) in req.headers() {
|
||||
js_headers
|
||||
.append(name.as_str(), value.to_str().map_err(crate::error::builder)?)
|
||||
.append(
|
||||
name.as_str(),
|
||||
value.to_str().map_err(crate::error::builder)?,
|
||||
)
|
||||
.map_err(crate::error::wasm)
|
||||
.map_err(crate::error::builder)?;
|
||||
}
|
||||
init.headers(&js_headers.into());
|
||||
|
||||
if let Some(body) = req.body() {
|
||||
let body_bytes: &[u8] = body.bytes();
|
||||
let body_array: Uint8Array = body_bytes.into();
|
||||
init.body(Some(&body_array.into()));
|
||||
}
|
||||
|
||||
let js_req = web_sys::Request::new_with_str_and_init(req.url().as_str(), &init)
|
||||
.map_err(crate::error::wasm)
|
||||
.map_err(crate::error::builder)?;
|
||||
@@ -160,5 +173,4 @@ impl ClientBuilder {
|
||||
pub fn build(self) -> Result<Client, crate::Error> {
|
||||
Ok(Client(()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use http::HttpTryFrom;
|
||||
use std::fmt;
|
||||
|
||||
use http::{Method, HeaderMap};
|
||||
use http::Method;
|
||||
use url::Url;
|
||||
|
||||
use super::{Body, Client, Response};
|
||||
use crate::header::{HeaderMap, HeaderName, HeaderValue};
|
||||
|
||||
/// A request which can be executed with `Client::execute()`.
|
||||
pub struct Request {
|
||||
@@ -83,7 +85,6 @@ impl RequestBuilder {
|
||||
RequestBuilder { client, request }
|
||||
}
|
||||
|
||||
|
||||
/// Set the request body.
|
||||
pub fn body<T: Into<Body>>(mut self, body: T) -> RequestBuilder {
|
||||
if let Ok(ref mut req) = self.request {
|
||||
@@ -92,6 +93,30 @@ impl RequestBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a `Header` to this Request.
|
||||
pub fn header<K, V>(mut self, key: K, value: V) -> RequestBuilder
|
||||
where
|
||||
HeaderName: HttpTryFrom<K>,
|
||||
HeaderValue: HttpTryFrom<V>,
|
||||
{
|
||||
let mut error = None;
|
||||
if let Ok(ref mut req) = self.request {
|
||||
match <HeaderName as HttpTryFrom<K>>::try_from(key) {
|
||||
Ok(key) => match <HeaderValue as HttpTryFrom<V>>::try_from(value) {
|
||||
Ok(value) => {
|
||||
req.headers_mut().append(key, value);
|
||||
}
|
||||
Err(e) => error = Some(crate::error::builder(e.into())),
|
||||
},
|
||||
Err(e) => error = Some(crate::error::builder(e.into())),
|
||||
};
|
||||
}
|
||||
if let Some(err) = error {
|
||||
self.request = Err(err);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Constructs the Request and sends it to the target URL, returning a
|
||||
/// future Response.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user