diff options
author | Gregory Terzian <gterzian@users.noreply.github.com> | 2018-07-01 20:30:05 +0800 |
---|---|---|
committer | Gregory Terzian <gterzian@users.noreply.github.com> | 2018-07-29 16:42:59 +0800 |
commit | f2ee941da2f56b22d2258057a83998306e862350 (patch) | |
tree | dcbbd50e8799659084874b0eae4abe9a4f868a5b /components/script/dom/eventsource.rs | |
parent | ff62ca7c018eb3e6d50b516dc653e5090dbe7e37 (diff) | |
download | servo-f2ee941da2f56b22d2258057a83998306e862350.tar.gz servo-f2ee941da2f56b22d2258057a83998306e862350.zip |
Introduce DOMTracker, cancel eventsource fetch when aborting document load
Diffstat (limited to 'components/script/dom/eventsource.rs')
-rw-r--r-- | components/script/dom/eventsource.rs | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 48b762978ca..072a3dd0080 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -16,6 +16,7 @@ use dom::globalscope::GlobalScope; use dom::messageevent::MessageEvent; use dom_struct::dom_struct; use euclid::Length; +use fetch::FetchCanceller; use hyper::header::{Accept, qitem}; use ipc_channel::ipc; use ipc_channel::router::ROUTER; @@ -64,6 +65,7 @@ pub struct EventSource { ready_state: Cell<ReadyState>, with_credentials: bool, + canceller: DomRefCell<FetchCanceller>, } enum ParserState { @@ -118,19 +120,7 @@ impl EventSourceContext { if self.gen_id != event_source.generation_id.get() { return; } - let global = event_source.global(); - let event_source = self.event_source.clone(); - // FIXME(nox): Why are errors silenced here? - let _ = global.remote_event_task_source().queue( - task!(fail_the_event_source_connection: move || { - let event_source = event_source.root(); - if event_source.ready_state.get() != ReadyState::Closed { - event_source.ready_state.set(ReadyState::Closed); - event_source.upcast::<EventTarget>().fire_event(atom!("error")); - } - }), - &global, - ); + event_source.fail_the_connection(); } // https://html.spec.whatwg.org/multipage/#reestablish-the-connection @@ -410,6 +400,7 @@ impl EventSource { ready_state: Cell::new(ReadyState::Connecting), with_credentials: with_credentials, + canceller: DomRefCell::new(Default::default()) } } @@ -419,6 +410,29 @@ impl EventSource { Wrap) } + // https://html.spec.whatwg.org/multipage/#sse-processing-model:fail-the-connection-3 + pub fn cancel(&self) { + self.canceller.borrow_mut().cancel(); + self.fail_the_connection(); + } + + /// <https://html.spec.whatwg.org/multipage/#fail-the-connection> + pub fn fail_the_connection(&self) { + let global = self.global(); + let event_source = Trusted::new(self); + // FIXME(nox): Why are errors silenced here? + let _ = global.remote_event_task_source().queue( + task!(fail_the_event_source_connection: move || { + let event_source = event_source.root(); + if event_source.ready_state.get() != ReadyState::Closed { + event_source.ready_state.set(ReadyState::Closed); + event_source.upcast::<EventTarget>().fire_event(atom!("error")); + } + }), + &global, + ); + } + pub fn request(&self) -> RequestInit { self.request.borrow().clone().unwrap() } @@ -437,6 +451,7 @@ impl EventSource { }; // Step 1, 5 let ev = EventSource::new(global, url_record.clone(), event_source_init.withCredentials); + global.track_event_source(&ev); // Steps 6-7 let cors_attribute_state = if event_source_init.withCredentials { CorsSettings::UseCredentials @@ -491,13 +506,23 @@ impl EventSource { ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| { listener.notify_fetch(message.to().unwrap()); })); + let cancel_receiver = ev.canceller.borrow_mut().initialize(); global.core_resource_thread().send( - CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(action_sender, None))).unwrap(); + CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(action_sender, Some(cancel_receiver)))).unwrap(); // Step 13 Ok(ev) } } +// https://html.spec.whatwg.org/multipage/#garbage-collection-2 +impl Drop for EventSource { + fn drop(&mut self) { + // If an EventSource object is garbage collected while its connection is still open, + // the user agent must abort any instance of the fetch algorithm opened by this EventSource. + self.canceller.borrow_mut().cancel(); + } +} + impl EventSourceMethods for EventSource { // https://html.spec.whatwg.org/multipage/#handler-eventsource-onopen event_handler!(open, GetOnopen, SetOnopen); @@ -527,6 +552,7 @@ impl EventSourceMethods for EventSource { fn Close(&self) { let GenerationId(prev_id) = self.generation_id.get(); self.generation_id.set(GenerationId(prev_id + 1)); + self.canceller.borrow_mut().cancel(); self.ready_state.set(ReadyState::Closed); } } |