From d99d26cf1fc3cc2199cc8d84817c0b505e9634d2 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 4 Oct 2016 22:25:30 -0700 Subject: [PATCH 1/9] Implement the constructor for EventSource --- components/net_traits/request.rs | 9 +- components/script/dom/bindings/trace.rs | 3 +- components/script/dom/eventsource.rs | 113 +++++++++++++++++++----- components/script/fetch.rs | 5 +- 4 files changed, 105 insertions(+), 25 deletions(-) diff --git a/components/net_traits/request.rs b/components/net_traits/request.rs index 6cff552f2e8..c559b41fd9c 100644 --- a/components/net_traits/request.rs +++ b/components/net_traits/request.rs @@ -70,7 +70,7 @@ pub enum CredentialsMode { } /// [Cache mode](https://fetch.spec.whatwg.org/#concept-request-cache-mode) -#[derive(Copy, Clone, PartialEq, HeapSizeOf)] +#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)] pub enum CacheMode { Default, NoStore, @@ -111,14 +111,16 @@ pub enum CorsSettings { UseCredentials } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, HeapSizeOf)] pub struct RequestInit { #[serde(deserialize_with = "::hyper_serde::deserialize", serialize_with = "::hyper_serde::serialize")] + #[ignore_heap_size_of = "Defined in hyper"] pub method: Method, pub url: Url, #[serde(deserialize_with = "::hyper_serde::deserialize", serialize_with = "::hyper_serde::serialize")] + #[ignore_heap_size_of = "Defined in hyper"] pub headers: Headers, pub unsafe_request: bool, pub body: Option>, @@ -127,6 +129,7 @@ pub struct RequestInit { pub destination: Destination, pub synchronous: bool, pub mode: RequestMode, + pub cache_mode: CacheMode, pub use_cors_preflight: bool, pub credentials_mode: CredentialsMode, pub use_url_credentials: bool, @@ -152,6 +155,7 @@ impl Default for RequestInit { destination: Destination::None, synchronous: false, mode: RequestMode::NoCors, + cache_mode: CacheMode::Default, use_cors_preflight: false, credentials_mode: CredentialsMode::Omit, use_url_credentials: false, @@ -261,6 +265,7 @@ impl Request { req.use_cors_preflight = init.use_cors_preflight; req.credentials_mode = init.credentials_mode; req.use_url_credentials = init.use_url_credentials; + req.cache_mode.set(init.cache_mode); *req.referrer.borrow_mut() = if let Some(url) = init.referrer_url { Referrer::ReferrerUrl(url) } else { diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index b8274aec90c..8f5aaba2eca 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -63,7 +63,7 @@ use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::filemanager_thread::RelativePos; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; -use net_traits::request::Request; +use net_traits::request::{Request, RequestInit}; use net_traits::response::{Response, ResponseBody}; use net_traits::response::HttpsState; use net_traits::storage_thread::StorageType; @@ -349,6 +349,7 @@ no_jsmanaged_fields!(AttrValue); no_jsmanaged_fields!(Snapshot); no_jsmanaged_fields!(HttpsState); no_jsmanaged_fields!(Request); +no_jsmanaged_fields!(RequestInit); no_jsmanaged_fields!(SharedRt); no_jsmanaged_fields!(TouchpadPressurePhase); no_jsmanaged_fields!(USVString); diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index f05e73beafa..6736173943a 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -11,11 +11,20 @@ use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; +use hyper::header::{Accept, qitem}; +use ipc_channel::ipc; +use ipc_channel::router::ROUTER; +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 std::cell::Cell; +use std::sync::{Arc, Mutex}; use url::Url; #[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)] -enum EventSourceReadyState { +/// https://html.spec.whatwg.org/multipage/#dom-eventsource-readystate +enum ReadyState { Connecting = 0, #[allow(dead_code)] Open = 1, @@ -25,50 +34,114 @@ enum EventSourceReadyState { #[dom_struct] pub struct EventSource { eventtarget: EventTarget, - url: Url, + url: DOMRefCell>, + request: DOMRefCell>, ready_state: Cell, with_credentials: bool, last_event_id: DOMRefCell } +struct EventSourceContext; + +impl FetchResponseListener for EventSourceContext { + fn process_request_body(&mut self) { + // TODO + } + + fn process_request_eof(&mut self) { + // TODO + } + + fn process_response(&mut self, _metadata: Result) { + // TODO + } + + fn process_response_chunk(&mut self, mut _chunk: Vec) { + // TODO + } + + fn process_response_eof(&mut self, _response: Result<(), NetworkError>) { + // TODO + } +} + +impl PreInvoke for EventSourceContext {} + impl EventSource { - fn new_inherited(url: Url, with_credentials: bool) -> EventSource { + fn new_inherited(with_credentials: bool) -> EventSource { EventSource { eventtarget: EventTarget::new_inherited(), - url: url, - ready_state: Cell::new(EventSourceReadyState::Connecting), + url: DOMRefCell::new(None), + request: DOMRefCell::new(None), + ready_state: Cell::new(ReadyState::Connecting), with_credentials: with_credentials, last_event_id: DOMRefCell::new(DOMString::from("")) } } - fn new(global: &GlobalScope, url: Url, with_credentials: bool) -> Root { - reflect_dom_object(box EventSource::new_inherited(url, with_credentials), + fn new(global: &GlobalScope, with_credentials: bool) -> Root { + reflect_dom_object(box EventSource::new_inherited(with_credentials), global, Wrap) } pub fn Constructor(global: &GlobalScope, - url_str: DOMString, + url: DOMString, event_source_init: &EventSourceInit) -> Fallible> { - // Steps 1-2 - let base_url = global.get_url(); - let url = match base_url.join(&*url_str) { + // Step 1 + let ev = EventSource::new(global, event_source_init.withCredentials); + // TODO: Step 2 relevant settings object + // Step 3 + let base_url = global.api_base_url(); + let url_record = match base_url.join(&*url) { Ok(u) => u, + // Step 4 Err(_) => return Err(Error::Syntax) }; - // Step 3 - let event_source = EventSource::new(global, url, event_source_init.withCredentials); - // Step 4 // Step 5 - // Step 6 - // Step 7 + *ev.url.borrow_mut() = Some(url_record.clone()); + // Steps 6-7 + let cors_attribute_state = if event_source_init.withCredentials { + CorsSettings::UseCredentials + } else { + CorsSettings::Anonymous + }; // Step 8 - // Step 9 + // TODO: Step 9 set request's client settings + let mut request = RequestInit { + url: url_record, + origin: global.get_url(), + pipeline_id: Some(global.pipeline_id()), + // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request + use_url_credentials: true, + mode: RequestMode::CorsMode, + credentials_mode: if cors_attribute_state == CorsSettings::Anonymous { + CredentialsMode::CredentialsSameOrigin + } else { + CredentialsMode::Include + }, + ..RequestInit::default() + }; // Step 10 + request.headers.set(Accept(vec![qitem(mime!(Text / EventStream))])); // Step 11 - Ok(event_source) + request.cache_mode = CacheMode::NoStore; // Step 12 + *ev.request.borrow_mut() = Some(request.clone()); + // Step 14 + let context = EventSourceContext; + let listener = NetworkListener { + context: Arc::new(Mutex::new(context)), + script_chan: global.script_chan(), + wrapper: None + }; + 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(); + // Step 13 + Ok(ev) } } @@ -84,7 +157,7 @@ impl EventSourceMethods for EventSource { // https://html.spec.whatwg.org/multipage/#dom-eventsource-url fn Url(&self) -> DOMString { - DOMString::from(self.url.as_str()) + DOMString::from(self.url.borrow().clone().map_or("".to_owned(), Url::into_string)) } // https://html.spec.whatwg.org/multipage/#dom-eventsource-withcredentials @@ -99,7 +172,7 @@ impl EventSourceMethods for EventSource { // https://html.spec.whatwg.org/multipage/#dom-eventsource-close fn Close(&self) { - self.ready_state.set(EventSourceReadyState::Closed); + self.ready_state.set(ReadyState::Closed); // TODO: Terminate ongoing fetch } } diff --git a/components/script/fetch.rs b/components/script/fetch.rs index ed1a66fc683..9ba9fbf59cb 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -2,10 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::Bindings::RequestBinding::RequestInfo; use dom::bindings::codegen::Bindings::RequestBinding::RequestInit; use dom::bindings::codegen::Bindings::ResponseBinding::ResponseBinding::ResponseMethods; use dom::bindings::codegen::Bindings::ResponseBinding::ResponseType as DOMResponseType; -use dom::bindings::codegen::UnionTypes::RequestOrUSVString; use dom::bindings::error::Error; use dom::bindings::js::Root; use dom::bindings::refcounted::{Trusted, TrustedPromise}; @@ -62,12 +62,13 @@ fn request_init_from_request(request: NetTraitsRequest) -> NetTraitsRequestInit referrer_policy: request.referrer_policy.get(), pipeline_id: request.pipeline_id.get(), redirect_mode: request.redirect_mode.get(), + ..NetTraitsRequestInit::default() } } // https://fetch.spec.whatwg.org/#fetch-method #[allow(unrooted_must_root)] -pub fn Fetch(global: &GlobalScope, input: RequestOrUSVString, init: &RequestInit) -> Rc { +pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: &RequestInit) -> Rc { let core_resource_thread = global.core_resource_thread(); // Step 1 From 72cb856e31eecd9310cbcf3745baa16fd77dc8e9 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 13 Oct 2016 17:41:48 -0700 Subject: [PATCH 2/9] Properly implement TaskSource for NetworkingTaskSource --- components/script/dom/bluetooth.rs | 4 +-- components/script/dom/eventsource.rs | 4 +-- components/script/dom/globalscope.rs | 5 +-- components/script/dom/htmlimageelement.rs | 8 ++--- components/script/dom/htmllinkelement.rs | 4 +-- components/script/dom/htmlmediaelement.rs | 5 ++- components/script/dom/htmlscriptelement.rs | 4 +-- components/script/dom/websocket.rs | 38 +++++++++++++-------- components/script/dom/window.rs | 2 +- components/script/dom/workerglobalscope.rs | 5 +++ components/script/dom/xmlhttprequest.rs | 23 ++++++------- components/script/fetch.rs | 4 +-- components/script/network_listener.rs | 10 +++--- components/script/script_thread.rs | 7 ++-- components/script/task_source/networking.rs | 35 +++++++++++++------ 15 files changed, 89 insertions(+), 69 deletions(-) diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 1f5fd15c49f..0a6634f35dc 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -148,14 +148,14 @@ pub fn response_async( promise: &Rc, receiver: &T) -> IpcSender { let (action_sender, action_receiver) = ipc::channel().unwrap(); - let chan = receiver.global().networking_task_source(); + let task_source = receiver.global().networking_task_source(); let context = Arc::new(Mutex::new(BluetoothContext { promise: Some(TrustedPromise::new(promise.clone())), receiver: Trusted::new(receiver), })); let listener = NetworkListener { context: context, - script_chan: chan, + task_source: task_source, wrapper: None, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 6736173943a..04a968a327a 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -132,8 +132,8 @@ impl EventSource { let context = EventSourceContext; let listener = NetworkListener { context: Arc::new(Mutex::new(context)), - script_chan: global.script_chan(), - wrapper: None + 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| { diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index fc160675df5..2338dcf32e7 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -42,6 +42,7 @@ use std::collections::hash_map::Entry; use std::ffi::CString; use std::panic; use task_source::file_reading::FileReadingTaskSource; +use task_source::networking::NetworkingTaskSource; use time::{Timespec, get_time}; use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle}; use timers::{OneshotTimers, TimerCallback}; @@ -325,12 +326,12 @@ impl GlobalScope { /// `ScriptChan` to send messages to the networking task source of /// this of this global scope. - pub fn networking_task_source(&self) -> Box { + pub fn networking_task_source(&self) -> NetworkingTaskSource { if let Some(window) = self.downcast::() { return window.networking_task_source(); } if let Some(worker) = self.downcast::() { - return worker.script_chan(); + return worker.networking_task_source(); } unreachable!(); } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index e8a269c782c..d8ecda30943 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -26,8 +26,6 @@ use ipc_channel::ipc; use ipc_channel::router::ROUTER; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache_thread::{ImageResponder, ImageResponse}; -use script_runtime::CommonScriptMsg; -use script_runtime::ScriptThreadEventCategory::UpdateReplacedElement; use script_thread::Runnable; use std::i32; use std::sync::Arc; @@ -140,7 +138,7 @@ impl HTMLImageElement { let trusted_node = Trusted::new(self); let (responder_sender, responder_receiver) = ipc::channel().unwrap(); - let script_chan = window.networking_task_source(); + let task_source = window.networking_task_source(); let wrapper = window.get_runnable_wrapper(); ROUTER.add_route(responder_receiver.to_opaque(), box move |message| { // Return the image via a message to the script thread, which marks the element @@ -148,9 +146,7 @@ impl HTMLImageElement { let image_response = message.to().unwrap(); let runnable = box ImageResponseHandlerRunnable::new( trusted_node.clone(), image_response); - let runnable = wrapper.wrap_runnable(runnable); - let _ = script_chan.send(CommonScriptMsg::RunnableMsg( - UpdateReplacedElement, runnable)); + let _ = task_source.queue_with_wrapper(runnable, &wrapper); }); image_cache.request_image_and_metadata(img_url, diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 90499388153..5df64f62ca0 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -243,8 +243,8 @@ impl HTMLLinkElement { let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = NetworkListener { context: context, - script_chan: document.window().networking_task_source(), - wrapper: Some(document.window().get_runnable_wrapper()), + task_source: document.window().networking_task_source(), + wrapper: Some(document.window().get_runnable_wrapper()) }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { listener.notify_fetch(message.to().unwrap()); diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 0627bcf0ffb..09a1b7cc438 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -521,11 +521,10 @@ impl HTMLMediaElement { let context = Arc::new(Mutex::new(HTMLMediaElementContext::new(self, url.clone()))); let (action_sender, action_receiver) = ipc::channel().unwrap(); let window = window_from_node(self); - let script_chan = window.networking_task_source(); let listener = NetworkListener { context: context, - script_chan: script_chan, - wrapper: Some(window.get_runnable_wrapper()), + task_source: window.networking_task_source(), + wrapper: Some(window.get_runnable_wrapper()) }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 86e0987b666..68b65f93142 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -262,8 +262,8 @@ fn fetch_a_classic_script(script: &HTMLScriptElement, let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = NetworkListener { context: context, - script_chan: doc.window().networking_task_source(), - wrapper: Some(doc.window().get_runnable_wrapper()), + task_source: doc.window().networking_task_source(), + wrapper: Some(doc.window().get_runnable_wrapper()) }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index dd49f62d247..1764db20764 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -33,14 +33,16 @@ use net_traits::CoreResourceMsg::{SetCookiesForUrl, WebsocketConnect}; use net_traits::MessageData; use net_traits::hosts::replace_hosts; use net_traits::unwrap_websocket_protocol; -use script_runtime::{CommonScriptMsg, ScriptChan}; +use script_runtime::CommonScriptMsg; use script_runtime::ScriptThreadEventCategory::WebSocketEvent; -use script_thread::Runnable; +use script_thread::{Runnable, RunnableWrapper}; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; use std::ptr; use std::thread; +use task_source::TaskSource; +use task_source::networking::NetworkingTaskSource; use websocket::client::request::Url; use websocket::header::{Headers, WebSocketProtocol}; use websocket::ws::util::url::parse_url; @@ -141,7 +143,8 @@ mod close_code { } pub fn close_the_websocket_connection(address: Trusted, - sender: Box, + task_source: &NetworkingTaskSource, + wrapper: &RunnableWrapper, code: Option, reason: String) { let close_task = box CloseTask { @@ -150,17 +153,19 @@ pub fn close_the_websocket_connection(address: Trusted, code: code, reason: Some(reason), }; - sender.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, close_task)).unwrap(); + task_source.queue_with_wrapper(close_task, &wrapper).unwrap(); } -pub fn fail_the_websocket_connection(address: Trusted, sender: Box) { +pub fn fail_the_websocket_connection(address: Trusted, + task_source: &NetworkingTaskSource, + wrapper: &RunnableWrapper) { let close_task = box CloseTask { address: address, failed: true, code: Some(close_code::ABNORMAL), reason: None, }; - sender.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, close_task)).unwrap(); + task_source.queue_with_wrapper(close_task, &wrapper).unwrap(); } #[dom_struct] @@ -268,7 +273,8 @@ impl WebSocket { *ws.sender.borrow_mut() = Some(dom_action_sender); let moved_address = address.clone(); - let sender = global.networking_task_source(); + let task_source = global.networking_task_source(); + let wrapper = global.get_runnable_wrapper(); thread::spawn(move || { while let Ok(event) = dom_event_receiver.recv() { match event { @@ -278,20 +284,22 @@ impl WebSocket { headers: headers, protocols: protocols, }; - sender.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, open_thread)).unwrap(); + task_source.queue_with_wrapper(open_thread, &wrapper).unwrap(); }, WebSocketNetworkEvent::MessageReceived(message) => { let message_thread = box MessageReceivedTask { address: moved_address.clone(), message: message, }; - sender.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, message_thread)).unwrap(); + task_source.queue_with_wrapper(message_thread, &wrapper).unwrap(); }, WebSocketNetworkEvent::Fail => { - fail_the_websocket_connection(moved_address.clone(), sender.clone()); + fail_the_websocket_connection(moved_address.clone(), + &task_source, &wrapper); }, WebSocketNetworkEvent::Close(code, reason) => { - close_the_websocket_connection(moved_address.clone(), sender.clone(), code, reason); + close_the_websocket_connection(moved_address.clone(), + &task_source, &wrapper, code, reason); }, } } @@ -436,8 +444,8 @@ impl WebSocketMethods for WebSocket { self.ready_state.set(WebSocketRequestState::Closing); let address = Trusted::new(self); - let sender = self.global().networking_task_source(); - fail_the_websocket_connection(address, sender); + let task_source = self.global().networking_task_source(); + fail_the_websocket_connection(address, &task_source, &self.global().get_runnable_wrapper()); } WebSocketRequestState::Open => { self.ready_state.set(WebSocketRequestState::Closing); @@ -470,8 +478,8 @@ impl Runnable for ConnectionEstablishedTask { // Step 1: Protocols. if !self.protocols.is_empty() && self.headers.get::().is_none() { - let sender = ws.global().networking_task_source(); - fail_the_websocket_connection(self.address, sender); + let task_source = ws.global().networking_task_source(); + fail_the_websocket_connection(self.address, &task_source, &ws.global().get_runnable_wrapper()); return; } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index a78dcda8893..63485e45dfc 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -267,7 +267,7 @@ impl Window { self.user_interaction_task_source.clone() } - pub fn networking_task_source(&self) -> Box { + pub fn networking_task_source(&self) -> NetworkingTaskSource { self.networking_task_source.clone() } diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 2efa2920cb8..041ce8448de 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -41,6 +41,7 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::Receiver; use task_source::file_reading::FileReadingTaskSource; +use task_source::networking::NetworkingTaskSource; use timers::{IsInterval, TimerCallback}; use url::Url; @@ -361,6 +362,10 @@ impl WorkerGlobalScope { FileReadingTaskSource(self.script_chan()) } + pub fn networking_task_source(&self) -> NetworkingTaskSource { + NetworkingTaskSource(self.script_chan()) + } + pub fn new_script_pair(&self) -> (Box, Box) { let dedicated = self.downcast::(); if let Some(dedicated) = dedicated { diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index ab603f5c444..c07f445a27b 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -49,13 +49,12 @@ use js::jsapi::{JSContext, JS_ParseJSON}; use js::jsapi::JS_ClearPendingException; use js::jsval::{JSVal, NullValue, UndefinedValue}; use msg::constellation_msg::PipelineId; -use net_traits::{CoreResourceThread, FetchMetadata, FilteredMetadata}; +use net_traits::{FetchMetadata, FilteredMetadata}; use net_traits::{FetchResponseListener, LoadOrigin, NetworkError, ReferrerPolicy}; use net_traits::CoreResourceMsg::Fetch; use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode}; use net_traits::trim_http_whitespace; use network_listener::{NetworkListener, PreInvoke}; -use script_runtime::ScriptChan; use servo_atoms::Atom; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -63,6 +62,7 @@ use std::cell::Cell; use std::default::Default; use std::str; use std::sync::{Arc, Mutex}; +use task_source::networking::NetworkingTaskSource; use time; use timers::{OneshotTimerCallback, OneshotTimerHandle}; use url::{Position, Url}; @@ -214,8 +214,8 @@ impl XMLHttpRequest { } fn initiate_async_xhr(context: Arc>, - script_chan: Box, - core_resource_thread: CoreResourceThread, + task_source: NetworkingTaskSource, + global: &GlobalScope, init: RequestInit) { impl FetchResponseListener for XHRContext { fn process_request_body(&mut self) { @@ -262,13 +262,13 @@ impl XMLHttpRequest { let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = NetworkListener { context: context, - script_chan: script_chan, - wrapper: None, + task_source: task_source, + wrapper: Some(global.get_runnable_wrapper()) }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { listener.notify_fetch(message.to().unwrap()); }); - core_resource_thread.send(Fetch(init, action_sender)).unwrap(); + global.core_resource_thread().send(Fetch(init, action_sender)).unwrap(); } } @@ -1293,16 +1293,15 @@ impl XMLHttpRequest { sync_status: DOMRefCell::new(None), })); - let (script_chan, script_port) = if self.sync.get() { + let (task_source, script_port) = if self.sync.get() { let (tx, rx) = global.new_script_pair(); - (tx, Some(rx)) + (NetworkingTaskSource(tx), Some(rx)) } else { (global.networking_task_source(), None) }; - let core_resource_thread = global.core_resource_thread(); - XMLHttpRequest::initiate_async_xhr(context.clone(), script_chan, - core_resource_thread, init); + XMLHttpRequest::initiate_async_xhr(context.clone(), task_source, + global, init); if let Some(script_port) = script_port { loop { diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 9ba9fbf59cb..740099344bf 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -97,8 +97,8 @@ pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: &RequestInit) -> Rc })); let listener = NetworkListener { context: fetch_context, - script_chan: global.networking_task_source(), - wrapper: None, + task_source: global.networking_task_source(), + wrapper: Some(global.get_runnable_wrapper()) }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs index cd0158409f1..5a96317fb18 100644 --- a/components/script/network_listener.rs +++ b/components/script/network_listener.rs @@ -4,16 +4,16 @@ use bluetooth_traits::{BluetoothResponseListener, BluetoothResponseResult}; use net_traits::{Action, FetchResponseListener, FetchResponseMsg}; -use script_runtime::{CommonScriptMsg, ScriptChan}; -use script_runtime::ScriptThreadEventCategory::NetworkEvent; use script_thread::{Runnable, RunnableWrapper}; use std::sync::{Arc, Mutex}; +use task_source::TaskSource; +use task_source::networking::NetworkingTaskSource; /// An off-thread sink for async network event runnables. All such events are forwarded to /// a target thread, where they are invoked on the provided context object. pub struct NetworkListener { pub context: Arc>, - pub script_chan: Box, + pub task_source: NetworkingTaskSource, pub wrapper: Option, } @@ -24,9 +24,9 @@ impl NetworkListener { action: action, }; let result = if let Some(ref wrapper) = self.wrapper { - self.script_chan.send(CommonScriptMsg::RunnableMsg(NetworkEvent, wrapper.wrap_runnable(runnable))) + self.task_source.queue_with_wrapper(runnable, wrapper) } else { - self.script_chan.send(CommonScriptMsg::RunnableMsg(NetworkEvent, runnable)) + self.task_source.queue_wrapperless(runnable) }; if let Err(err) = result { warn!("failed to deliver network data: {:?}", err); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index cccfbda842d..403dafda0cb 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -659,7 +659,7 @@ impl ScriptThread { chan: MainThreadScriptChan(chan.clone()), dom_manipulation_task_source: DOMManipulationTaskSource(chan.clone()), user_interaction_task_source: UserInteractionTaskSource(chan.clone()), - networking_task_source: NetworkingTaskSource(chan.clone()), + networking_task_source: NetworkingTaskSource(boxed_script_sender.clone()), history_traversal_task_source: HistoryTraversalTaskSource(chan), file_reading_task_source: FileReadingTaskSource(boxed_script_sender), @@ -1623,7 +1623,6 @@ impl ScriptThread { let MainThreadScriptChan(ref sender) = self.chan; let DOMManipulationTaskSource(ref dom_sender) = self.dom_manipulation_task_source; let UserInteractionTaskSource(ref user_sender) = self.user_interaction_task_source; - let NetworkingTaskSource(ref network_sender) = self.networking_task_source; let HistoryTraversalTaskSource(ref history_sender) = self.history_traversal_task_source; let (ipc_timer_event_chan, ipc_timer_event_port) = ipc::channel().unwrap(); @@ -1635,7 +1634,7 @@ impl ScriptThread { MainThreadScriptChan(sender.clone()), DOMManipulationTaskSource(dom_sender.clone()), UserInteractionTaskSource(user_sender.clone()), - NetworkingTaskSource(network_sender.clone()), + self.networking_task_source.clone(), HistoryTraversalTaskSource(history_sender.clone()), self.file_reading_task_source.clone(), self.image_cache_channel.clone(), @@ -2050,7 +2049,7 @@ impl ScriptThread { let (action_sender, action_receiver) = ipc::channel().unwrap(); let listener = NetworkListener { context: context, - script_chan: self.chan.clone(), + task_source: self.networking_task_source.clone(), wrapper: None, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { diff --git a/components/script/task_source/networking.rs b/components/script/task_source/networking.rs index 4f85ac6c3e6..8306a4789bb 100644 --- a/components/script/task_source/networking.rs +++ b/components/script/task_source/networking.rs @@ -2,19 +2,32 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use script_runtime::{CommonScriptMsg, ScriptChan}; -use script_thread::MainThreadScriptMsg; -use std::sync::mpsc::Sender; +use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; +use script_thread::{Runnable, RunnableWrapper}; +use task_source::TaskSource; #[derive(JSTraceable)] -pub struct NetworkingTaskSource(pub Sender); +pub struct NetworkingTaskSource(pub Box); -impl ScriptChan for NetworkingTaskSource { - fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { - self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ()) - } - - fn clone(&self) -> Box { - box NetworkingTaskSource((&self.0).clone()) +impl Clone for NetworkingTaskSource { + fn clone(&self) -> NetworkingTaskSource { + NetworkingTaskSource(self.0.clone()) + } +} + +impl TaskSource for NetworkingTaskSource { + fn queue_with_wrapper(&self, + msg: Box, + wrapper: &RunnableWrapper) + -> Result<(), ()> + where T: Runnable + Send + 'static { + self.0.send(CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::NetworkEvent, + wrapper.wrap_runnable(msg))) + } +} + +impl NetworkingTaskSource { + pub fn queue_wrapperless(&self, msg: Box) -> Result<(), ()> { + self.0.send(CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::NetworkEvent, msg)) } } From 388c3bff7b5153407fd6d1bb6da8c0b0a6f3c35e Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 14 Oct 2016 11:57:22 -0700 Subject: [PATCH 3/9] Parse metadata in EventSource --- components/script/dom/eventsource.rs | 94 ++++++++++++++++++++++++++-- 1 file 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>, request: DOMRefCell>, - ready_state: Cell, + ready_state: Cell, with_credentials: bool, last_event_id: DOMRefCell } -struct EventSourceContext; +struct EventSourceContext { + event_source: Trusted, + 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) { - // TODO + fn process_response(&mut self, metadata: Result) { + 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) { @@ -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, +} + +impl Runnable for AnnounceConnectionRunnable { + fn name(&self) -> &'static str { "EventSource AnnounceConnectionRunnable" } + + // https://html.spec.whatwg.org/multipage/#announce-the-connection + fn handler(self: Box) { + 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::().fire_event(atom!("open")); + } + } +} + +pub struct FailConnectionRunnable { + event_source: Trusted, +} + +impl Runnable for FailConnectionRunnable { + fn name(&self) -> &'static str { "EventSource FailConnectionRunnable" } + + // https://html.spec.whatwg.org/multipage/#fail-the-connection + fn handler(self: Box) { + 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::().fire_event(atom!("error")); + } + } +} From 9afc17cd3a62b0abab8f1f591cd7dbcff4766d79 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 14 Oct 2016 12:17:39 -0700 Subject: [PATCH 4/9] Remove preferences in EventSource.webidl --- components/script/dom/webidls/EventSource.webidl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/script/dom/webidls/EventSource.webidl b/components/script/dom/webidls/EventSource.webidl index b9cf82d6a3e..11c30e959d4 100644 --- a/components/script/dom/webidls/EventSource.webidl +++ b/components/script/dom/webidls/EventSource.webidl @@ -7,8 +7,7 @@ */ [Constructor(DOMString url, optional EventSourceInit eventSourceInitDict), - Exposed=(Window,Worker), - Pref="dom.eventsource.enabled"] + Exposed=(Window,Worker)] interface EventSource : EventTarget { readonly attribute DOMString url; readonly attribute boolean withCredentials; From 2924726b0a24fbf1c82ff3c4334ed08cae397f08 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sat, 15 Oct 2016 19:25:31 -0700 Subject: [PATCH 5/9] Implement reestablishing the connection for EventSource And remove unneeded fields in EventSourceContext --- components/script/dom/eventsource.rs | 114 ++++++++++++++++++++++++--- components/script/lib.rs | 1 + 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, - networking_task_source: NetworkingTaskSource, - wrapper: RunnableWrapper + event_source: Trusted } 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> { @@ -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, + 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) { + 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::().fire_event(atom!("error")); + self.done_chan.send(()).unwrap(); + } +} + +pub struct RefetchRequestRunnable { + event_source: Trusted, +} + +impl Runnable for RefetchRequestRunnable { + fn name(&self) -> &'static str { "EventSource RefetchRequestRunnable" } + + // https://html.spec.whatwg.org/multipage/#reestablish-the-connection + fn handler(self: Box) { + 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; From c198bfa388df0b5c6c80538f0b232d447326f084 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 16 Oct 2016 12:19:27 -0700 Subject: [PATCH 6/9] Add GenerationId to EventSource --- components/script/dom/eventsource.rs | 46 +++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 34fd2d427fb..780d4563469 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -30,6 +30,9 @@ use url::Url; header! { (LastEventId, "Last-Event-ID") => [String] } +#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)] +struct GenerationId(u32); + #[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)] /// https://html.spec.whatwg.org/multipage/#dom-eventsource-readystate enum ReadyState { @@ -43,18 +46,24 @@ pub struct EventSource { eventtarget: EventTarget, url: DOMRefCell>, request: DOMRefCell>, + last_event_id: DOMRefCell, + generation_id: Cell, + ready_state: Cell, with_credentials: bool, - last_event_id: DOMRefCell } struct EventSourceContext { - event_source: Trusted + event_source: Trusted, + gen_id: GenerationId } impl EventSourceContext { fn announce_the_connection(&self) { let event_source = self.event_source.root(); + if self.gen_id != event_source.generation_id.get() { + return; + } let runnable = box AnnounceConnectionRunnable { event_source: self.event_source.clone() }; @@ -63,6 +72,9 @@ impl EventSourceContext { fn fail_the_connection(&self) { let event_source = self.event_source.root(); + if self.gen_id != event_source.generation_id.get() { + return; + } let runnable = box FailConnectionRunnable { event_source: self.event_source.clone() }; @@ -78,13 +90,23 @@ impl EventSourceContext { event_source: self.event_source.clone(), done_chan: sender }; + if self.gen_id != self.event_source.root().generation_id.get() { + return; + } let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); // Step 4 + if self.gen_id != self.event_source.root().generation_id.get() { + return; + } let _ = receiver.recv(); // Step 5 let runnable = box RefetchRequestRunnable { event_source: self.event_source.clone(), + gen_id: self.gen_id }; + if self.gen_id != self.event_source.root().generation_id.get() { + return; + } let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); } } @@ -129,7 +151,11 @@ impl FetchResponseListener for EventSourceContext { } } -impl PreInvoke for EventSourceContext {} +impl PreInvoke for EventSourceContext { + fn should_invoke(&self) -> bool { + self.event_source.root().generation_id.get() == self.gen_id + } +} impl EventSource { fn new_inherited(with_credentials: bool) -> EventSource { @@ -137,9 +163,11 @@ impl EventSource { eventtarget: EventTarget::new_inherited(), url: DOMRefCell::new(None), request: DOMRefCell::new(None), + last_event_id: DOMRefCell::new(DOMString::from("")), + generation_id: Cell::new(GenerationId(0)), + ready_state: Cell::new(ReadyState::Connecting), with_credentials: with_credentials, - last_event_id: DOMRefCell::new(DOMString::from("")) } } @@ -202,7 +230,8 @@ impl EventSource { *ev.request.borrow_mut() = Some(request.clone()); // Step 14 let context = EventSourceContext { - event_source: Trusted::new(&ev) + event_source: Trusted::new(&ev), + gen_id: ev.generation_id.get() }; let listener = NetworkListener { context: Arc::new(Mutex::new(context)), @@ -246,8 +275,9 @@ impl EventSourceMethods for EventSource { // https://html.spec.whatwg.org/multipage/#dom-eventsource-close fn Close(&self) { + let GenerationId(prev_id) = self.generation_id.get(); + self.generation_id.set(GenerationId(prev_id + 1)); self.ready_state.set(ReadyState::Closed); - // TODO: Terminate ongoing fetch } } @@ -311,6 +341,7 @@ impl Runnable for ReestablishConnectionRunnable { pub struct RefetchRequestRunnable { event_source: Trusted, + gen_id: GenerationId } impl Runnable for RefetchRequestRunnable { @@ -332,7 +363,8 @@ impl Runnable for RefetchRequestRunnable { } // Step 5.4 let context = EventSourceContext { - event_source: self.event_source.clone() + event_source: self.event_source.clone(), + gen_id: self.gen_id }; let listener = NetworkListener { context: Arc::new(Mutex::new(context)), From 0b32b624a7746a10ddfa7701fa316dfdbd59ee54 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 27 Oct 2016 02:48:20 -0700 Subject: [PATCH 7/9] Interpret event stream --- components/script/dom/eventsource.rs | 255 ++++++++++++++++++++++++--- 1 file changed, 229 insertions(+), 26 deletions(-) diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 780d4563469..2bc10f244ac 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -11,25 +11,39 @@ use dom::bindings::js::Root; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; +use dom::event::Event; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; +use dom::messageevent::MessageEvent; +use encoding::Encoding; +use encoding::all::UTF_8; use hyper::header::{Accept, qitem}; use ipc_channel::ipc; use ipc_channel::router::ROUTER; +use js::conversions::ToJSValConvertible; +use js::jsapi::JSAutoCompartment; +use js::jsval::UndefinedValue; 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; +use servo_atoms::Atom; use std::cell::Cell; +use std::mem; +use std::str::{Chars, FromStr}; use std::sync::{Arc, Mutex}; use std::sync::mpsc::{Sender, channel}; +use std::thread; +use std::time::Duration; use task_source::TaskSource; use url::Url; header! { (LastEventId, "Last-Event-ID") => [String] } +const DEFAULT_RECONNECTION_TIME: u64 = 5000; + #[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)] struct GenerationId(u32); @@ -44,18 +58,34 @@ enum ReadyState { #[dom_struct] pub struct EventSource { eventtarget: EventTarget, - url: DOMRefCell>, + url: Url, request: DOMRefCell>, last_event_id: DOMRefCell, + reconnection_time: Cell, generation_id: Cell, ready_state: Cell, with_credentials: bool, } +enum ParserState { + Field, + Comment, + Value, + Eol +} + struct EventSourceContext { event_source: Trusted, - gen_id: GenerationId + gen_id: GenerationId, + parser_state: ParserState, + field: String, + value: String, + origin: String, + + event_type: String, + data: String, + last_event_id: String, } impl EventSourceContext { @@ -94,6 +124,9 @@ impl EventSourceContext { return; } let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); + // Step 2 + thread::sleep(Duration::from_millis(event_source.reconnection_time.get())); + // TODO Step 3: Optionally wait some more // Step 4 if self.gen_id != self.event_source.root().generation_id.get() { return; @@ -102,13 +135,146 @@ impl EventSourceContext { // Step 5 let runnable = box RefetchRequestRunnable { event_source: self.event_source.clone(), - gen_id: self.gen_id + gen_id: self.gen_id, + + event_type: self.event_type.clone(), + data: self.data.clone(), + last_event_id: self.last_event_id.clone(), }; if self.gen_id != self.event_source.root().generation_id.get() { return; } let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); } + + // https://html.spec.whatwg.org/multipage/#processField + fn process_field(&mut self) { + match &*self.field { + "event" => mem::swap(&mut self.event_type, &mut self.value), + "data" => { + self.data.push_str(&self.value); + self.data.push('\n'); + } + "id" => mem::swap(&mut self.last_event_id, &mut self.value), + "retry" => if let Ok(time) = u64::from_str(&self.value) { + self.event_source.root().reconnection_time.set(time); + }, + _ => () + } + + self.field.clear(); + self.value.clear(); + } + + // https://html.spec.whatwg.org/multipage/#dispatchMessage + #[allow(unsafe_code)] + fn dispatch_event(&mut self) { + let event_source = self.event_source.root(); + // Step 1 + *event_source.last_event_id.borrow_mut() = DOMString::from(self.last_event_id.clone()); + // Step 2 + if self.data.is_empty() { + self.data.clear(); + self.event_type.clear(); + return; + } + // Step 3 + if let Some(last) = self.data.pop() { + if last != '\n' { + self.data.push(last); + } + } + // Step 6 + let type_ = if !self.event_type.is_empty() { + Atom::from(self.event_type.clone()) + } else { + atom!("message") + }; + // Steps 4-5 + let event = { + let _ac = JSAutoCompartment::new(event_source.global().get_cx(), + event_source.reflector().get_jsobject().get()); + rooted!(in(event_source.global().get_cx()) let mut data = UndefinedValue()); + unsafe { self.data.to_jsval(event_source.global().get_cx(), data.handle_mut()) }; + MessageEvent::new(&*event_source.global(), type_, false, false, data.handle(), + DOMString::from(self.origin.clone()), + event_source.last_event_id.borrow().clone()) + }; + // Step 7 + self.event_type.clear(); + self.data.clear(); + // Step 8 + let runnable = box DispatchEventRunnable { + event_source: self.event_source.clone(), + event: Trusted::new(&event) + }; + let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); + } + + // https://html.spec.whatwg.org/multipage/#event-stream-interpretation + fn parse(&mut self, stream: Chars) { + let mut stream = stream.peekable(); + + while let Some(ch) = stream.next() { + match (ch, &self.parser_state) { + (':', &ParserState::Eol) => self.parser_state = ParserState::Comment, + (':', &ParserState::Field) => { + self.parser_state = ParserState::Value; + if let Some(&' ') = stream.peek() { + stream.next(); + } + } + + ('\n', &ParserState::Value) => { + self.parser_state = ParserState::Eol; + self.process_field(); + } + ('\r', &ParserState::Value) => { + if let Some(&'\n') = stream.peek() { + continue; + } + self.parser_state = ParserState::Eol; + self.process_field(); + } + + ('\n', &ParserState::Field) => { + self.parser_state = ParserState::Eol; + self.process_field(); + } + ('\r', &ParserState::Field) => { + if let Some(&'\n') = stream.peek() { + continue; + } + self.parser_state = ParserState::Eol; + self.process_field(); + } + + ('\n', &ParserState::Eol) => self.dispatch_event(), + ('\r', &ParserState::Eol) => { + if let Some(&'\n') = stream.peek() { + continue; + } + self.dispatch_event(); + } + + ('\n', &ParserState::Comment) => self.parser_state = ParserState::Eol, + ('\r', &ParserState::Comment) => { + if let Some(&'\n') = stream.peek() { + continue; + } + self.parser_state = ParserState::Eol; + } + + (_, &ParserState::Field) => self.field.push(ch), + (_, &ParserState::Value) => self.value.push(ch), + (_, &ParserState::Eol) => { + self.parser_state = ParserState::Field; + self.field.push(ch); + } + (_, &ParserState::Comment) => (), + } + } + } } impl FetchResponseListener for EventSourceContext { @@ -130,8 +296,10 @@ impl FetchResponseListener for EventSourceContext { 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(), + Mime(TopLevel::Text, SubLevel::EventStream, _) => { + self.origin = meta.final_url.origin().unicode_serialization(); + self.announce_the_connection(); + } _ => self.fail_the_connection() } } @@ -142,12 +310,14 @@ impl FetchResponseListener for EventSourceContext { } } - fn process_response_chunk(&mut self, mut _chunk: Vec) { - // TODO + fn process_response_chunk(&mut self, chunk: Vec) { + let mut stream = String::new(); + UTF_8.raw_decoder().raw_feed(&chunk, &mut stream); + self.parse(stream.chars()) } fn process_response_eof(&mut self, _response: Result<(), NetworkError>) { - // TODO + } } @@ -158,12 +328,13 @@ impl PreInvoke for EventSourceContext { } impl EventSource { - fn new_inherited(with_credentials: bool) -> EventSource { + fn new_inherited(url: Url, with_credentials: bool) -> EventSource { EventSource { eventtarget: EventTarget::new_inherited(), - url: DOMRefCell::new(None), + url: url, request: DOMRefCell::new(None), last_event_id: DOMRefCell::new(DOMString::from("")), + reconnection_time: Cell::new(DEFAULT_RECONNECTION_TIME), generation_id: Cell::new(GenerationId(0)), ready_state: Cell::new(ReadyState::Connecting), @@ -171,8 +342,8 @@ impl EventSource { } } - fn new(global: &GlobalScope, with_credentials: bool) -> Root { - reflect_dom_object(box EventSource::new_inherited(with_credentials), + fn new(global: &GlobalScope, url: Url, with_credentials: bool) -> Root { + reflect_dom_object(box EventSource::new_inherited(url, with_credentials), global, Wrap) } @@ -181,15 +352,9 @@ impl EventSource { 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> { - // Step 1 - let ev = EventSource::new(global, event_source_init.withCredentials); // TODO: Step 2 relevant settings object // Step 3 let base_url = global.api_base_url(); @@ -198,8 +363,8 @@ impl EventSource { // Step 4 Err(_) => return Err(Error::Syntax) }; - // Step 5 - *ev.url.borrow_mut() = Some(url_record.clone()); + // Step 1, 5 + let ev = EventSource::new(global, url_record.clone(), event_source_init.withCredentials); // Steps 6-7 let cors_attribute_state = if event_source_init.withCredentials { CorsSettings::UseCredentials @@ -231,7 +396,15 @@ impl EventSource { // Step 14 let context = EventSourceContext { event_source: Trusted::new(&ev), - gen_id: ev.generation_id.get() + gen_id: ev.generation_id.get(), + parser_state: ParserState::Eol, + field: String::new(), + value: String::new(), + origin: String::new(), + + event_type: String::new(), + data: String::new(), + last_event_id: String::new(), }; let listener = NetworkListener { context: Arc::new(Mutex::new(context)), @@ -260,7 +433,7 @@ impl EventSourceMethods for EventSource { // https://html.spec.whatwg.org/multipage/#dom-eventsource-url fn Url(&self) -> DOMString { - DOMString::from(self.url.borrow().clone().map_or("".to_owned(), Url::into_string)) + DOMString::from(self.url.as_str()) } // https://html.spec.whatwg.org/multipage/#dom-eventsource-withcredentials @@ -341,7 +514,11 @@ impl Runnable for ReestablishConnectionRunnable { pub struct RefetchRequestRunnable { event_source: Trusted, - gen_id: GenerationId + gen_id: GenerationId, + + event_type: String, + data: String, + last_event_id: String, } impl Runnable for RefetchRequestRunnable { @@ -358,13 +535,21 @@ impl Runnable for RefetchRequestRunnable { // 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()))); + if !event_source.last_event_id.borrow().is_empty() { + request.headers.set(LastEventId(String::from(event_source.last_event_id.borrow().clone()))); } // Step 5.4 let context = EventSourceContext { event_source: self.event_source.clone(), - gen_id: self.gen_id + gen_id: self.gen_id, + parser_state: ParserState::Eol, + field: String::new(), + value: String::new(), + origin: String::new(), + + event_type: self.event_type.clone(), + data: self.data.clone(), + last_event_id: self.last_event_id.clone() }; let listener = NetworkListener { context: Arc::new(Mutex::new(context)), @@ -378,3 +563,21 @@ impl Runnable for RefetchRequestRunnable { global.core_resource_thread().send(CoreResourceMsg::Fetch(request, action_sender)).unwrap(); } } + +pub struct DispatchEventRunnable { + event_source: Trusted, + event: Trusted, +} + +impl Runnable for DispatchEventRunnable { + fn name(&self) -> &'static str { "EventSource DispatchEventRunnable" } + + // https://html.spec.whatwg.org/multipage/#dispatchMessage + fn handler(self: Box) { + let event_source = self.event_source.root(); + // Step 8 + if event_source.ready_state.get() != ReadyState::Closed { + self.event.root().upcast::().fire(&event_source.upcast()); + } + } +} From a5c2c0ba4b4691d6b2f189488890bf647c125d7d Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 28 Oct 2016 03:09:05 -0700 Subject: [PATCH 8/9] Use a timer callback when re-establishing a connection --- components/script/dom/eventsource.rs | 100 +++++++++------------------ components/script/timers.rs | 3 + 2 files changed, 36 insertions(+), 67 deletions(-) diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 2bc10f244ac..2eabfcbc8b0 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -17,6 +17,7 @@ use dom::globalscope::GlobalScope; use dom::messageevent::MessageEvent; use encoding::Encoding; use encoding::all::UTF_8; +use euclid::length::Length; use hyper::header::{Accept, qitem}; use ipc_channel::ipc; use ipc_channel::router::ROUTER; @@ -24,7 +25,7 @@ use js::conversions::ToJSValConvertible; use js::jsapi::JSAutoCompartment; use js::jsval::UndefinedValue; use mime::{Mime, TopLevel, SubLevel}; -use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseListener, NetworkError}; +use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseMsg, FetchResponseListener, NetworkError}; use net_traits::request::{CacheMode, CorsSettings, CredentialsMode}; use net_traits::request::{RequestInit, RequestMode}; use network_listener::{NetworkListener, PreInvoke}; @@ -34,10 +35,8 @@ use std::cell::Cell; use std::mem; use std::str::{Chars, FromStr}; use std::sync::{Arc, Mutex}; -use std::sync::mpsc::{Sender, channel}; -use std::thread; -use std::time::Duration; use task_source::TaskSource; +use timers::OneshotTimerCallback; use url::Url; header! { (LastEventId, "Last-Event-ID") => [String] } @@ -78,6 +77,8 @@ enum ParserState { struct EventSourceContext { event_source: Trusted, gen_id: GenerationId, + action_sender: ipc::IpcSender, + parser_state: ParserState, field: String, value: String, @@ -114,36 +115,16 @@ impl EventSourceContext { // 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(); + + if self.gen_id != event_source.generation_id.get() { + return; + } + // Step 1 let runnable = box ReestablishConnectionRunnable { event_source: self.event_source.clone(), - done_chan: sender + action_sender: self.action_sender.clone() }; - if self.gen_id != self.event_source.root().generation_id.get() { - return; - } - let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); - // Step 2 - thread::sleep(Duration::from_millis(event_source.reconnection_time.get())); - // TODO Step 3: Optionally wait some more - // Step 4 - if self.gen_id != self.event_source.root().generation_id.get() { - return; - } - let _ = receiver.recv(); - // Step 5 - let runnable = box RefetchRequestRunnable { - event_source: self.event_source.clone(), - gen_id: self.gen_id, - - event_type: self.event_type.clone(), - data: self.data.clone(), - last_event_id: self.last_event_id.clone(), - }; - if self.gen_id != self.event_source.root().generation_id.get() { - return; - } let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global()); } @@ -317,7 +298,7 @@ impl FetchResponseListener for EventSourceContext { } fn process_response_eof(&mut self, _response: Result<(), NetworkError>) { - + self.reestablish_the_connection(); } } @@ -394,9 +375,12 @@ impl EventSource { // Step 12 *ev.request.borrow_mut() = Some(request.clone()); // Step 14 + let (action_sender, action_receiver) = ipc::channel().unwrap(); let context = EventSourceContext { event_source: Trusted::new(&ev), gen_id: ev.generation_id.get(), + action_sender: action_sender.clone(), + parser_state: ParserState::Eol, field: String::new(), value: String::new(), @@ -411,7 +395,6 @@ impl EventSource { 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()); }); @@ -490,7 +473,7 @@ impl Runnable for FailConnectionRunnable { pub struct ReestablishConnectionRunnable { event_source: Trusted, - done_chan: Sender<()> + action_sender: ipc::IpcSender, } impl Runnable for ReestablishConnectionRunnable { @@ -501,31 +484,35 @@ impl Runnable for 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::().fire_event(atom!("error")); - self.done_chan.send(()).unwrap(); + // Step 2 + let duration = Length::new(event_source.reconnection_time.get()); + // TODO Step 3: Optionally wait some more + // Steps 4-5 + let callback = OneshotTimerCallback::EventSourceTimeout(EventSourceTimeoutCallback { + event_source: self.event_source.clone(), + action_sender: self.action_sender.clone() + }); + let _ = event_source.global().schedule_callback(callback, duration); } } -pub struct RefetchRequestRunnable { +#[derive(JSTraceable, HeapSizeOf)] +pub struct EventSourceTimeoutCallback { + #[ignore_heap_size_of = "Because it is non-owning"] event_source: Trusted, - gen_id: GenerationId, - - event_type: String, - data: String, - last_event_id: String, + #[ignore_heap_size_of = "Because it is non-owning"] + action_sender: ipc::IpcSender, } -impl Runnable for RefetchRequestRunnable { - fn name(&self) -> &'static str { "EventSource RefetchRequestRunnable" } - +impl EventSourceTimeoutCallback { // https://html.spec.whatwg.org/multipage/#reestablish-the-connection - fn handler(self: Box) { + pub fn invoke(self) { let event_source = self.event_source.root(); let global = event_source.global(); // Step 5.1 @@ -539,28 +526,7 @@ impl Runnable for RefetchRequestRunnable { request.headers.set(LastEventId(String::from(event_source.last_event_id.borrow().clone()))); } // Step 5.4 - let context = EventSourceContext { - event_source: self.event_source.clone(), - gen_id: self.gen_id, - parser_state: ParserState::Eol, - field: String::new(), - value: String::new(), - origin: String::new(), - - event_type: self.event_type.clone(), - data: self.data.clone(), - last_event_id: self.last_event_id.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(); + global.core_resource_thread().send(CoreResourceMsg::Fetch(request, self.action_sender)).unwrap(); } } diff --git a/components/script/timers.rs b/components/script/timers.rs index 34ac02b6589..6b67d6959e3 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -7,6 +7,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::FunctionBinding::Function; use dom::bindings::reflector::Reflectable; use dom::bindings::str::DOMString; +use dom::eventsource::EventSourceTimeoutCallback; use dom::globalscope::GlobalScope; use dom::testbinding::TestBindingCallback; use dom::xmlhttprequest::XHRTimeoutCallback; @@ -67,6 +68,7 @@ struct OneshotTimer { #[derive(JSTraceable, HeapSizeOf)] pub enum OneshotTimerCallback { XhrTimeout(XHRTimeoutCallback), + EventSourceTimeout(EventSourceTimeoutCallback), JsTimer(JsTimerTask), TestBindingCallback(TestBindingCallback), } @@ -75,6 +77,7 @@ impl OneshotTimerCallback { fn invoke(self, this: &T, js_timers: &JsTimers) { match self { OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(), + OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(), OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers), OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(), } From a39d1fa7d1b6119f4d86c11cc42728ce22bf1060 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 6 Nov 2016 10:59:06 -0800 Subject: [PATCH 9/9] Update WPT expectations --- .../eventsource-close.htm.ini | 5 -- ...source-constructor-non-same-origin.htm.ini | 3 - .../eventsource-constructor-url-bogus.htm.ini | 5 -- .../eventsource-eventtarget.worker.js.ini | 6 -- .../eventsource-onmesage.htm.ini | 5 -- .../eventsource-onopen.htm.ini | 5 -- .../eventsource-prototype.htm.ini | 5 -- .../dedicated-worker/eventsource-url.htm.ini | 5 -- .../metadata/eventsource/event-data.html.ini | 5 -- .../eventsource/eventsource-close.htm.ini | 3 - ...source-constructor-document-domain.htm.ini | 5 -- ...source-constructor-non-same-origin.htm.ini | 3 - .../eventsource-constructor-stringify.htm.ini | 14 ---- .../eventsource-constructor-url-bogus.htm.ini | 5 -- .../eventsource-cross-origin.htm.ini | 7 +- .../eventsource-eventtarget.htm.ini | 5 -- .../eventsource/eventsource-onmessage.htm.ini | 5 -- .../eventsource/eventsource-onopen.htm.ini | 5 -- .../eventsource/eventsource-prototype.htm.ini | 5 -- .../eventsource/eventsource-reconnect.htm.ini | 8 -- .../eventsource/eventsource-url.htm.ini | 5 -- .../metadata/eventsource/format-bom-2.htm.ini | 5 -- .../eventsource/format-comments.htm.ini | 5 -- .../eventsource/format-field-data.htm.ini | 5 -- .../format-field-event-empty.htm.ini | 5 -- .../eventsource/format-field-event.htm.ini | 5 -- .../eventsource/format-field-id-2.htm.ini | 5 -- .../eventsource/format-field-id.htm.ini | 5 -- .../eventsource/format-field-parsing.htm.ini | 5 -- .../format-field-retry-bogus.htm.ini | 5 -- .../format-field-retry-empty.htm.ini | 5 -- .../eventsource/format-field-retry.htm.ini | 5 -- .../eventsource/format-field-unknown.htm.ini | 5 -- .../eventsource/format-leading-space.htm.ini | 5 -- .../eventsource/format-mime-bogus.htm.ini | 5 -- .../format-mime-trailing-semicolon.htm.ini | 5 -- .../format-mime-valid-bogus.htm.ini | 5 -- .../eventsource/format-newlines.htm.ini | 5 -- .../format-null-character.html.ini | 5 -- .../metadata/eventsource/format-utf-8.htm.ini | 5 -- .../metadata/eventsource/interfaces.html.ini | 82 ------------------- .../eventsource/request-accept.htm.ini | 5 -- .../eventsource/request-cache-control.htm.ini | 6 +- .../eventsource/request-credentials.htm.ini | 7 +- .../eventsource/request-redirect.htm.ini | 14 ---- .../wpt/metadata/html/dom/interfaces.html.ini | 55 ------------- .../expected-self-properties.worker.js.ini | 4 - .../interface-objects/001.worker.js.ini | 4 - .../wpt/mozilla/tests/mozilla/interfaces.html | 1 + .../tests/mozilla/interfaces.worker.js | 1 + 50 files changed, 13 insertions(+), 375 deletions(-) delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-close.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-eventtarget.worker.js.ini delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onmesage.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onopen.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-prototype.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/dedicated-worker/eventsource-url.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/event-data.html.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-constructor-document-domain.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-constructor-stringify.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-constructor-url-bogus.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-eventtarget.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-onmessage.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-onopen.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-prototype.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-reconnect.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/eventsource-url.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-bom-2.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-comments.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-data.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-event-empty.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-event.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-id-2.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-id.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-parsing.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-retry-bogus.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-retry-empty.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-retry.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-field-unknown.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-leading-space.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-mime-bogus.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-mime-valid-bogus.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-newlines.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/format-null-character.html.ini delete mode 100644 tests/wpt/metadata/eventsource/format-utf-8.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/request-accept.htm.ini delete mode 100644 tests/wpt/metadata/eventsource/request-redirect.htm.ini diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-close.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-close.htm.ini deleted file mode 100644 index 64aa4dc6950..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-close.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-close.htm] - type: testharness - [dedicated worker - EventSource: close()] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm.ini index f139e30e4ef..e8f2fed80bc 100644 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm.ini +++ b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm.ini @@ -9,9 +9,6 @@ [dedicated worker - EventSource: constructor (act as if there is a network error) (ftp://example.not/)] expected: FAIL - [dedicated worker - EventSource: constructor (act as if there is a network error) (about:blank)] - expected: FAIL - [dedicated worker - EventSource: constructor (act as if there is a network error) (mailto:whatwg@awesome.example)] expected: FAIL diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm.ini deleted file mode 100644 index a49013bbcd9..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-constructor-url-bogus.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-constructor-url-bogus.htm] - type: testharness - [dedicated worker - EventSource: constructor (invalid URL)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-eventtarget.worker.js.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-eventtarget.worker.js.ini deleted file mode 100644 index 113257a0aa4..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-eventtarget.worker.js.ini +++ /dev/null @@ -1,6 +0,0 @@ -[eventsource-eventtarget.worker] - type: testharness - bug: https://github.com/servo/servo/issues/8925 - [dedicated worker - EventSource: addEventListener()] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onmesage.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onmesage.htm.ini deleted file mode 100644 index f5091818eb8..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onmesage.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-onmesage.htm] - type: testharness - [dedicated worker - EventSource: onmessage] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onopen.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onopen.htm.ini deleted file mode 100644 index 46763f8958c..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-onopen.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-onopen.htm] - type: testharness - [dedicated worker - EventSource: onopen (announcing the connection)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-prototype.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-prototype.htm.ini deleted file mode 100644 index f7a425c7190..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-prototype.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-prototype.htm] - type: testharness - [dedicated worker - EventSource: prototype et al] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-url.htm.ini b/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-url.htm.ini deleted file mode 100644 index 4130add5218..00000000000 --- a/tests/wpt/metadata/eventsource/dedicated-worker/eventsource-url.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-url.htm] - type: testharness - [dedicated worker - EventSource: url] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/event-data.html.ini b/tests/wpt/metadata/eventsource/event-data.html.ini deleted file mode 100644 index 14e880be7c4..00000000000 --- a/tests/wpt/metadata/eventsource/event-data.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[event-data.html] - type: testharness - [EventSource: lines and data parsing] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-close.htm.ini b/tests/wpt/metadata/eventsource/eventsource-close.htm.ini index a892a4d6a63..d251fd965ce 100644 --- a/tests/wpt/metadata/eventsource/eventsource-close.htm.ini +++ b/tests/wpt/metadata/eventsource/eventsource-close.htm.ini @@ -1,8 +1,5 @@ [eventsource-close.htm] type: testharness - [EventSource: close()] - expected: FAIL - [EventSource: close(), test events] expected: FAIL diff --git a/tests/wpt/metadata/eventsource/eventsource-constructor-document-domain.htm.ini b/tests/wpt/metadata/eventsource/eventsource-constructor-document-domain.htm.ini deleted file mode 100644 index f8a7cc98e65..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-constructor-document-domain.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-constructor-document-domain.htm] - type: testharness - [EventSource: document.domain] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-constructor-non-same-origin.htm.ini b/tests/wpt/metadata/eventsource/eventsource-constructor-non-same-origin.htm.ini index e6876748057..49f71f310f2 100644 --- a/tests/wpt/metadata/eventsource/eventsource-constructor-non-same-origin.htm.ini +++ b/tests/wpt/metadata/eventsource/eventsource-constructor-non-same-origin.htm.ini @@ -9,9 +9,6 @@ [EventSource: constructor (act as if there is a network error) (ftp://example.not/)] expected: FAIL - [EventSource: constructor (act as if there is a network error) (about:blank)] - expected: FAIL - [EventSource: constructor (act as if there is a network error) (mailto:whatwg@awesome.example)] expected: FAIL diff --git a/tests/wpt/metadata/eventsource/eventsource-constructor-stringify.htm.ini b/tests/wpt/metadata/eventsource/eventsource-constructor-stringify.htm.ini deleted file mode 100644 index a7dcaf15440..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-constructor-stringify.htm.ini +++ /dev/null @@ -1,14 +0,0 @@ -[eventsource-constructor-stringify.htm] - type: testharness - [EventSource: stringify argument, object] - expected: FAIL - - [EventSource: stringify argument, 1] - expected: FAIL - - [EventSource: stringify argument, null] - expected: FAIL - - [EventSource: stringify argument, undefined] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-constructor-url-bogus.htm.ini b/tests/wpt/metadata/eventsource/eventsource-constructor-url-bogus.htm.ini deleted file mode 100644 index 2ac31a6aca1..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-constructor-url-bogus.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-constructor-url-bogus.htm] - type: testharness - [EventSource: constructor (invalid URL)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-cross-origin.htm.ini b/tests/wpt/metadata/eventsource/eventsource-cross-origin.htm.ini index e15e785a561..b8818892048 100644 --- a/tests/wpt/metadata/eventsource/eventsource-cross-origin.htm.ini +++ b/tests/wpt/metadata/eventsource/eventsource-cross-origin.htm.ini @@ -1,13 +1,14 @@ [eventsource-cross-origin.htm] type: testharness + expected: TIMEOUT [EventSource: cross-origin basic use] - expected: FAIL + expected: TIMEOUT [EventSource: cross-origin redirect use] - expected: FAIL + expected: TIMEOUT [EventSource: cross-origin redirect use recon] - expected: FAIL + expected: TIMEOUT [EventSource: cross-origin allow-origin: http://example.org should fail] expected: FAIL diff --git a/tests/wpt/metadata/eventsource/eventsource-eventtarget.htm.ini b/tests/wpt/metadata/eventsource/eventsource-eventtarget.htm.ini deleted file mode 100644 index c5525b8a537..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-eventtarget.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-eventtarget.htm] - type: testharness - [EventSource: addEventListener()] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-onmessage.htm.ini b/tests/wpt/metadata/eventsource/eventsource-onmessage.htm.ini deleted file mode 100644 index 415bd7c471b..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-onmessage.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-onmessage.htm] - type: testharness - [EventSource: onmessage] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-onopen.htm.ini b/tests/wpt/metadata/eventsource/eventsource-onopen.htm.ini deleted file mode 100644 index f67e21e13e2..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-onopen.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-onopen.htm] - type: testharness - [EventSource: onopen (announcing the connection)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-prototype.htm.ini b/tests/wpt/metadata/eventsource/eventsource-prototype.htm.ini deleted file mode 100644 index dca324d5e66..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-prototype.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-prototype.htm] - type: testharness - [EventSource: prototype et al] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-reconnect.htm.ini b/tests/wpt/metadata/eventsource/eventsource-reconnect.htm.ini deleted file mode 100644 index d82a99aa477..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-reconnect.htm.ini +++ /dev/null @@ -1,8 +0,0 @@ -[eventsource-reconnect.htm] - type: testharness - [EventSource: reconnection 200] - expected: FAIL - - [EventSource: reconnection, test reconnection events] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/eventsource-url.htm.ini b/tests/wpt/metadata/eventsource/eventsource-url.htm.ini deleted file mode 100644 index 1a36f3fab88..00000000000 --- a/tests/wpt/metadata/eventsource/eventsource-url.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-url.htm] - type: testharness - [EventSource: url] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-bom-2.htm.ini b/tests/wpt/metadata/eventsource/format-bom-2.htm.ini deleted file mode 100644 index cf286d7ddf9..00000000000 --- a/tests/wpt/metadata/eventsource/format-bom-2.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-bom-2.htm] - type: testharness - [EventSource: Double BOM] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-comments.htm.ini b/tests/wpt/metadata/eventsource/format-comments.htm.ini deleted file mode 100644 index 94715a0059a..00000000000 --- a/tests/wpt/metadata/eventsource/format-comments.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-comments.htm] - type: testharness - [EventSource: comment fest] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-data.htm.ini b/tests/wpt/metadata/eventsource/format-field-data.htm.ini deleted file mode 100644 index c06b343a528..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-data.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-data.htm] - type: testharness - [EventSource: data field parsing] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-event-empty.htm.ini b/tests/wpt/metadata/eventsource/format-field-event-empty.htm.ini deleted file mode 100644 index 52f3322218f..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-event-empty.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-event-empty.htm] - type: testharness - [EventSource: empty "event" field] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-event.htm.ini b/tests/wpt/metadata/eventsource/format-field-event.htm.ini deleted file mode 100644 index a04bef8c5d2..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-event.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-event.htm] - type: testharness - [EventSource: custom event name] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-id-2.htm.ini b/tests/wpt/metadata/eventsource/format-field-id-2.htm.ini deleted file mode 100644 index db7df35dd1b..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-id-2.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-id-2.htm] - type: testharness - [EventSource: Last-Event-ID (2)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-id.htm.ini b/tests/wpt/metadata/eventsource/format-field-id.htm.ini deleted file mode 100644 index 7574f06467e..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-id.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-id.htm] - type: testharness - [EventSource: Last-Event-ID] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-parsing.htm.ini b/tests/wpt/metadata/eventsource/format-field-parsing.htm.ini deleted file mode 100644 index 0138a4e364c..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-parsing.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-parsing.htm] - type: testharness - [EventSource: field parsing] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-retry-bogus.htm.ini b/tests/wpt/metadata/eventsource/format-field-retry-bogus.htm.ini deleted file mode 100644 index d48cb5f75b5..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-retry-bogus.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-retry-bogus.htm] - type: testharness - [EventSource: "retry" field (bogus)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-retry-empty.htm.ini b/tests/wpt/metadata/eventsource/format-field-retry-empty.htm.ini deleted file mode 100644 index 6490cd21548..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-retry-empty.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-retry-empty.htm] - type: testharness - [EventSource: empty retry field] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-retry.htm.ini b/tests/wpt/metadata/eventsource/format-field-retry.htm.ini deleted file mode 100644 index e2171f00af2..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-retry.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-retry.htm] - type: testharness - [EventSource: "retry" field] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-field-unknown.htm.ini b/tests/wpt/metadata/eventsource/format-field-unknown.htm.ini deleted file mode 100644 index 8f5d446ea7f..00000000000 --- a/tests/wpt/metadata/eventsource/format-field-unknown.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-field-unknown.htm] - type: testharness - [EventSource: unknown fields and parsing fun] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-leading-space.htm.ini b/tests/wpt/metadata/eventsource/format-leading-space.htm.ini deleted file mode 100644 index 2bd98e1ff1c..00000000000 --- a/tests/wpt/metadata/eventsource/format-leading-space.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-leading-space.htm] - type: testharness - [EventSource: leading space] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-mime-bogus.htm.ini b/tests/wpt/metadata/eventsource/format-mime-bogus.htm.ini deleted file mode 100644 index c0258901cef..00000000000 --- a/tests/wpt/metadata/eventsource/format-mime-bogus.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-mime-bogus.htm] - type: testharness - [EventSource: bogus MIME type] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini b/tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini deleted file mode 100644 index b8151056ac1..00000000000 --- a/tests/wpt/metadata/eventsource/format-mime-trailing-semicolon.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-mime-trailing-semicolon.htm] - type: testharness - [EventSource: MIME type with trailing ;] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-mime-valid-bogus.htm.ini b/tests/wpt/metadata/eventsource/format-mime-valid-bogus.htm.ini deleted file mode 100644 index 4603c171651..00000000000 --- a/tests/wpt/metadata/eventsource/format-mime-valid-bogus.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-mime-valid-bogus.htm] - type: testharness - [EventSource: incorrect valid MIME type] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-newlines.htm.ini b/tests/wpt/metadata/eventsource/format-newlines.htm.ini deleted file mode 100644 index 64aaa33572b..00000000000 --- a/tests/wpt/metadata/eventsource/format-newlines.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-newlines.htm] - type: testharness - [EventSource: newline fest] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-null-character.html.ini b/tests/wpt/metadata/eventsource/format-null-character.html.ini deleted file mode 100644 index 29a30bdef83..00000000000 --- a/tests/wpt/metadata/eventsource/format-null-character.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-null-character.html] - type: testharness - [EventSource: null character in response] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/format-utf-8.htm.ini b/tests/wpt/metadata/eventsource/format-utf-8.htm.ini deleted file mode 100644 index 1c8cfeafb5b..00000000000 --- a/tests/wpt/metadata/eventsource/format-utf-8.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[format-utf-8.htm] - type: testharness - [EventSource: always UTF-8] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/interfaces.html.ini b/tests/wpt/metadata/eventsource/interfaces.html.ini index aeece3e4173..99706ee7d67 100644 --- a/tests/wpt/metadata/eventsource/interfaces.html.ini +++ b/tests/wpt/metadata/eventsource/interfaces.html.ini @@ -8,85 +8,3 @@ [Stringification of new EventSource("http://foo")] expected: FAIL - - [EventSource interface object length] - expected: FAIL - - [EventSource interface object name] - expected: FAIL - - [EventSource interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [EventSource interface: attribute url] - expected: FAIL - - [EventSource interface: attribute withCredentials] - expected: FAIL - - [EventSource interface: constant CONNECTING on interface object] - expected: FAIL - - [EventSource interface: constant CONNECTING on interface prototype object] - expected: FAIL - - [EventSource interface: constant OPEN on interface object] - expected: FAIL - - [EventSource interface: constant OPEN on interface prototype object] - expected: FAIL - - [EventSource interface: constant CLOSED on interface object] - expected: FAIL - - [EventSource interface: constant CLOSED on interface prototype object] - expected: FAIL - - [EventSource interface: attribute readyState] - expected: FAIL - - [EventSource interface: attribute onopen] - expected: FAIL - - [EventSource interface: attribute onmessage] - expected: FAIL - - [EventSource interface: attribute onerror] - expected: FAIL - - [EventSource interface: operation close()] - expected: FAIL - - [EventSource must be primary interface of new EventSource("http://foo")] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "url" with the proper type (0)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "withCredentials" with the proper type (1)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "CONNECTING" with the proper type (2)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "OPEN" with the proper type (3)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "CLOSED" with the proper type (4)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "readyState" with the proper type (5)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "onopen" with the proper type (6)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "onmessage" with the proper type (7)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "onerror" with the proper type (8)] - expected: FAIL - - [EventSource interface: new EventSource("http://foo") must inherit property "close" with the proper type (9)] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/request-accept.htm.ini b/tests/wpt/metadata/eventsource/request-accept.htm.ini deleted file mode 100644 index 41f665968d8..00000000000 --- a/tests/wpt/metadata/eventsource/request-accept.htm.ini +++ /dev/null @@ -1,5 +0,0 @@ -[request-accept.htm] - type: testharness - [EventSource: Accept header] - expected: FAIL - diff --git a/tests/wpt/metadata/eventsource/request-cache-control.htm.ini b/tests/wpt/metadata/eventsource/request-cache-control.htm.ini index 08c14fe743a..9d7703c7521 100644 --- a/tests/wpt/metadata/eventsource/request-cache-control.htm.ini +++ b/tests/wpt/metadata/eventsource/request-cache-control.htm.ini @@ -1,8 +1,8 @@ [request-cache-control.htm] type: testharness + expected: TIMEOUT [EventSource: Cache-Control] - expected: FAIL + expected: TIMEOUT [EventSource: Cache-Control 1] - expected: FAIL - + expected: TIMEOUT diff --git a/tests/wpt/metadata/eventsource/request-credentials.htm.ini b/tests/wpt/metadata/eventsource/request-credentials.htm.ini index 138c988e338..1ca9f95ac12 100644 --- a/tests/wpt/metadata/eventsource/request-credentials.htm.ini +++ b/tests/wpt/metadata/eventsource/request-credentials.htm.ini @@ -1,11 +1,12 @@ [request-credentials.htm] type: testharness + expected: TIMEOUT [EventSource: credentials: credentials enabled] - expected: FAIL + expected: TIMEOUT [EventSource: credentials: credentials disabled] - expected: FAIL + expected: TIMEOUT [EventSource: credentials: credentials default] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/metadata/eventsource/request-redirect.htm.ini b/tests/wpt/metadata/eventsource/request-redirect.htm.ini deleted file mode 100644 index a86159c2b92..00000000000 --- a/tests/wpt/metadata/eventsource/request-redirect.htm.ini +++ /dev/null @@ -1,14 +0,0 @@ -[request-redirect.htm] - type: testharness - [EventSource: redirect (301)] - expected: FAIL - - [EventSource: redirect (302)] - expected: FAIL - - [EventSource: redirect (303)] - expected: FAIL - - [EventSource: redirect (307)] - expected: FAIL - diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index c2fd0d37c5c..151d88e473a 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -10577,58 +10577,3 @@ [Navigator interface: window.navigator must inherit property "hardwareConcurrency" with the proper type (22)] expected: FAIL - - [EventSource interface: existence and properties of interface object] - expected: FAIL - - [EventSource interface object length] - expected: FAIL - - [EventSource interface object name] - expected: FAIL - - [EventSource interface: existence and properties of interface prototype object] - expected: FAIL - - [EventSource interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [EventSource interface: attribute url] - expected: FAIL - - [EventSource interface: attribute withCredentials] - expected: FAIL - - [EventSource interface: constant CONNECTING on interface object] - expected: FAIL - - [EventSource interface: constant CONNECTING on interface prototype object] - expected: FAIL - - [EventSource interface: constant OPEN on interface object] - expected: FAIL - - [EventSource interface: constant OPEN on interface prototype object] - expected: FAIL - - [EventSource interface: constant CLOSED on interface object] - expected: FAIL - - [EventSource interface: constant CLOSED on interface prototype object] - expected: FAIL - - [EventSource interface: attribute readyState] - expected: FAIL - - [EventSource interface: attribute onopen] - expected: FAIL - - [EventSource interface: attribute onmessage] - expected: FAIL - - [EventSource interface: attribute onerror] - expected: FAIL - - [EventSource interface: operation close()] - expected: FAIL - diff --git a/tests/wpt/metadata/workers/constructors/Worker/expected-self-properties.worker.js.ini b/tests/wpt/metadata/workers/constructors/Worker/expected-self-properties.worker.js.ini index f7c5702bba0..1e27dc99102 100644 --- a/tests/wpt/metadata/workers/constructors/Worker/expected-self-properties.worker.js.ini +++ b/tests/wpt/metadata/workers/constructors/Worker/expected-self-properties.worker.js.ini @@ -5,7 +5,3 @@ [existence of SharedWorker] expected: FAIL - - [existence of EventSource] - expected: FAIL - diff --git a/tests/wpt/metadata/workers/semantics/interface-objects/001.worker.js.ini b/tests/wpt/metadata/workers/semantics/interface-objects/001.worker.js.ini index 2c7740b23a8..60807857f7a 100644 --- a/tests/wpt/metadata/workers/semantics/interface-objects/001.worker.js.ini +++ b/tests/wpt/metadata/workers/semantics/interface-objects/001.worker.js.ini @@ -80,7 +80,3 @@ [The IDBTransaction interface object should be exposed.] expected: FAIL - - [The EventSource interface object should be exposed.] - expected: FAIL - diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index 65dc554e274..51c0b2cae63 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -41,6 +41,7 @@ test_interfaces([ "Element", "ErrorEvent", "Event", + "EventSource", "EventTarget", "File", "FileList", diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js index 9751b273d96..bc46462be50 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js @@ -22,6 +22,7 @@ test_interfaces([ "DOMException", "ErrorEvent", "Event", + "EventSource", "EventTarget", "File", "FileList",