diff options
author | Keith Yeung <kungfukeith11@gmail.com> | 2016-10-04 22:25:30 -0700 |
---|---|---|
committer | Keith Yeung <kungfukeith11@gmail.com> | 2016-11-11 14:50:37 -0800 |
commit | d99d26cf1fc3cc2199cc8d84817c0b505e9634d2 (patch) | |
tree | cbab515c876695fc5ef9069cbc8bce8808c730c0 | |
parent | 75d35241db63894db31b6385143ffea0db5cac70 (diff) | |
download | servo-d99d26cf1fc3cc2199cc8d84817c0b505e9634d2.tar.gz servo-d99d26cf1fc3cc2199cc8d84817c0b505e9634d2.zip |
Implement the constructor for EventSource
-rw-r--r-- | components/net_traits/request.rs | 9 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 3 | ||||
-rw-r--r-- | components/script/dom/eventsource.rs | 113 | ||||
-rw-r--r-- | 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<Vec<u8>>, @@ -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<Option<Url>>, + request: DOMRefCell<Option<RequestInit>>, ready_state: Cell<EventSourceReadyState>, with_credentials: bool, last_event_id: DOMRefCell<DOMString> } +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<FetchMetadata, NetworkError>) { + // TODO + } + + fn process_response_chunk(&mut self, mut _chunk: Vec<u8>) { + // 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<EventSource> { - reflect_dom_object(box EventSource::new_inherited(url, with_credentials), + fn new(global: &GlobalScope, with_credentials: bool) -> Root<EventSource> { + 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<Root<EventSource>> { - // 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<Promise> { +pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: &RequestInit) -> Rc<Promise> { let core_resource_thread = global.core_resource_thread(); // Step 1 |