aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/eventsource.rs114
-rw-r--r--components/script/lib.rs1
2 files changed, 102 insertions, 13 deletions
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index b1b70b5a658..34fd2d427fb 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -9,7 +9,7 @@ use dom::bindings::error::{Error, Fallible};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
-use dom::bindings::reflector::reflect_dom_object;
+use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
@@ -21,13 +21,15 @@ use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseListener, NetworkE
use net_traits::request::{CacheMode, CorsSettings, CredentialsMode};
use net_traits::request::{RequestInit, RequestMode};
use network_listener::{NetworkListener, PreInvoke};
-use script_thread::{Runnable, RunnableWrapper};
+use script_thread::Runnable;
use std::cell::Cell;
use std::sync::{Arc, Mutex};
+use std::sync::mpsc::{Sender, channel};
use task_source::TaskSource;
-use task_source::networking::NetworkingTaskSource;
use url::Url;
+header! { (LastEventId, "Last-Event-ID") => [String] }
+
#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)]
/// https://html.spec.whatwg.org/multipage/#dom-eventsource-readystate
enum ReadyState {
@@ -47,24 +49,43 @@ pub struct EventSource {
}
struct EventSourceContext {
- event_source: Trusted<EventSource>,
- networking_task_source: NetworkingTaskSource,
- wrapper: RunnableWrapper
+ event_source: Trusted<EventSource>
}
impl EventSourceContext {
fn announce_the_connection(&self) {
+ let event_source = self.event_source.root();
let runnable = box AnnounceConnectionRunnable {
event_source: self.event_source.clone()
};
- let _ = self.networking_task_source.queue_with_wrapper(runnable, &self.wrapper);
+ let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
}
fn fail_the_connection(&self) {
+ let event_source = self.event_source.root();
let runnable = box FailConnectionRunnable {
event_source: self.event_source.clone()
};
- let _ = self.networking_task_source.queue_with_wrapper(runnable, &self.wrapper);
+ let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
+ }
+
+ // https://html.spec.whatwg.org/multipage/#reestablish-the-connection
+ fn reestablish_the_connection(&self) {
+ let event_source = self.event_source.root();
+ let (sender, receiver) = channel();
+ // Step 1
+ let runnable = box ReestablishConnectionRunnable {
+ event_source: self.event_source.clone(),
+ done_chan: sender
+ };
+ let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
+ // Step 4
+ let _ = receiver.recv();
+ // Step 5
+ let runnable = box RefetchRequestRunnable {
+ event_source: self.event_source.clone(),
+ };
+ let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
}
}
@@ -94,8 +115,7 @@ impl FetchResponseListener for EventSourceContext {
}
}
Err(_) => {
- // FIXME: Fail the connection for now, but it should really attempt to re-establish
- self.fail_the_connection();
+ self.reestablish_the_connection();
}
}
}
@@ -129,6 +149,14 @@ impl EventSource {
Wrap)
}
+ pub fn request(&self) -> RequestInit {
+ self.request.borrow().clone().unwrap()
+ }
+
+ pub fn last_event_id(&self) -> DOMString {
+ self.last_event_id.borrow().clone()
+ }
+
pub fn Constructor(global: &GlobalScope,
url: DOMString,
event_source_init: &EventSourceInit) -> Fallible<Root<EventSource>> {
@@ -174,9 +202,7 @@ impl EventSource {
*ev.request.borrow_mut() = Some(request.clone());
// Step 14
let context = EventSourceContext {
- event_source: Trusted::new(&ev),
- networking_task_source: global.networking_task_source(),
- wrapper: global.get_runnable_wrapper()
+ event_source: Trusted::new(&ev)
};
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),
@@ -258,3 +284,65 @@ impl Runnable for FailConnectionRunnable {
}
}
}
+
+pub struct ReestablishConnectionRunnable {
+ event_source: Trusted<EventSource>,
+ done_chan: Sender<()>
+}
+
+impl Runnable for ReestablishConnectionRunnable {
+ fn name(&self) -> &'static str { "EventSource ReestablishConnectionRunnable" }
+
+ // https://html.spec.whatwg.org/multipage/#reestablish-the-connection
+ fn handler(self: Box<ReestablishConnectionRunnable>) {
+ let event_source = self.event_source.root();
+ // Step 1.1
+ if event_source.ready_state.get() == ReadyState::Closed {
+ self.done_chan.send(()).unwrap();
+ return;
+ }
+ // Step 1.2
+ event_source.ready_state.set(ReadyState::Connecting);
+ // Step 1.3
+ event_source.upcast::<EventTarget>().fire_event(atom!("error"));
+ self.done_chan.send(()).unwrap();
+ }
+}
+
+pub struct RefetchRequestRunnable {
+ event_source: Trusted<EventSource>,
+}
+
+impl Runnable for RefetchRequestRunnable {
+ fn name(&self) -> &'static str { "EventSource RefetchRequestRunnable" }
+
+ // https://html.spec.whatwg.org/multipage/#reestablish-the-connection
+ fn handler(self: Box<RefetchRequestRunnable>) {
+ let event_source = self.event_source.root();
+ let global = event_source.global();
+ // Step 5.1
+ if event_source.ready_state.get() != ReadyState::Connecting {
+ return;
+ }
+ // Step 5.2
+ let mut request = event_source.request();
+ // Step 5.3
+ if !event_source.last_event_id().is_empty() {
+ request.headers.set(LastEventId(String::from(event_source.last_event_id())));
+ }
+ // Step 5.4
+ let context = EventSourceContext {
+ event_source: self.event_source.clone()
+ };
+ let listener = NetworkListener {
+ context: Arc::new(Mutex::new(context)),
+ task_source: global.networking_task_source(),
+ wrapper: Some(global.get_runnable_wrapper())
+ };
+ let (action_sender, action_receiver) = ipc::channel().unwrap();
+ ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
+ listener.notify_fetch(message.to().unwrap());
+ });
+ global.core_resource_thread().send(CoreResourceMsg::Fetch(request, action_sender)).unwrap();
+ }
+}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 94e9683ffaf..1ebb59a7ee4 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -48,6 +48,7 @@ extern crate heapsize;
#[macro_use] extern crate heapsize_derive;
extern crate html5ever;
#[macro_use] extern crate html5ever_atoms;
+#[macro_use]
extern crate hyper;
extern crate hyper_serde;
extern crate image;