aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/response.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/response.rs')
-rw-r--r--components/script/dom/response.rs107
1 files changed, 93 insertions, 14 deletions
diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs
index acfc181283a..b8eeb81fb66 100644
--- a/components/script/dom/response.rs
+++ b/components/script/dom/response.rs
@@ -2,11 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use body::{BodyOperations, BodyType, consume_body};
use core::cell::Cell;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HeadersBinding::HeadersMethods;
use dom::bindings::codegen::Bindings::ResponseBinding;
use dom::bindings::codegen::Bindings::ResponseBinding::{ResponseMethods, ResponseType as DOMResponseType};
+use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::BodyInit;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutNullableHeap, Root};
@@ -14,9 +16,16 @@ use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, USVString};
use dom::headers::{Headers, Guard};
use dom::headers::{is_vchar, is_obs_text};
+use dom::promise::Promise;
+use dom::xmlhttprequest::Extractable;
+use hyper::header::Headers as HyperHeaders;
use hyper::status::StatusCode;
+use hyper_serde::Serde;
use net_traits::response::{ResponseBody as NetTraitsResponseBody};
+use std::mem;
+use std::rc::Rc;
use std::str::FromStr;
+use style::refcell::Ref;
use url::Position;
use url::Url;
@@ -33,8 +42,7 @@ pub struct Response {
response_type: DOMRefCell<DOMResponseType>,
url: DOMRefCell<Option<Url>>,
url_list: DOMRefCell<Vec<Url>>,
- // For now use the existing NetTraitsResponseBody enum, until body
- // is implemented.
+ // For now use the existing NetTraitsResponseBody enum
body: DOMRefCell<NetTraitsResponseBody>,
}
@@ -59,7 +67,7 @@ impl Response {
reflect_dom_object(box Response::new_inherited(), global, ResponseBinding::Wrap)
}
- pub fn Constructor(global: GlobalRef, _body: Option<USVString>, init: &ResponseBinding::ResponseInit)
+ pub fn Constructor(global: GlobalRef, body: Option<BodyInit>, init: &ResponseBinding::ResponseInit)
-> Fallible<Root<Response>> {
// Step 1
if init.status < 200 || init.status > 599 {
@@ -86,11 +94,6 @@ impl Response {
// Step 6
if let Some(ref headers_member) = init.headers {
// Step 6.1
- // TODO: Figure out how/if we should make r's response's
- // header list and r's Headers object the same thing. For
- // now just working with r's Headers object. Also, the
- // header list should already be empty so this step may be
- // unnecessary.
r.Headers().empty_header_list();
// Step 6.2
@@ -98,23 +101,22 @@ impl Response {
}
// Step 7
- if let Some(_) = _body {
+ if let Some(ref body) = body {
// Step 7.1
if is_null_body_status(init.status) {
return Err(Error::Type(
"Body is non-null but init's status member is a null body status".to_string()));
};
- // Step 7.2
- let content_type: Option<ByteString> = None;
-
// Step 7.3
- // TODO: Extract body and implement step 7.3.
+ let (extracted_body, content_type) = body.extract();
+ *r.body.borrow_mut() = NetTraitsResponseBody::Done(extracted_body);
// Step 7.4
if let Some(content_type_contents) = content_type {
if !r.Headers().Has(ByteString::new(b"Content-Type".to_vec())).unwrap() {
- try!(r.Headers().Append(ByteString::new(b"Content-Type".to_vec()), content_type_contents));
+ try!(r.Headers().Append(ByteString::new(b"Content-Type".to_vec()),
+ ByteString::new(content_type_contents.as_bytes().to_vec())));
}
};
}
@@ -178,6 +180,38 @@ impl Response {
// Step 7
Ok(r)
}
+
+ // https://fetch.spec.whatwg.org/#concept-body-locked
+ fn locked(&self) -> bool {
+ // TODO: ReadableStream is unimplemented. Just return false
+ // for now.
+ false
+ }
+}
+
+impl BodyOperations for Response {
+ fn get_body_used(&self) -> bool {
+ self.BodyUsed()
+ }
+
+ fn is_locked(&self) -> bool {
+ self.locked()
+ }
+
+ fn take_body(&self) -> Option<Vec<u8>> {
+ let body: NetTraitsResponseBody = mem::replace(&mut *self.body.borrow_mut(), NetTraitsResponseBody::Empty);
+ match body {
+ NetTraitsResponseBody::Done(bytes) | NetTraitsResponseBody::Receiving(bytes) => {
+ self.body_used.set(true);
+ Some(bytes)
+ },
+ _ => None,
+ }
+ }
+
+ fn get_mime_type(&self) -> Ref<Vec<u8>> {
+ self.mime_type.borrow()
+ }
}
// https://fetch.spec.whatwg.org/#redirect-status
@@ -283,8 +317,53 @@ impl ResponseMethods for Response {
fn BodyUsed(&self) -> bool {
self.body_used.get()
}
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-text
+ fn Text(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Text)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-blob
+ fn Blob(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Blob)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-formdata
+ fn FormData(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::FormData)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-json
+ fn Json(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Json)
+ }
}
fn serialize_without_fragment(url: &Url) -> &str {
&url[..Position::AfterQuery]
}
+
+impl Response {
+ pub fn set_type(&self, new_response_type: DOMResponseType) {
+ *self.response_type.borrow_mut() = new_response_type;
+ }
+
+ pub fn set_headers(&self, option_hyper_headers: Option<Serde<HyperHeaders>>) {
+ self.Headers().set_headers(match option_hyper_headers {
+ Some(hyper_headers) => hyper_headers.into_inner(),
+ None => HyperHeaders::new(),
+ });
+ }
+
+ pub fn set_raw_status(&self, status: Option<(u16, Vec<u8>)>) {
+ *self.raw_status.borrow_mut() = status;
+ }
+
+ pub fn set_final_url(&self, final_url: Url) {
+ *self.url.borrow_mut() = Some(final_url);
+ }
+}