diff options
author | Keith Yeung <kungfukeith11@gmail.com> | 2016-07-03 21:24:53 +0800 |
---|---|---|
committer | Keith Yeung <kungfukeith11@gmail.com> | 2016-09-21 11:50:55 -0700 |
commit | 4dcf693a751b0780a72a3e3058e12642a8082cfe (patch) | |
tree | 1a24b992521eb6eaf32d2a54bcd7ebe4585ed9c3 /components/script | |
parent | d4816762fa9db76d56014caa50243f40f481265b (diff) | |
download | servo-4dcf693a751b0780a72a3e3058e12642a8082cfe.tar.gz servo-4dcf693a751b0780a72a3e3058e12642a8082cfe.zip |
Use fetch infrastructure to load external scripts
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/document_loader.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 73 |
2 files changed, 56 insertions, 19 deletions
diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs index c38a234b2c1..5209b68b9ac 100644 --- a/components/script/document_loader.rs +++ b/components/script/document_loader.rs @@ -9,9 +9,9 @@ use dom::bindings::js::JS; use dom::document::Document; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{PipelineId, ReferrerPolicy}; -use net_traits::request::RequestInit; use net_traits::{AsyncResponseTarget, PendingAsyncLoad, LoadContext}; use net_traits::{FetchResponseMsg, ResourceThreads, IpcSend}; +use net_traits::request::RequestInit; use std::thread; use url::Url; diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index a583ddc2137..ea44dd81336 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -15,6 +15,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::js::RootedReference; use dom::bindings::refcounted::Trusted; +use dom::bindings::reflector::Reflectable; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element, ElementCreator}; @@ -30,8 +31,8 @@ use html5ever::tree_builder::NextParserState; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use js::jsval::UndefinedValue; -use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError}; -use net_traits::request::CORSSettings; +use net_traits::{FetchResponseListener, Metadata, NetworkError}; +use net_traits::request::{CORSSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use std::ascii::AsciiExt; use std::cell::Cell; @@ -153,8 +154,12 @@ struct ScriptContext { status: Result<(), NetworkError> } -impl AsyncResponseListener for ScriptContext { - fn headers_available(&mut self, metadata: Result<Metadata, NetworkError>) { +impl FetchResponseListener for ScriptContext { + fn process_request_body(&mut self) {} // TODO(KiChjang): Perhaps add custom steps to perform fetch here? + + fn process_request_eof(&mut self) {} // TODO(KiChjang): Perhaps add custom steps to perform fetch here? + + fn process_response(&mut self, metadata: Result<Metadata, NetworkError>) { self.metadata = metadata.ok(); let status_code = self.metadata.as_ref().and_then(|m| { @@ -171,18 +176,17 @@ impl AsyncResponseListener for ScriptContext { }; } - fn data_available(&mut self, payload: Vec<u8>) { + fn process_response_chunk(&mut self, mut chunk: Vec<u8>) { if self.status.is_ok() { - let mut payload = payload; - self.data.append(&mut payload); + self.data.append(&mut chunk); } } /// https://html.spec.whatwg.org/multipage/#fetch-a-classic-script /// step 4-9 - fn response_complete(&mut self, status: Result<(), NetworkError>) { + fn process_response_eof(&mut self, response: Result<(), NetworkError>) { // Step 5. - let load = status.and(self.status.clone()).map(|_| { + let load = response.and(self.status.clone()).map(|_| { let metadata = self.metadata.take().unwrap(); // Step 6. @@ -212,8 +216,38 @@ impl PreInvoke for ScriptContext {} /// https://html.spec.whatwg.org/multipage/#fetch-a-classic-script fn fetch_a_classic_script(script: &HTMLScriptElement, url: Url, + cors_setting: Option<CORSSettings>, character_encoding: EncodingRef) { - // TODO(#9186): use the fetch infrastructure. + let doc = document_from_node(script); + + // Step 1, 2. + let request = RequestInit { + url: url.clone(), + type_: RequestType::Script, + destination: Destination::Script, + // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request + // Step 1 + mode: match cors_setting { + Some(_) => RequestMode::CORSMode, + None => RequestMode::NoCORS, + }, + // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request + // Step 3-4 + credentials_mode: match cors_setting { + Some(CORSSettings::Anonymous) => CredentialsMode::CredentialsSameOrigin, + _ => CredentialsMode::Include, + }, + origin: doc.url().clone(), + pipeline_id: Some(script.global().r().pipeline_id()), + // FIXME: Set to true for now, discussion in https://github.com/whatwg/fetch/issues/381 + same_origin_data: true, + referrer_url: Some(doc.url().clone()), + referrer_policy: doc.get_referrer_policy(), + .. RequestInit::default() + }; + + // TODO: Step 3, Add custom steps to perform fetch + let context = Arc::new(Mutex::new(ScriptContext { elem: Trusted::new(script), character_encoding: character_encoding, @@ -231,14 +265,11 @@ fn fetch_a_classic_script(script: &HTMLScriptElement, script_chan: doc.window().networking_task_source(), wrapper: Some(doc.window().get_runnable_wrapper()), }; - let response_target = AsyncResponseTarget { - sender: action_sender, - }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify_action(message.to().unwrap()); + listener.notify_fetch(message.to().unwrap()); }); - - doc.load_async(LoadType::Script(url), response_target, None); + doc.fetch_async(LoadType::Script(url), request, action_sender, None); } impl HTMLScriptElement { @@ -324,7 +355,13 @@ impl HTMLScriptElement { .and_then(|charset| encoding_from_whatwg_label(&charset.value())) .unwrap_or_else(|| doc.encoding()); - // TODO: Step 14: CORS. + // Step 14. + let cors_setting = match self.GetCrossOrigin() { + Some(ref s) if *s == "anonymous" => Some(CORSSettings::Anonymous), + Some(ref s) if *s == "use-credentials" => Some(CORSSettings::UseCredentials), + None => None, + _ => unreachable!() + }; // TODO: Step 15: Nonce. @@ -356,7 +393,7 @@ impl HTMLScriptElement { }; // Step 18.6. - fetch_a_classic_script(self, url, encoding); + fetch_a_classic_script(self, url, cors_setting, encoding); true }, |