mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
auto merge of #2521 : Manishearth/servo/xhr-responsetext, r=Ms2ger
Blocks #2282
This commit is contained in:
commit
33c4a7a5dc
4 changed files with 54 additions and 28 deletions
|
@ -111,6 +111,7 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
let mut metadata = Metadata::default(url);
|
let mut metadata = Metadata::default(url);
|
||||||
metadata.set_content_type(&response.headers.content_type);
|
metadata.set_content_type(&response.headers.content_type);
|
||||||
metadata.headers = Some(*response.headers.clone());
|
metadata.headers = Some(*response.headers.clone());
|
||||||
|
metadata.status = response.status.clone();
|
||||||
|
|
||||||
let progress_chan = start_sending(start_chan, metadata);
|
let progress_chan = start_sending(start_chan, metadata);
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -16,6 +16,9 @@ use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
||||||
use http::method::{Method, Get};
|
use http::method::{Method, Get};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
use StatusOk = http::status::Ok;
|
||||||
|
use http::status::Status;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
|
|
||||||
|
@ -57,6 +60,9 @@ pub struct Metadata {
|
||||||
|
|
||||||
/// Headers
|
/// Headers
|
||||||
pub headers: Option<ResponseHeaderCollection>,
|
pub headers: Option<ResponseHeaderCollection>,
|
||||||
|
|
||||||
|
/// HTTP Status
|
||||||
|
pub status: Status
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Metadata {
|
impl Metadata {
|
||||||
|
@ -66,7 +72,8 @@ impl Metadata {
|
||||||
final_url: url,
|
final_url: url,
|
||||||
content_type: None,
|
content_type: None,
|
||||||
charset: None,
|
charset: None,
|
||||||
headers: None
|
headers: None,
|
||||||
|
status: StatusOk // http://fetch.spec.whatwg.org/#concept-response-status-message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
|
||||||
// void overrideMimeType(DOMString mime);
|
// void overrideMimeType(DOMString mime);
|
||||||
attribute XMLHttpRequestResponseType responseType;
|
attribute XMLHttpRequestResponseType responseType;
|
||||||
readonly attribute any response;
|
readonly attribute any response;
|
||||||
|
[Throws]
|
||||||
readonly attribute DOMString responseText;
|
readonly attribute DOMString responseText;
|
||||||
[Exposed=Window] readonly attribute Document? responseXML;
|
[Exposed=Window] readonly attribute Document? responseXML;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,8 +8,7 @@ use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestRespo
|
||||||
use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseTypeValues::{_empty, Text};
|
use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseTypeValues::{_empty, Text};
|
||||||
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, XMLHttpRequestDerived};
|
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, XMLHttpRequestDerived};
|
||||||
use dom::bindings::conversions::ToJSValConvertible;
|
use dom::bindings::conversions::ToJSValConvertible;
|
||||||
use dom::bindings::error::{ErrorResult, InvalidState, Network, Syntax, Security};
|
use dom::bindings::error::{ErrorResult, Fallible, InvalidState, Network, Syntax, Security};
|
||||||
use dom::bindings::error::Fallible;
|
|
||||||
use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable, OptionalRootedRootable};
|
use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable, OptionalRootedRootable};
|
||||||
use dom::bindings::str::ByteString;
|
use dom::bindings::str::ByteString;
|
||||||
use dom::bindings::trace::Untraceable;
|
use dom::bindings::trace::Untraceable;
|
||||||
|
@ -21,30 +20,36 @@ use dom::progressevent::ProgressEvent;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget;
|
use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget;
|
||||||
use dom::xmlhttprequestupload::XMLHttpRequestUpload;
|
use dom::xmlhttprequestupload::XMLHttpRequestUpload;
|
||||||
|
|
||||||
|
use encoding::all::UTF_8;
|
||||||
|
use encoding::types::{DecodeReplace, Encoding};
|
||||||
|
|
||||||
|
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
||||||
|
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
||||||
|
use http::headers::{HeaderEnum, HeaderValueByteIterator};
|
||||||
|
use http::headers::request::Header;
|
||||||
|
use http::method::{Method, Get, Head, Post, Connect, Trace};
|
||||||
|
use http::status::Status;
|
||||||
|
|
||||||
|
use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext};
|
||||||
|
use js::jsval::{JSVal, NullValue};
|
||||||
|
|
||||||
|
use libc;
|
||||||
|
use libc::c_void;
|
||||||
|
|
||||||
use net::resource_task::{ResourceTask, Load, LoadData, Payload, Done};
|
use net::resource_task::{ResourceTask, Load, LoadData, Payload, Done};
|
||||||
use script_task::{ScriptChan, XHRProgressMsg};
|
use script_task::{ScriptChan, XHRProgressMsg};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use servo_util::url::{parse_url, try_parse_url};
|
use servo_util::url::{parse_url, try_parse_url};
|
||||||
|
|
||||||
use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext};
|
use std::ascii::StrAsciiExt;
|
||||||
use js::jsval::{JSVal, NullValue};
|
|
||||||
|
|
||||||
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
|
||||||
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
|
||||||
|
|
||||||
use http::headers::{HeaderEnum, HeaderValueByteIterator};
|
|
||||||
use http::headers::request::Header;
|
|
||||||
use http::method::{Method, Get, Head, Post, Connect, Trace};
|
|
||||||
|
|
||||||
use libc;
|
|
||||||
use libc::c_void;
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::comm::channel;
|
use std::comm::channel;
|
||||||
use std::io::{BufReader, MemWriter};
|
use std::io::{BufReader, MemWriter};
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
use std::ascii::StrAsciiExt;
|
|
||||||
use std::task::TaskBuilder;
|
|
||||||
use std::path::BytesContainer;
|
use std::path::BytesContainer;
|
||||||
|
use std::task::TaskBuilder;
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
// As send() start accepting more and more parameter types,
|
// As send() start accepting more and more parameter types,
|
||||||
|
@ -69,7 +74,7 @@ enum XMLHttpRequestState {
|
||||||
|
|
||||||
pub enum XHRProgress {
|
pub enum XHRProgress {
|
||||||
/// Notify that headers have been received
|
/// Notify that headers have been received
|
||||||
HeadersReceivedMsg(Option<ResponseHeaderCollection>),
|
HeadersReceivedMsg(Option<ResponseHeaderCollection>, Status),
|
||||||
/// Partial progress (after receiving headers), containing portion of the response
|
/// Partial progress (after receiving headers), containing portion of the response
|
||||||
LoadingMsg(ByteString),
|
LoadingMsg(ByteString),
|
||||||
/// Loading is done
|
/// Loading is done
|
||||||
|
@ -105,7 +110,6 @@ pub struct XMLHttpRequest {
|
||||||
status_text: ByteString,
|
status_text: ByteString,
|
||||||
response: ByteString,
|
response: ByteString,
|
||||||
response_type: XMLHttpRequestResponseType,
|
response_type: XMLHttpRequestResponseType,
|
||||||
response_text: DOMString,
|
|
||||||
response_xml: Cell<Option<JS<Document>>>,
|
response_xml: Cell<Option<JS<Document>>>,
|
||||||
response_headers: Untraceable<ResponseHeaderCollection>,
|
response_headers: Untraceable<ResponseHeaderCollection>,
|
||||||
|
|
||||||
|
@ -136,7 +140,6 @@ impl XMLHttpRequest {
|
||||||
status_text: ByteString::new(vec!()),
|
status_text: ByteString::new(vec!()),
|
||||||
response: ByteString::new(vec!()),
|
response: ByteString::new(vec!()),
|
||||||
response_type: _empty,
|
response_type: _empty,
|
||||||
response_text: "".to_owned(),
|
|
||||||
response_xml: Cell::new(None),
|
response_xml: Cell::new(None),
|
||||||
response_headers: Untraceable::new(ResponseHeaderCollection::new()),
|
response_headers: Untraceable::new(ResponseHeaderCollection::new()),
|
||||||
|
|
||||||
|
@ -190,7 +193,8 @@ impl XMLHttpRequest {
|
||||||
let (start_chan, start_port) = channel();
|
let (start_chan, start_port) = channel();
|
||||||
resource_task.send(Load(load_data, start_chan));
|
resource_task.send(Load(load_data, start_chan));
|
||||||
let response = start_port.recv();
|
let response = start_port.recv();
|
||||||
notify_partial_progress(fetch_type, HeadersReceivedMsg(response.metadata.headers.clone()));
|
notify_partial_progress(fetch_type, HeadersReceivedMsg(
|
||||||
|
response.metadata.headers.clone(), response.metadata.status.clone()));
|
||||||
let mut buf = vec!();
|
let mut buf = vec!();
|
||||||
loop {
|
loop {
|
||||||
match response.progress_port.recv() {
|
match response.progress_port.recv() {
|
||||||
|
@ -241,7 +245,7 @@ pub trait XMLHttpRequestMethods<'a> {
|
||||||
fn ResponseType(&self) -> XMLHttpRequestResponseType;
|
fn ResponseType(&self) -> XMLHttpRequestResponseType;
|
||||||
fn SetResponseType(&mut self, response_type: XMLHttpRequestResponseType);
|
fn SetResponseType(&mut self, response_type: XMLHttpRequestResponseType);
|
||||||
fn Response(&self, _cx: *mut JSContext) -> JSVal;
|
fn Response(&self, _cx: *mut JSContext) -> JSVal;
|
||||||
fn ResponseText(&self) -> DOMString;
|
fn GetResponseText(&self) -> Fallible<DOMString>;
|
||||||
fn GetResponseXML(&self) -> Option<Temporary<Document>>;
|
fn GetResponseXML(&self) -> Option<Temporary<Document>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +286,8 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
*self.request_url = parsed_url;
|
*self.request_url = parsed_url;
|
||||||
*self.request_headers = RequestHeaderCollection::new();
|
*self.request_headers = RequestHeaderCollection::new();
|
||||||
self.send_flag = false;
|
self.send_flag = false;
|
||||||
// XXXManishearth Set response to a NetworkError
|
self.status_text = ByteString::new(vec!());
|
||||||
|
self.status = 0;
|
||||||
|
|
||||||
// Step 13
|
// Step 13
|
||||||
if self.ready_state != Opened {
|
if self.ready_state != Opened {
|
||||||
|
@ -497,8 +502,19 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn ResponseText(&self) -> DOMString {
|
fn GetResponseText(&self) -> Fallible<DOMString> {
|
||||||
self.response_text.clone()
|
match self.response_type {
|
||||||
|
_empty | Text => {
|
||||||
|
match self.ready_state {
|
||||||
|
// XXXManishearth handle charset, etc (http://xhr.spec.whatwg.org/#text-response)
|
||||||
|
// According to Simon decode() should never return an error, so unwrap()ing
|
||||||
|
// the result should be fine. XXXManishearth have a closer look at this later
|
||||||
|
Loading | XHRDone => Ok(UTF_8.decode(self.response.as_slice(), DecodeReplace).unwrap().to_owned()),
|
||||||
|
_ => Ok("".to_owned())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => Err(InvalidState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn GetResponseXML(&self) -> Option<Temporary<Document>> {
|
fn GetResponseXML(&self) -> Option<Temporary<Document>> {
|
||||||
self.response_xml.get().map(|response| Temporary::new(response))
|
self.response_xml.get().map(|response| Temporary::new(response))
|
||||||
|
@ -575,13 +591,12 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
|
||||||
|
|
||||||
fn process_partial_response(&mut self, progress: XHRProgress) {
|
fn process_partial_response(&mut self, progress: XHRProgress) {
|
||||||
match progress {
|
match progress {
|
||||||
HeadersReceivedMsg(headers) => {
|
HeadersReceivedMsg(headers, status) => {
|
||||||
// XXXManishearth Find a way to track partial progress of the send (onprogresss for XHRUpload)
|
// XXXManishearth Find a way to track partial progress of the send (onprogresss for XHRUpload)
|
||||||
|
|
||||||
// Part of step 13, send() (processing request end of file)
|
// Part of step 13, send() (processing request end of file)
|
||||||
// Substep 1
|
// Substep 1
|
||||||
self.upload_complete = true;
|
self.upload_complete = true;
|
||||||
|
|
||||||
// Substeps 2-4
|
// Substeps 2-4
|
||||||
self.dispatch_upload_progress_event("progress".to_owned(), None);
|
self.dispatch_upload_progress_event("progress".to_owned(), None);
|
||||||
self.dispatch_upload_progress_event("load".to_owned(), None);
|
self.dispatch_upload_progress_event("load".to_owned(), None);
|
||||||
|
@ -589,7 +604,9 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
|
||||||
|
|
||||||
// Part of step 13, send() (processing response)
|
// Part of step 13, send() (processing response)
|
||||||
// XXXManishearth handle errors, if any (substep 1)
|
// XXXManishearth handle errors, if any (substep 1)
|
||||||
// Substep 2 (only headers)
|
// Substep 2
|
||||||
|
self.status_text = ByteString::new(status.reason().container_into_owned_bytes());
|
||||||
|
self.status = status.code();
|
||||||
match headers {
|
match headers {
|
||||||
Some(ref h) => *self.response_headers = h.clone(),
|
Some(ref h) => *self.response_headers = h.clone(),
|
||||||
None => {}
|
None => {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue