diff options
-rw-r--r-- | components/net/fetch/methods.rs | 7 | ||||
-rw-r--r-- | components/net_traits/lib.rs | 19 | ||||
-rw-r--r-- | components/net_traits/response.rs | 48 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 10 | ||||
-rw-r--r-- | components/script/dom/xmlhttprequest.rs | 20 |
5 files changed, 75 insertions, 29 deletions
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index dd35ce06656..23fb67ce82b 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -22,7 +22,7 @@ use hyper::status::StatusCode; use hyper_serde::Serde; use mime_guess::guess_mime_type; use msg::constellation_msg::ReferrerPolicy; -use net_traits::FetchTaskTarget; +use net_traits::{FetchTaskTarget, FetchMetadata}; use net_traits::request::{CacheMode, CredentialsMode, Destination}; use net_traits::request::{RedirectMode, Referrer, Request, RequestMode, ResponseTainting}; use net_traits::request::{Type, Origin, Window}; @@ -981,7 +981,10 @@ fn http_network_fetch(request: Rc<Request>, // We're about to spawn a thread to be waited on here *done_chan = Some(channel()); - let meta = response.metadata().expect("Response metadata should exist at this stage"); + let meta = match response.metadata().expect("Response metadata should exist at this stage") { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { unsafe_, .. } => unsafe_ + }; let done_sender = done_chan.as_ref().map(|ch| ch.0.clone()); let devtools_sender = devtools_chan.clone(); let meta_status = meta.status.clone(); diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index bd3436d9f00..2cbc198e0f7 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -170,7 +170,7 @@ pub enum FetchResponseMsg { ProcessRequestBody, ProcessRequestEOF, // todo: send more info about the response (or perhaps the entire Response) - ProcessResponse(Result<Metadata, NetworkError>), + ProcessResponse(Result<FetchMetadata, NetworkError>), ProcessResponseChunk(Vec<u8>), ProcessResponseEOF(Result<(), NetworkError>), } @@ -200,10 +200,25 @@ pub trait FetchTaskTarget { fn process_response_eof(&mut self, response: &Response); } +#[derive(Serialize, Deserialize)] +pub enum FilteredMetadata { + Opaque, + Transparent(Metadata) +} + +#[derive(Serialize, Deserialize)] +pub enum FetchMetadata { + Unfiltered(Metadata), + Filtered { + filtered: FilteredMetadata, + unsafe_: Metadata + } +} + pub trait FetchResponseListener { fn process_request_body(&mut self); fn process_request_eof(&mut self); - fn process_response(&mut self, metadata: Result<Metadata, NetworkError>); + fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>); fn process_response_chunk(&mut self, chunk: Vec<u8>); fn process_response_eof(&mut self, response: Result<(), NetworkError>); } diff --git a/components/net_traits/response.rs b/components/net_traits/response.rs index 823c56c7002..c4b4a3fe8e3 100644 --- a/components/net_traits/response.rs +++ b/components/net_traits/response.rs @@ -4,7 +4,7 @@ //! The [Response](https://fetch.spec.whatwg.org/#responses) object //! resulting from a [fetch operation](https://fetch.spec.whatwg.org/#concept-fetch) -use {Metadata, NetworkError}; +use {FetchMetadata, FilteredMetadata, Metadata, NetworkError}; use hyper::header::{AccessControlExposeHeaders, ContentType, Headers}; use hyper::status::StatusCode; use hyper_serde::Serde; @@ -225,24 +225,42 @@ impl Response { response } - pub fn metadata(&self) -> Result<Metadata, NetworkError> { - let mut metadata = if let Some(ref url) = self.url { - Metadata::default(url.clone()) - } else { - return Err(NetworkError::Internal("No url found in response".to_string())); + pub fn metadata(&self) -> Result<FetchMetadata, NetworkError> { + fn init_metadata(response: &Response, url: &Url) -> Metadata { + let mut metadata = Metadata::default(url.clone()); + metadata.set_content_type(match response.headers.get() { + Some(&ContentType(ref mime)) => Some(mime), + None => None + }); + metadata.headers = Some(Serde(response.headers.clone())); + metadata.status = response.raw_status.clone(); + metadata.https_state = response.https_state; + metadata }; if self.is_network_error() { - return Err(NetworkError::Internal("Cannot extract metadata from network error".to_string())); + return Err(NetworkError::Internal("Cannot extract metadata from network error".to_owned())); } - metadata.set_content_type(match self.headers.get() { - Some(&ContentType(ref mime)) => Some(mime), - None => None - }); - metadata.headers = Some(Serde(self.headers.clone())); - metadata.status = self.raw_status.clone(); - metadata.https_state = self.https_state; - return Ok(metadata); + let metadata = self.url.as_ref().map(|url| init_metadata(self, url)); + + if let Some(ref response) = self.internal_response { + match response.url { + Some(ref url) => { + let unsafe_metadata = init_metadata(response, url); + + Ok(FetchMetadata::Filtered { + filtered: match metadata { + Some(m) => FilteredMetadata::Transparent(m), + None => FilteredMetadata::Opaque + }, + unsafe_: unsafe_metadata + }) + } + None => Err(NetworkError::Internal("No url found in unsafe response".to_owned())) + } + } else { + Ok(FetchMetadata::Unfiltered(metadata.unwrap())) + } } } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index ea44dd81336..566b69967d4 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -31,7 +31,7 @@ use html5ever::tree_builder::NextParserState; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use js::jsval::UndefinedValue; -use net_traits::{FetchResponseListener, Metadata, NetworkError}; +use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError}; use net_traits::request::{CORSSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use std::ascii::AsciiExt; @@ -159,8 +159,12 @@ impl FetchResponseListener for ScriptContext { 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(); + fn process_response(&mut self, + metadata: Result<FetchMetadata, NetworkError>) { + self.metadata = metadata.ok().map(|meta| match meta { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { unsafe_, .. } => unsafe_ + }); let status_code = self.metadata.as_ref().and_then(|m| { match m.status { diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 66338dd9ef1..24ee2c28d36 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -45,8 +45,8 @@ use js::jsapi::{JSContext, JS_ParseJSON}; use js::jsapi::JS_ClearPendingException; use js::jsval::{JSVal, NullValue, UndefinedValue}; use msg::constellation_msg::{PipelineId, ReferrerPolicy}; -use net_traits::{CoreResourceThread, LoadOrigin}; -use net_traits::{FetchResponseListener, Metadata, NetworkError}; +use net_traits::{CoreResourceThread, FetchMetadata, FilteredMetadata}; +use net_traits::{FetchResponseListener, LoadOrigin, NetworkError}; use net_traits::CoreResourceMsg::Fetch; use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode}; use net_traits::trim_http_whitespace; @@ -227,10 +227,10 @@ impl XMLHttpRequest { // todo } - fn process_response(&mut self, metadata: Result<Metadata, NetworkError>) { + fn process_response(&mut self, + metadata: Result<FetchMetadata, NetworkError>) { let xhr = self.xhr.root(); - let rv = xhr.process_headers_available(self.gen_id, - metadata); + let rv = xhr.process_headers_available(self.gen_id, metadata); if rv.is_err() { *self.sync_status.borrow_mut() = Some(rv); } @@ -869,10 +869,16 @@ impl XMLHttpRequest { } fn process_headers_available(&self, - gen_id: GenerationId, metadata: Result<Metadata, NetworkError>) + gen_id: GenerationId, metadata: Result<FetchMetadata, NetworkError>) -> Result<(), Error> { let metadata = match metadata { - Ok(meta) => meta, + Ok(meta) => match meta { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { filtered, .. } => match filtered { + FilteredMetadata::Opaque => return Err(Error::Network), + FilteredMetadata::Transparent(m) => m + } + }, Err(_) => { self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network)); return Err(Error::Network); |