Use FetchCanceller in XHR

This commit is contained in:
Manish Goregaokar 2017-11-21 15:31:26 -08:00
parent 57bb4553c1
commit 78c8b4232f
No known key found for this signature in database
GPG key ID: 3BBF4D3E2EF79F98

View file

@ -38,6 +38,7 @@ use dom::xmlhttprequestupload::XMLHttpRequestUpload;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8}; use encoding_rs::{Encoding, UTF_8};
use euclid::Length; use euclid::Length;
use fetch::FetchCanceller;
use html5ever::serialize; use html5ever::serialize;
use html5ever::serialize::SerializeOpts; use html5ever::serialize::SerializeOpts;
use hyper::header::{ContentLength, ContentType, ContentEncoding}; use hyper::header::{ContentLength, ContentType, ContentEncoding};
@ -154,8 +155,7 @@ pub struct XMLHttpRequest {
response_status: Cell<Result<(), ()>>, response_status: Cell<Result<(), ()>>,
referrer_url: Option<ServoUrl>, referrer_url: Option<ServoUrl>,
referrer_policy: Option<ReferrerPolicy>, referrer_policy: Option<ReferrerPolicy>,
#[ignore_malloc_size_of = "channels are hard"] canceller: DomRefCell<FetchCanceller>,
cancellation_chan: DomRefCell<Option<ipc::IpcSender<()>>>,
} }
impl XMLHttpRequest { impl XMLHttpRequest {
@ -200,7 +200,7 @@ impl XMLHttpRequest {
response_status: Cell::new(Ok(())), response_status: Cell::new(Ok(())),
referrer_url: referrer_url, referrer_url: referrer_url,
referrer_policy: referrer_policy, referrer_policy: referrer_policy,
cancellation_chan: DomRefCell::new(None), canceller: DomRefCell::new(Default::default()),
} }
} }
pub fn new(global: &GlobalScope) -> DomRoot<XMLHttpRequest> { pub fn new(global: &GlobalScope) -> DomRoot<XMLHttpRequest> {
@ -978,6 +978,7 @@ impl XMLHttpRequest {
self.sync.get()); self.sync.get());
self.cancel_timeout(); self.cancel_timeout();
self.canceller.borrow_mut().ignore();
// Part of step 11, send() (processing response end of file) // Part of step 11, send() (processing response end of file)
// XXXManishearth handle errors, if any (substep 2) // XXXManishearth handle errors, if any (substep 2)
@ -994,6 +995,7 @@ impl XMLHttpRequest {
}, },
XHRProgress::Errored(_, e) => { XHRProgress::Errored(_, e) => {
self.cancel_timeout(); self.cancel_timeout();
self.canceller.borrow_mut().ignore();
self.discard_subsequent_responses(); self.discard_subsequent_responses();
self.send_flag.set(false); self.send_flag.set(false);
@ -1023,12 +1025,7 @@ impl XMLHttpRequest {
} }
fn terminate_ongoing_fetch(&self) { fn terminate_ongoing_fetch(&self) {
if let Some(ref cancel_chan) = *self.cancellation_chan.borrow() { self.canceller.borrow_mut().cancel();
// The receiver will be destroyed if the request has already completed;
// so we throw away the error. Cancellation is a courtesy call,
// we don't actually care if the other side heard.
let _ = cancel_chan.send(());
}
let GenerationId(prev_id) = self.generation_id.get(); let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1)); self.generation_id.set(GenerationId(prev_id + 1));
self.response_status.set(Ok(())); self.response_status.set(Ok(()));
@ -1322,8 +1319,7 @@ impl XMLHttpRequest {
(global.networking_task_source(), None) (global.networking_task_source(), None)
}; };
let (cancel_sender, cancel_receiver) = ipc::channel().unwrap(); let cancel_receiver = self.canceller.borrow_mut().initialize();
*self.cancellation_chan.borrow_mut() = Some(cancel_sender);
XMLHttpRequest::initiate_async_xhr(context.clone(), task_source, XMLHttpRequest::initiate_async_xhr(context.clone(), task_source,
global, init, cancel_receiver); global, init, cancel_receiver);