mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Auto merge of #9621 - KiChjang:xhr-response-json, r=Ms2ger
Cache XHR JSON responses Fixes #3919. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9621) <!-- Reviewable:end -->
This commit is contained in:
commit
5ee5ce07ba
2 changed files with 38 additions and 18 deletions
|
@ -17,7 +17,7 @@ use dom::bindings::conversions::{ToJSValConvertible};
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::{GlobalRef, GlobalRoot};
|
use dom::bindings::global::{GlobalRef, GlobalRoot};
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, MutNullableHeap};
|
use dom::bindings::js::{JS, MutHeapJSVal, MutNullableHeap};
|
||||||
use dom::bindings::js::{Root, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
|
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
|
||||||
|
@ -125,6 +125,8 @@ pub struct XMLHttpRequest {
|
||||||
response_type: Cell<XMLHttpRequestResponseType>,
|
response_type: Cell<XMLHttpRequestResponseType>,
|
||||||
response_xml: MutNullableHeap<JS<Document>>,
|
response_xml: MutNullableHeap<JS<Document>>,
|
||||||
response_blob: MutNullableHeap<JS<Blob>>,
|
response_blob: MutNullableHeap<JS<Blob>>,
|
||||||
|
#[ignore_heap_size_of = "Defined in rust-mozjs"]
|
||||||
|
response_json: MutHeapJSVal,
|
||||||
#[ignore_heap_size_of = "Defined in hyper"]
|
#[ignore_heap_size_of = "Defined in hyper"]
|
||||||
response_headers: DOMRefCell<Headers>,
|
response_headers: DOMRefCell<Headers>,
|
||||||
#[ignore_heap_size_of = "Defined in hyper"]
|
#[ignore_heap_size_of = "Defined in hyper"]
|
||||||
|
@ -165,6 +167,7 @@ impl XMLHttpRequest {
|
||||||
response_type: Cell::new(XMLHttpRequestResponseType::_empty),
|
response_type: Cell::new(XMLHttpRequestResponseType::_empty),
|
||||||
response_xml: Default::default(),
|
response_xml: Default::default(),
|
||||||
response_blob: Default::default(),
|
response_blob: Default::default(),
|
||||||
|
response_json: MutHeapJSVal::new(),
|
||||||
response_headers: DOMRefCell::new(Headers::new()),
|
response_headers: DOMRefCell::new(Headers::new()),
|
||||||
override_mime_type: DOMRefCell::new(None),
|
override_mime_type: DOMRefCell::new(None),
|
||||||
override_charset: DOMRefCell::new(None),
|
override_charset: DOMRefCell::new(None),
|
||||||
|
@ -720,15 +723,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
XMLHttpRequestResponseType::Json => {
|
XMLHttpRequestResponseType::Json => {
|
||||||
let decoded = UTF_8.decode(&self.response.borrow(), DecoderTrap::Replace).unwrap().to_owned();
|
self.json_response(cx).to_jsval(cx, rval.handle_mut());
|
||||||
let decoded: Vec<u16> = decoded.utf16_units().collect();
|
|
||||||
if !JS_ParseJSON(cx,
|
|
||||||
decoded.as_ptr(),
|
|
||||||
decoded.len() as u32,
|
|
||||||
rval.handle_mut()) {
|
|
||||||
JS_ClearPendingException(cx);
|
|
||||||
return NullValue();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
XMLHttpRequestResponseType::Blob => {
|
XMLHttpRequestResponseType::Blob => {
|
||||||
self.blob_response().to_jsval(cx, rval.handle_mut());
|
self.blob_response().to_jsval(cx, rval.handle_mut());
|
||||||
|
@ -1093,6 +1088,39 @@ impl XMLHttpRequest {
|
||||||
Some(temp_doc)
|
Some(temp_doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
// https://xhr.spec.whatwg.org/#json-response
|
||||||
|
fn json_response(&self, cx: *mut JSContext) -> JSVal {
|
||||||
|
// Step 1
|
||||||
|
let response_json = self.response_json.get();
|
||||||
|
if !response_json.is_null_or_undefined() {
|
||||||
|
return response_json;
|
||||||
|
}
|
||||||
|
// Step 2
|
||||||
|
let bytes = self.response.borrow();
|
||||||
|
// Step 3
|
||||||
|
if bytes.len() == 0 {
|
||||||
|
return NullValue();
|
||||||
|
}
|
||||||
|
// Step 4
|
||||||
|
let json_text = UTF_8.decode(&bytes, DecoderTrap::Replace).unwrap().to_owned();
|
||||||
|
let json_text: Vec<u16> = json_text.utf16_units().collect();
|
||||||
|
// Step 5
|
||||||
|
let mut rval = RootedValue::new(cx, UndefinedValue());
|
||||||
|
unsafe {
|
||||||
|
if !JS_ParseJSON(cx,
|
||||||
|
json_text.as_ptr(),
|
||||||
|
json_text.len() as u32,
|
||||||
|
rval.handle_mut()) {
|
||||||
|
JS_ClearPendingException(cx);
|
||||||
|
return NullValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Step 6
|
||||||
|
self.response_json.set(rval.ptr);
|
||||||
|
self.response_json.get()
|
||||||
|
}
|
||||||
|
|
||||||
fn document_text_html(&self) -> Root<Document>{
|
fn document_text_html(&self) -> Root<Document>{
|
||||||
let charset = self.final_charset().unwrap_or(UTF_8);
|
let charset = self.final_charset().unwrap_or(UTF_8);
|
||||||
let wr = self.global();
|
let wr = self.global();
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[response-json.htm]
|
|
||||||
type: testharness
|
|
||||||
[JSON object roundtrip]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[JSON roundtrip with Japanese text]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue