mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Merge pull request #2809 from Manishearth/sendparam
Allow URLSearchParams to be passed to XHR Send(); r=jdm
This commit is contained in:
commit
8c8051800f
4 changed files with 51 additions and 21 deletions
|
@ -78,7 +78,7 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
match load_data.data {
|
match load_data.data {
|
||||||
Some(ref data) => {
|
Some(ref data) => {
|
||||||
writer.headers.content_length = Some(data.len());
|
writer.headers.content_length = Some(data.len());
|
||||||
match writer.write(data.clone().into_bytes().as_slice()) {
|
match writer.write(data.as_slice()) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
send_error(url, e.desc.to_string(), start_chan);
|
send_error(url, e.desc.to_string(), start_chan);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub struct LoadData {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
pub headers: RequestHeaderCollection,
|
pub headers: RequestHeaderCollection,
|
||||||
pub data: Option<String>
|
pub data: Option<Vec<u8>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadData {
|
impl LoadData {
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
* http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
|
* http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// http://fetch.spec.whatwg.org/#fetchbodyinit
|
||||||
|
typedef (/*ArrayBuffer or ArrayBufferView or Blob or FormData or */DOMString or URLSearchParams) FetchBodyInit;
|
||||||
|
|
||||||
enum XMLHttpRequestResponseType {
|
enum XMLHttpRequestResponseType {
|
||||||
"",
|
"",
|
||||||
"arraybuffer",
|
"arraybuffer",
|
||||||
|
@ -50,7 +53,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
|
||||||
attribute boolean withCredentials;
|
attribute boolean withCredentials;
|
||||||
readonly attribute XMLHttpRequestUpload upload;
|
readonly attribute XMLHttpRequestUpload upload;
|
||||||
[Throws]
|
[Throws]
|
||||||
void send(optional /*(ArrayBufferView or Blob or Document or [EnsureUTF16] */ DOMString/* or FormData or URLSearchParams)*/? data = null);
|
void send(optional /*Document or*/ FetchBodyInit? data = null);
|
||||||
void abort();
|
void abort();
|
||||||
|
|
||||||
// response
|
// response
|
||||||
|
|
|
@ -18,13 +18,14 @@ use dom::document::Document;
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetHelpers, XMLHttpRequestTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetHelpers, XMLHttpRequestTargetTypeId};
|
||||||
use dom::progressevent::ProgressEvent;
|
use dom::progressevent::ProgressEvent;
|
||||||
|
use dom::urlsearchparams::URLSearchParamsHelpers;
|
||||||
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::all::UTF_8;
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
use encoding::types::{DecodeReplace, Encoding};
|
use encoding::types::{DecodeReplace, Encoding, EncodeReplace};
|
||||||
|
|
||||||
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
||||||
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
||||||
|
@ -56,10 +57,9 @@ use std::task::TaskBuilder;
|
||||||
use time;
|
use time;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
// As send() start accepting more and more parameter types,
|
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eString, eURLSearchParams, StringOrURLSearchParams};
|
||||||
// change this to the appropriate type from UnionTypes, eg
|
pub type SendParam = StringOrURLSearchParams;
|
||||||
// use SendParam = dom::bindings::codegen::UnionTypes::StringOrFormData;
|
|
||||||
pub type SendParam = DOMString;
|
|
||||||
|
|
||||||
#[deriving(PartialEq,Encodable)]
|
#[deriving(PartialEq,Encodable)]
|
||||||
pub enum XMLHttpRequestId {
|
pub enum XMLHttpRequestId {
|
||||||
|
@ -114,7 +114,7 @@ pub struct XMLHttpRequest {
|
||||||
request_method: Untraceable<RefCell<Method>>,
|
request_method: Untraceable<RefCell<Method>>,
|
||||||
request_url: Untraceable<RefCell<Url>>,
|
request_url: Untraceable<RefCell<Url>>,
|
||||||
request_headers: Untraceable<RefCell<RequestHeaderCollection>>,
|
request_headers: Untraceable<RefCell<RequestHeaderCollection>>,
|
||||||
request_body: SendParam,
|
request_body_len: Traceable<Cell<uint>>,
|
||||||
sync: Traceable<Cell<bool>>,
|
sync: Traceable<Cell<bool>>,
|
||||||
upload_complete: Traceable<Cell<bool>>,
|
upload_complete: Traceable<Cell<bool>>,
|
||||||
upload_events: Traceable<Cell<bool>>,
|
upload_events: Traceable<Cell<bool>>,
|
||||||
|
@ -147,7 +147,7 @@ impl XMLHttpRequest {
|
||||||
request_method: Untraceable::new(RefCell::new(Get)),
|
request_method: Untraceable::new(RefCell::new(Get)),
|
||||||
request_url: Untraceable::new(RefCell::new(parse_url("", None))),
|
request_url: Untraceable::new(RefCell::new(parse_url("", None))),
|
||||||
request_headers: Untraceable::new(RefCell::new(RequestHeaderCollection::new())),
|
request_headers: Untraceable::new(RefCell::new(RequestHeaderCollection::new())),
|
||||||
request_body: "".to_string(),
|
request_body_len: Traceable::new(Cell::new(0)),
|
||||||
sync: Traceable::new(Cell::new(false)),
|
sync: Traceable::new(Cell::new(false)),
|
||||||
send_flag: Traceable::new(Cell::new(false)),
|
send_flag: Traceable::new(Cell::new(false)),
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ pub trait XMLHttpRequestMethods<'a> {
|
||||||
fn WithCredentials(&self) -> bool;
|
fn WithCredentials(&self) -> bool;
|
||||||
fn SetWithCredentials(&self, with_credentials: bool);
|
fn SetWithCredentials(&self, with_credentials: bool);
|
||||||
fn Upload(&self) -> Temporary<XMLHttpRequestUpload>;
|
fn Upload(&self) -> Temporary<XMLHttpRequestUpload>;
|
||||||
fn Send(&self, _data: Option<SendParam>) -> ErrorResult;
|
fn Send(&self, data: Option<SendParam>) -> ErrorResult;
|
||||||
fn Abort(&self);
|
fn Abort(&self);
|
||||||
fn ResponseURL(&self) -> DOMString;
|
fn ResponseURL(&self) -> DOMString;
|
||||||
fn Status(&self) -> u16;
|
fn Status(&self) -> u16;
|
||||||
|
@ -435,7 +435,7 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
fn Upload(&self) -> Temporary<XMLHttpRequestUpload> {
|
fn Upload(&self) -> Temporary<XMLHttpRequestUpload> {
|
||||||
Temporary::new(self.upload.get())
|
Temporary::new(self.upload.get())
|
||||||
}
|
}
|
||||||
fn Send(&self, data: Option<DOMString>) -> ErrorResult {
|
fn Send(&self, data: Option<SendParam>) -> ErrorResult {
|
||||||
if self.ready_state.deref().get() != Opened || self.send_flag.deref().get() {
|
if self.ready_state.deref().get() != Opened || self.send_flag.deref().get() {
|
||||||
return Err(InvalidState); // Step 1, 2
|
return Err(InvalidState); // Step 1, 2
|
||||||
}
|
}
|
||||||
|
@ -444,13 +444,15 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
Get | Head => None, // Step 3
|
Get | Head => None, // Step 3
|
||||||
_ => data
|
_ => data
|
||||||
};
|
};
|
||||||
|
let extracted = data.map(|d| d.extract());
|
||||||
|
self.request_body_len.set(extracted.as_ref().map(|e| e.len()).unwrap_or(0));
|
||||||
|
|
||||||
// Step 6
|
// Step 6
|
||||||
self.upload_events.deref().set(false);
|
self.upload_events.deref().set(false);
|
||||||
// Step 7
|
// Step 7
|
||||||
self.upload_complete.deref().set(match data {
|
self.upload_complete.deref().set(match extracted {
|
||||||
None => true,
|
None => true,
|
||||||
Some (ref s) if s.len() == 0 => true,
|
Some (ref v) if v.len() == 0 => true,
|
||||||
_ => false
|
_ => false
|
||||||
});
|
});
|
||||||
let mut addr = None;
|
let mut addr = None;
|
||||||
|
@ -485,16 +487,27 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
let global = self.global.root();
|
let global = self.global.root();
|
||||||
let resource_task = global.deref().page().resource_task.deref().clone();
|
let resource_task = global.deref().page().resource_task.deref().clone();
|
||||||
let mut load_data = LoadData::new(self.request_url.deref().borrow().clone());
|
let mut load_data = LoadData::new(self.request_url.deref().borrow().clone());
|
||||||
load_data.data = data;
|
load_data.data = extracted;
|
||||||
|
|
||||||
// Default headers
|
// Default headers
|
||||||
let request_headers = self.request_headers.deref();
|
let request_headers = self.request_headers.deref();
|
||||||
if request_headers.borrow().content_type.is_none() {
|
if request_headers.borrow().content_type.is_none() {
|
||||||
request_headers.borrow_mut().content_type = Some(MediaType {
|
let parameters = vec!((String::from_str("charset"), String::from_str("UTF-8")));
|
||||||
type_: String::from_str("text"),
|
request_headers.borrow_mut().content_type = match data {
|
||||||
subtype: String::from_str("plain"),
|
Some(eString(_)) =>
|
||||||
parameters: vec!((String::from_str("charset"), String::from_str("UTF-8")))
|
Some(MediaType {
|
||||||
});
|
type_: String::from_str("text"),
|
||||||
|
subtype: String::from_str("plain"),
|
||||||
|
parameters: parameters
|
||||||
|
}),
|
||||||
|
Some(eURLSearchParams(_)) =>
|
||||||
|
Some(MediaType {
|
||||||
|
type_: String::from_str("application"),
|
||||||
|
subtype: String::from_str("x-www-form-urlencoded"),
|
||||||
|
parameters: parameters
|
||||||
|
}),
|
||||||
|
None => None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if request_headers.borrow().accept.is_none() {
|
if request_headers.borrow().accept.is_none() {
|
||||||
|
@ -839,7 +852,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
|
||||||
fn dispatch_upload_progress_event(&self, type_: DOMString, partial_load: Option<u64>) {
|
fn dispatch_upload_progress_event(&self, type_: DOMString, partial_load: Option<u64>) {
|
||||||
// If partial_load is None, loading has completed and we can just use the value from the request body
|
// If partial_load is None, loading has completed and we can just use the value from the request body
|
||||||
|
|
||||||
let total = self.request_body.len() as u64;
|
let total = self.request_body_len.get() as u64;
|
||||||
self.dispatch_progress_event(true, type_, partial_load.unwrap_or(total), Some(total));
|
self.dispatch_progress_event(true, type_, partial_load.unwrap_or(total), Some(total));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,3 +930,17 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
|
||||||
headers
|
headers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait Extractable {
|
||||||
|
fn extract(&self) -> Vec<u8>;
|
||||||
|
}
|
||||||
|
impl Extractable for SendParam {
|
||||||
|
fn extract(&self) -> Vec<u8> {
|
||||||
|
// http://fetch.spec.whatwg.org/#concept-fetchbodyinit-extract
|
||||||
|
let encoding = UTF_8 as &Encoding+Send;
|
||||||
|
match *self {
|
||||||
|
eString(ref s) => encoding.encode(s.as_slice(), EncodeReplace).unwrap(),
|
||||||
|
eURLSearchParams(ref usp) => usp.root().serialize(None) // Default encoding is UTF8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue