aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/eventsource.rs
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2016-10-14 11:57:22 -0700
committerKeith Yeung <kungfukeith11@gmail.com>2016-11-11 14:50:44 -0800
commit388c3bff7b5153407fd6d1bb6da8c0b0a6f3c35e (patch)
tree8b16ec443b06558efacd28133f1fc144d1c889ad /components/script/dom/eventsource.rs
parent72cb856e31eecd9310cbcf3745baa16fd77dc8e9 (diff)
downloadservo-388c3bff7b5153407fd6d1bb6da8c0b0a6f3c35e.tar.gz
servo-388c3bff7b5153407fd6d1bb6da8c0b0a6f3c35e.zip
Parse metadata in EventSource
Diffstat (limited to 'components/script/dom/eventsource.rs')
-rw-r--r--components/script/dom/eventsource.rs94
1 files changed, 88 insertions, 6 deletions
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index 04a968a327a..b1b70b5a658 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -6,7 +6,9 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventSourceBinding::{EventSourceInit, EventSourceMethods, Wrap};
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::str::DOMString;
use dom::eventtarget::EventTarget;
@@ -14,19 +16,22 @@ use dom::globalscope::GlobalScope;
use hyper::header::{Accept, qitem};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
+use mime::{Mime, TopLevel, SubLevel};
use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseListener, NetworkError};
use net_traits::request::{CacheMode, CorsSettings, CredentialsMode};
use net_traits::request::{RequestInit, RequestMode};
use network_listener::{NetworkListener, PreInvoke};
+use script_thread::{Runnable, RunnableWrapper};
use std::cell::Cell;
use std::sync::{Arc, Mutex};
+use task_source::TaskSource;
+use task_source::networking::NetworkingTaskSource;
use url::Url;
#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)]
/// https://html.spec.whatwg.org/multipage/#dom-eventsource-readystate
enum ReadyState {
Connecting = 0,
- #[allow(dead_code)]
Open = 1,
Closed = 2
}
@@ -36,12 +41,32 @@ pub struct EventSource {
eventtarget: EventTarget,
url: DOMRefCell<Option<Url>>,
request: DOMRefCell<Option<RequestInit>>,
- ready_state: Cell<EventSourceReadyState>,
+ ready_state: Cell<ReadyState>,
with_credentials: bool,
last_event_id: DOMRefCell<DOMString>
}
-struct EventSourceContext;
+struct EventSourceContext {
+ event_source: Trusted<EventSource>,
+ networking_task_source: NetworkingTaskSource,
+ wrapper: RunnableWrapper
+}
+
+impl EventSourceContext {
+ fn announce_the_connection(&self) {
+ let runnable = box AnnounceConnectionRunnable {
+ event_source: self.event_source.clone()
+ };
+ let _ = self.networking_task_source.queue_with_wrapper(runnable, &self.wrapper);
+ }
+
+ fn fail_the_connection(&self) {
+ let runnable = box FailConnectionRunnable {
+ event_source: self.event_source.clone()
+ };
+ let _ = self.networking_task_source.queue_with_wrapper(runnable, &self.wrapper);
+ }
+}
impl FetchResponseListener for EventSourceContext {
fn process_request_body(&mut self) {
@@ -52,8 +77,27 @@ impl FetchResponseListener for EventSourceContext {
// TODO
}
- fn process_response(&mut self, _metadata: Result<FetchMetadata, NetworkError>) {
- // TODO
+ fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
+ match metadata {
+ Ok(fm) => {
+ let meta = match fm {
+ FetchMetadata::Unfiltered(m) => m,
+ FetchMetadata::Filtered { unsafe_, .. } => unsafe_
+ };
+ match meta.content_type {
+ None => self.fail_the_connection(),
+ Some(ct) => match ct.into_inner().0 {
+ Mime(TopLevel::Text, SubLevel::EventStream, _) =>
+ self.announce_the_connection(),
+ _ => self.fail_the_connection()
+ }
+ }
+ }
+ Err(_) => {
+ // FIXME: Fail the connection for now, but it should really attempt to re-establish
+ self.fail_the_connection();
+ }
+ }
}
fn process_response_chunk(&mut self, mut _chunk: Vec<u8>) {
@@ -129,7 +173,11 @@ impl EventSource {
// Step 12
*ev.request.borrow_mut() = Some(request.clone());
// Step 14
- let context = EventSourceContext;
+ let context = EventSourceContext {
+ event_source: Trusted::new(&ev),
+ networking_task_source: global.networking_task_source(),
+ wrapper: global.get_runnable_wrapper()
+ };
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),
task_source: global.networking_task_source(),
@@ -176,3 +224,37 @@ impl EventSourceMethods for EventSource {
// TODO: Terminate ongoing fetch
}
}
+
+pub struct AnnounceConnectionRunnable {
+ event_source: Trusted<EventSource>,
+}
+
+impl Runnable for AnnounceConnectionRunnable {
+ fn name(&self) -> &'static str { "EventSource AnnounceConnectionRunnable" }
+
+ // https://html.spec.whatwg.org/multipage/#announce-the-connection
+ fn handler(self: Box<AnnounceConnectionRunnable>) {
+ let event_source = self.event_source.root();
+ if event_source.ready_state.get() != ReadyState::Closed {
+ event_source.ready_state.set(ReadyState::Open);
+ event_source.upcast::<EventTarget>().fire_event(atom!("open"));
+ }
+ }
+}
+
+pub struct FailConnectionRunnable {
+ event_source: Trusted<EventSource>,
+}
+
+impl Runnable for FailConnectionRunnable {
+ fn name(&self) -> &'static str { "EventSource FailConnectionRunnable" }
+
+ // https://html.spec.whatwg.org/multipage/#fail-the-connection
+ fn handler(self: Box<FailConnectionRunnable>) {
+ let event_source = self.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"));
+ }
+ }
+}