diff --git a/components/script/body.rs b/components/script/body.rs index 435f755aa07..43bd0fb5c18 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -7,17 +7,22 @@ use dom::bindings::error::{Error, Fallible}; use dom::bindings::reflector::DomObject; use dom::bindings::root::DomRoot; use dom::bindings::str::USVString; +use dom::bindings::trace::RootedTraceableBox; use dom::blob::{Blob, BlobImpl}; use dom::formdata::FormData; use dom::globalscope::GlobalScope; use dom::promise::Promise; +use js::jsapi::Heap; use js::jsapi::JSContext; +use js::jsapi::JSObject; use js::jsapi::JS_ClearPendingException; use js::jsapi::JS_ParseJSON; use js::jsapi::Value as JSValue; use js::jsval::UndefinedValue; +use js::typedarray::{ArrayBuffer, CreateWith}; use mime::{Mime, TopLevel, SubLevel}; use std::cell::Ref; +use std::ptr; use std::rc::Rc; use std::str; use url::form_urlencoded; @@ -36,6 +41,7 @@ pub enum FetchedData { Json(JSValue), BlobData(DomRoot), FormData(DomRoot), + ArrayBuffer(RootedTraceableBox>), } // https://fetch.spec.whatwg.org/#concept-body-consume-body @@ -84,6 +90,7 @@ pub fn consume_body_with_promise(object: &T, FetchedData::Json(j) => promise.resolve_native(&j), FetchedData::BlobData(b) => promise.resolve_native(&b), FetchedData::FormData(f) => promise.resolve_native(&f), + FetchedData::ArrayBuffer(a) => promise.resolve_native(&a) }; }, Err(err) => promise.reject_error(err), @@ -105,6 +112,9 @@ fn run_package_data_algorithm(object: &T, BodyType::Json => run_json_data_algorithm(cx, bytes), BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime), BodyType::FormData => run_form_data_algorithm(&global, bytes, mime), + BodyType::ArrayBuffer => unsafe { + run_array_buffer_data_algorithm(cx, bytes) + } } } @@ -167,6 +177,17 @@ fn run_form_data_algorithm(root: &GlobalScope, bytes: Vec, mime: &[u8]) -> F } } +#[allow(unsafe_code)] +unsafe fn run_array_buffer_data_algorithm(cx: *mut JSContext, bytes: Vec) -> Fallible { + rooted!(in(cx) let mut array_buffer_ptr = ptr::null_mut::()); + let arraybuffer = ArrayBuffer::create(cx, CreateWith::Slice(&bytes), array_buffer_ptr.handle_mut()); + if arraybuffer.is_err() { + return Err(Error::JSFailed); + } + let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get())); + Ok(FetchedData::ArrayBuffer(rooted_heap)) +} + pub trait BodyOperations { fn get_body_used(&self) -> bool; fn set_body_promise(&self, p: &Rc, body_type: BodyType);