aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2016-10-04 22:25:30 -0700
committerKeith Yeung <kungfukeith11@gmail.com>2016-11-11 14:50:37 -0800
commitd99d26cf1fc3cc2199cc8d84817c0b505e9634d2 (patch)
treecbab515c876695fc5ef9069cbc8bce8808c730c0
parent75d35241db63894db31b6385143ffea0db5cac70 (diff)
downloadservo-d99d26cf1fc3cc2199cc8d84817c0b505e9634d2.tar.gz
servo-d99d26cf1fc3cc2199cc8d84817c0b505e9634d2.zip
Implement the constructor for EventSource
-rw-r--r--components/net_traits/request.rs9
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/eventsource.rs113
-rw-r--r--components/script/fetch.rs5
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