diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 0d5b2d2835e..952ec3a91e8 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -10,8 +10,8 @@ use fetch::cors_cache::CORSCache; use filemanager_thread::{FileManager, UIProvider}; use http_loader::{HttpState, set_default_accept_encoding, set_request_cookies}; use http_loader::{NetworkHttpRequestFactory, ReadResult, StreamedResponse, obtain_response, read_block}; -use http_loader::{auth_from_cache, determine_request_referrer}; -use http_loader::{send_response_to_devtools, send_request_to_devtools}; +use http_loader::{auth_from_cache, determine_request_referrer, set_cookies_from_headers}; +use http_loader::{send_response_to_devtools, send_request_to_devtools, LoadErrorType}; use hyper::header::{Accept, AcceptLanguage, Authorization, AccessControlAllowCredentials}; use hyper::header::{AccessControlAllowOrigin, AccessControlAllowHeaders, AccessControlAllowMethods}; use hyper::header::{AccessControlRequestHeaders, AccessControlMaxAge, AccessControlRequestMethod, Basic}; @@ -24,15 +24,15 @@ use hyper::status::StatusCode; use hyper_serde::Serde; use mime_guess::guess_mime_type; use msg::constellation_msg::ReferrerPolicy; -use net_traits::{FetchTaskTarget, FetchMetadata}; +use net_traits::{FetchTaskTarget, FetchMetadata, NetworkError}; use net_traits::request::{CacheMode, CredentialsMode, Destination}; use net_traits::request::{RedirectMode, Referrer, Request, RequestMode, ResponseTainting}; use net_traits::request::{Type, Origin, Window}; -use net_traits::response::{HttpsState, TerminationReason}; -use net_traits::response::{Response, ResponseBody, ResponseType}; +use net_traits::response::{HttpsState, Response, ResponseBody, ResponseType}; use resource_thread::CancellationListener; use std::borrow::Cow; use std::collections::HashSet; +use std::error::Error; use std::fs::File; use std::io::Read; use std::iter::FromIterator; @@ -155,7 +155,7 @@ fn main_fetch(request: Rc, if request.local_urls_only { match request.current_url().scheme() { "about" | "blob" | "data" | "filesystem" => (), // Ok, the URL is local. - _ => response = Some(Response::network_error()) + _ => response = Some(Response::network_error(NetworkError::Internal("Non-local scheme".into()))) } } @@ -214,14 +214,14 @@ fn main_fetch(request: Rc, basic_fetch(request.clone(), cache, target, done_chan, context) } else if request.mode == RequestMode::SameOrigin { - Response::network_error() + Response::network_error(NetworkError::Internal("Cross-origin response".into())) } else if request.mode == RequestMode::NoCORS { request.response_tainting.set(ResponseTainting::Opaque); basic_fetch(request.clone(), cache, target, done_chan, context) } else if !matches!(current_url.scheme(), "http" | "https") { - Response::network_error() + Response::network_error(NetworkError::Internal("Non-http scheme".into())) } else if request.use_cors_preflight || (request.unsafe_request && @@ -263,8 +263,9 @@ fn main_fetch(request: Rc, { // Step 14 - let network_error_res = Response::network_error(); - let internal_response = if response.is_network_error() { + let network_error_res; + let internal_response = if let Some(error) = response.get_network_error() { + network_error_res = Response::network_error(error.clone()); &network_error_res } else { response.actual_response() @@ -434,10 +435,10 @@ fn basic_fetch(request: Rc, response.headers.set(ContentType(mime)); response }, - Err(_) => Response::network_error() + Err(_) => Response::network_error(NetworkError::Internal("Decoding data URL failed".into())) } } else { - Response::network_error() + Response::network_error(NetworkError::Internal("Unexpected method for data".into())) } }, @@ -445,23 +446,26 @@ fn basic_fetch(request: Rc, if *request.method.borrow() == Method::Get { match url.to_file_path() { Ok(file_path) => { - File::open(file_path.clone()).ok().map_or(Response::network_error(), |mut file| { - let mut bytes = vec![]; - let _ = file.read_to_end(&mut bytes); - let mime = guess_mime_type(file_path); + match File::open(file_path.clone()) { + Ok(mut file) => { + let mut bytes = vec![]; + let _ = file.read_to_end(&mut bytes); + let mime = guess_mime_type(file_path); - let mut response = Response::new(); - // https://github.com/whatwg/fetch/issues/312 - response.url = Some(url.clone()); - *response.body.lock().unwrap() = ResponseBody::Done(bytes); - response.headers.set(ContentType(mime)); - response - }) + let mut response = Response::new(); + // https://github.com/whatwg/fetch/issues/312 + response.url = Some(url.clone()); + *response.body.lock().unwrap() = ResponseBody::Done(bytes); + response.headers.set(ContentType(mime)); + response + }, + _ => Response::network_error(NetworkError::Internal("Opening file failed".into())), + } }, - _ => Response::network_error() + _ => Response::network_error(NetworkError::Internal("Constructing file path failed".into())) } } else { - Response::network_error() + Response::network_error(NetworkError::Internal("Unexpected method for file".into())) } }, @@ -469,7 +473,7 @@ fn basic_fetch(request: Rc, println!("Loading blob {}", url.as_str()); // Step 2. if *request.method.borrow() != Method::Get { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("Unexpected method for blob".into())); } match load_blob_sync(url.clone(), context.filemanager.clone()) { @@ -482,7 +486,7 @@ fn basic_fetch(request: Rc, }, Err(e) => { debug!("Failed to load {}: {:?}", url, e); - Response::network_error() + Response::network_error(e) }, } }, @@ -492,7 +496,7 @@ fn basic_fetch(request: Rc, panic!("Unimplemented scheme for Fetch") }, - _ => Response::network_error() + _ => Response::network_error(NetworkError::Internal("Unexpected scheme".into())) } } @@ -530,8 +534,8 @@ fn http_fetch(request: Rc, request.redirect_mode.get() != RedirectMode::Manual) || (res.url_list.borrow().len() > 1 && request.redirect_mode.get() != RedirectMode::Follow) || - res.response_type == ResponseType::Error { - return Response::network_error(); + res.is_network_error() { + return Response::network_error(NetworkError::Internal("Request failed".into())); } // Substep 4 @@ -563,8 +567,8 @@ fn http_fetch(request: Rc, if method_mismatch || header_mismatch { let preflight_result = cors_preflight_fetch(request.clone(), cache, context); // Sub-substep 2 - if preflight_result.response_type == ResponseType::Error { - return Response::network_error(); + if let Some(e) = preflight_result.get_network_error() { + return Response::network_error(e.clone()); } } } @@ -578,7 +582,7 @@ fn http_fetch(request: Rc, // Substep 4 if cors_flag && cors_check(request.clone(), &fetch_result).is_err() { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("CORS check failed".into())); } fetch_result.return_internal.set(false); @@ -589,12 +593,15 @@ fn http_fetch(request: Rc, let mut response = response.unwrap(); // Step 5 - match response.actual_response().status.unwrap() { + match response.actual_response().status { // Code 301, 302, 303, 307, 308 - StatusCode::MovedPermanently | StatusCode::Found | StatusCode::SeeOther | - StatusCode::TemporaryRedirect | StatusCode::PermanentRedirect => { + Some(StatusCode::MovedPermanently) | + Some(StatusCode::Found) | + Some(StatusCode::SeeOther) | + Some(StatusCode::TemporaryRedirect) | + Some(StatusCode::PermanentRedirect) => { response = match request.redirect_mode.get() { - RedirectMode::Error => Response::network_error(), + RedirectMode::Error => Response::network_error(NetworkError::Internal("Redirect mode error".into())), RedirectMode::Manual => { response.to_filtered(ResponseType::OpaqueRedirect) }, @@ -608,7 +615,7 @@ fn http_fetch(request: Rc, }, // Code 401 - StatusCode::Unauthorized => { + Some(StatusCode::Unauthorized) => { // Step 1 // FIXME: Figure out what to do with request window objects if cors_flag || !credentials { @@ -633,7 +640,7 @@ fn http_fetch(request: Rc, } // Code 407 - StatusCode::ProxyAuthenticationRequired => { + Some(StatusCode::ProxyAuthenticationRequired) => { // Step 1 // TODO: Figure out what to do with request window objects @@ -688,13 +695,13 @@ fn http_redirect_fetch(request: Rc, // Step 3 let location = match response.actual_response().headers.get::() { Some(&Location(ref location)) => location.clone(), - _ => return Response::network_error() + _ => return Response::network_error(NetworkError::Internal("Location header parsing failure".into())) }; let response_url = response.actual_response().url.as_ref().unwrap(); let location_url = response_url.join(&*location); let location_url = match location_url { Ok(url) => url, - _ => return Response::network_error() + _ => return Response::network_error(NetworkError::Internal("Location URL parsing failure".into())) }; // Step 4 @@ -702,7 +709,7 @@ fn http_redirect_fetch(request: Rc, // Step 5 if request.redirect_count.get() >= 20 { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("Too many redirects".into())); } // Step 6 @@ -717,12 +724,12 @@ fn http_redirect_fetch(request: Rc, let has_credentials = has_credentials(&location_url); if request.mode == RequestMode::CORSMode && !same_origin && has_credentials { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("Cross-origin credentials check failed".into())); } // Step 8 if cors_flag && has_credentials { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("Credentials check failed".into())); } // Step 9 @@ -938,7 +945,7 @@ fn http_network_or_cache_fetch(request: Rc, // Step 18 if response.is_none() { response = Some(http_network_fetch(http_request.clone(), credentials_flag, - done_chan, context.devtools_chan.clone())); + done_chan, context)); } let response = response.unwrap(); @@ -972,10 +979,11 @@ fn http_network_or_cache_fetch(request: Rc, } /// [HTTP network fetch](https://fetch.spec.whatwg.org/#http-network-fetch) -fn http_network_fetch(request: Rc, - _credentials_flag: bool, - done_chan: &mut DoneChannel, - devtools_chan: Option>) -> Response { +fn http_network_fetch(request: Rc, + credentials_flag: bool, + done_chan: &mut DoneChannel, + context: &FetchContext) + -> Response { // TODO: Implement HTTP network fetch spec // Step 1 @@ -995,7 +1003,7 @@ fn http_network_fetch(request: Rc, let url = request.current_url(); let cancellation_listener = CancellationListener::new(None); - let request_id = devtools_chan.as_ref().map(|_| { + let request_id = context.devtools_chan.as_ref().map(|_| { uuid::Uuid::new_v4().simple().to_string() }); @@ -1017,7 +1025,8 @@ fn http_network_fetch(request: Rc, response.status = Some(res.response.status); response.raw_status = Some((res.response.status_raw().0, res.response.status_raw().1.as_bytes().to_vec())); - response.headers = res.response.headers.clone(); + response.headers = res.response.headers.clone(); + response.referrer = request.referrer.borrow().to_url().cloned(); let res_body = response.body.clone(); @@ -1028,7 +1037,7 @@ fn http_network_fetch(request: Rc, FetchMetadata::Filtered { unsafe_, .. } => unsafe_ }; let done_sender = done_chan.as_ref().map(|ch| ch.0.clone()); - let devtools_sender = devtools_chan.clone(); + let devtools_sender = context.devtools_chan.clone(); let meta_status = meta.status.clone(); let meta_headers = meta.headers.clone(); spawn_named(format!("fetch worker thread"), move || { @@ -1091,8 +1100,14 @@ fn http_network_fetch(request: Rc, } }); }, - Err(_) => { - response.termination_reason = Some(TerminationReason::Fatal); + Err(error) => { + let error = match error.error { + LoadErrorType::ConnectionAborted { .. } => unreachable!(), + LoadErrorType::Ssl { reason } => NetworkError::SslValidation(error.url, reason), + LoadErrorType::Cancelled => NetworkError::LoadCancelled, + e => NetworkError::Internal(e.description().to_owned()) + }; + return Response::network_error(error); } }; @@ -1133,8 +1148,13 @@ fn http_network_fetch(request: Rc, // TODO this step isn't possible yet // Step 13 + // Step 14. + if credentials_flag { + set_cookies_from_headers(&url, &response.headers, &context.state.cookie_jar); + } + // TODO these steps - // Step 14 + // Step 15 // Substep 1 // Substep 2 // Sub-substep 1 @@ -1143,7 +1163,7 @@ fn http_network_fetch(request: Rc, // Sub-substep 4 // Substep 3 - // Step 15 + // Step 16 response } @@ -1191,7 +1211,7 @@ fn cors_preflight_fetch(request: Rc, match response.headers.get::() { Some(&AccessControlAllowMethods(ref m)) => m.clone(), // Substep 3 - None => return Response::network_error() + None => return Response::network_error(NetworkError::Internal("CORS ACAM check failed".into())) } } else { vec![] @@ -1202,7 +1222,7 @@ fn cors_preflight_fetch(request: Rc, match response.headers.get::() { Some(&AccessControlAllowHeaders(ref hn)) => hn.clone(), // Substep 3 - None => return Response::network_error() + None => return Response::network_error(NetworkError::Internal("CORS ACAH check failed".into())) } } else { vec![] @@ -1218,7 +1238,7 @@ fn cors_preflight_fetch(request: Rc, methods, request.method.borrow()); if methods.iter().all(|method| *method != *request.method.borrow()) && !is_simple_method(&*request.method.borrow()) { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("CORS method check failed".into())); } // Substep 6 @@ -1227,7 +1247,7 @@ fn cors_preflight_fetch(request: Rc, let set: HashSet<&UniCase> = HashSet::from_iter(header_names.iter()); if request.headers.borrow().iter().any(|ref hv| !set.contains(&UniCase(hv.name().to_owned())) && !is_simple_header(hv)) { - return Response::network_error(); + return Response::network_error(NetworkError::Internal("CORS headers check failed".into())); } // Substep 7, 8 @@ -1250,7 +1270,7 @@ fn cors_preflight_fetch(request: Rc, } // Step 8 - Response::network_error() + Response::network_error(NetworkError::Internal("CORS check failed".into())) } /// [CORS check](https://fetch.spec.whatwg.org#concept-cors-check) diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index c95b7c711c0..885ce794b6d 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -499,8 +499,8 @@ fn set_cookie_for_url(cookie_jar: &Arc>, } } -fn set_cookies_from_response(url: &Url, response: &HttpResponse, cookie_jar: &Arc>) { - if let Some(cookies) = response.headers().get_raw("set-cookie") { +pub fn set_cookies_from_headers(url: &Url, headers: &Headers, cookie_jar: &Arc>) { + if let Some(cookies) = headers.get_raw("set-cookie") { for cookie in cookies.iter() { if let Ok(cookie_value) = String::from_utf8(cookie.clone()) { set_cookie_for_url(&cookie_jar, @@ -731,7 +731,7 @@ pub fn process_response_headers(response: &HttpResponse, // https://fetch.spec.whatwg.org/#concept-http-network-fetch step 9 if load_data.credentials_flag { - set_cookies_from_response(url, response, cookie_jar); + set_cookies_from_headers(url, response.headers(), cookie_jar); } update_sts_list_from_response(url, response, hsts_list); } diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 2908571bf84..aad61971fd7 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -262,18 +262,6 @@ pub trait Action { fn process(self, listener: &mut Listener); } -/// A listener for asynchronous network events. Cancelling the underlying request is unsupported. -pub trait AsyncResponseListener { - /// The response headers for a request have been received. - fn headers_available(&mut self, metadata: Result); - /// A portion of the response body has been received. This data is unavailable after - /// this method returned, and must be stored accordingly. - fn data_available(&mut self, payload: Vec); - /// The response is complete. If the provided status is an Err value, there is no guarantee - /// that the response body was completely read. - fn response_complete(&mut self, status: Result<(), NetworkError>); -} - /// Data for passing between threads/processes to indicate a particular action to /// take on a provided network listener. #[derive(Deserialize, Serialize)] @@ -286,17 +274,6 @@ pub enum ResponseAction { ResponseComplete(Result<(), NetworkError>) } -impl Action for ResponseAction { - /// Execute the default action on a provided listener. - fn process(self, listener: &mut T) { - match self { - ResponseAction::HeadersAvailable(m) => listener.headers_available(m), - ResponseAction::DataAvailable(d) => listener.data_available(d), - ResponseAction::ResponseComplete(r) => listener.response_complete(r), - } - } -} - impl Action for FetchResponseMsg { /// Execute the default action on a provided listener. fn process(self, listener: &mut T) { diff --git a/components/net_traits/response.rs b/components/net_traits/response.rs index c4b4a3fe8e3..e9de8d83a58 100644 --- a/components/net_traits/response.rs +++ b/components/net_traits/response.rs @@ -14,12 +14,12 @@ use std::sync::{Arc, Mutex}; use url::Url; /// [Response type](https://fetch.spec.whatwg.org/#concept-response-type) -#[derive(Clone, PartialEq, Copy, Debug, Deserialize, Serialize, HeapSizeOf)] +#[derive(Clone, PartialEq, Debug, Deserialize, Serialize, HeapSizeOf)] pub enum ResponseType { Basic, CORS, Default, - Error, + Error(NetworkError), Opaque, OpaqueRedirect } @@ -91,6 +91,7 @@ pub struct Response { pub body: Arc>, pub cache_state: CacheState, pub https_state: HttpsState, + pub referrer: Option, /// [Internal response](https://fetch.spec.whatwg.org/#concept-internal-response), only used if the Response /// is a filtered response pub internal_response: Option>, @@ -111,14 +112,15 @@ impl Response { body: Arc::new(Mutex::new(ResponseBody::Empty)), cache_state: CacheState::None, https_state: HttpsState::None, + referrer: None, internal_response: None, return_internal: Cell::new(true) } } - pub fn network_error() -> Response { + pub fn network_error(e: NetworkError) -> Response { Response { - response_type: ResponseType::Error, + response_type: ResponseType::Error(e), termination_reason: None, url: None, url_list: RefCell::new(vec![]), @@ -128,6 +130,7 @@ impl Response { body: Arc::new(Mutex::new(ResponseBody::Empty)), cache_state: CacheState::None, https_state: HttpsState::None, + referrer: None, internal_response: None, return_internal: Cell::new(true) } @@ -135,11 +138,18 @@ impl Response { pub fn is_network_error(&self) -> bool { match self.response_type { - ResponseType::Error => true, + ResponseType::Error(..) => true, _ => false } } + pub fn get_network_error(&self) -> Option<&NetworkError> { + match self.response_type { + ResponseType::Error(ref e) => Some(e), + _ => None, + } + } + pub fn actual_response(&self) -> &Response { if self.return_internal.get() && self.internal_response.is_some() { &**self.internal_response.as_ref().unwrap() @@ -159,13 +169,15 @@ impl Response { /// Convert to a filtered response, of type `filter_type`. /// Do not use with type Error or Default pub fn to_filtered(self, filter_type: ResponseType) -> Response { - assert!(filter_type != ResponseType::Error); - assert!(filter_type != ResponseType::Default); + match filter_type { + ResponseType::Default | ResponseType::Error(..) => panic!(), + _ => (), + } let old_response = self.to_actual(); - if Response::is_network_error(&old_response) { - return Response::network_error(); + if let ResponseType::Error(e) = old_response.response_type { + return Response::network_error(e); } let old_headers = old_response.headers.clone(); @@ -173,8 +185,8 @@ impl Response { response.internal_response = Some(Box::new(old_response)); response.response_type = filter_type; - match filter_type { - ResponseType::Default | ResponseType::Error => unreachable!(), + match response.response_type { + ResponseType::Default | ResponseType::Error(..) => unreachable!(), ResponseType::Basic => { let headers = old_headers.iter().filter(|header| { @@ -235,11 +247,12 @@ impl Response { metadata.headers = Some(Serde(response.headers.clone())); metadata.status = response.raw_status.clone(); metadata.https_state = response.https_state; + metadata.referrer = response.referrer.clone(); metadata }; - if self.is_network_error() { - return Err(NetworkError::Internal("Cannot extract metadata from network error".to_owned())); + if let Some(error) = self.get_network_error() { + return Err(error.clone()); } let metadata = self.url.as_ref().map(|url| init_metadata(self, url)); diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index cb8fc3d753d..8c57dffa8e1 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -28,7 +28,7 @@ use hyper::mime::{Mime, SubLevel, TopLevel}; use hyper_serde::Serde; use js::jsapi::JSTracer; use msg::constellation_msg::PipelineId; -use net_traits::{AsyncResponseListener, Metadata, NetworkError}; +use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError}; use network_listener::PreInvoke; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType}; use profile_traits::time::{TimerMetadataReflowType, ProfilerCategory, profile}; @@ -332,11 +332,21 @@ impl ParserContext { } } -impl AsyncResponseListener for ParserContext { - fn headers_available(&mut self, meta_result: Result) { +impl FetchResponseListener for ParserContext { + fn process_request_body(&mut self) {} + + fn process_request_eof(&mut self) {} + + fn process_response(&mut self, + meta_result: Result) { let mut ssl_error = None; let metadata = match meta_result { - Ok(meta) => Some(meta), + Ok(meta) => { + Some(match meta { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { unsafe_, .. } => unsafe_ + }) + }, Err(NetworkError::SslValidation(url, reason)) => { ssl_error = Some(reason); let mut meta = Metadata::default(url); @@ -408,7 +418,7 @@ impl AsyncResponseListener for ParserContext { } } - fn data_available(&mut self, payload: Vec) { + fn process_response_chunk(&mut self, payload: Vec) { if !self.is_synthesized_document { // FIXME: use Vec (html5ever #34) let data = UTF_8.decode(&payload, DecoderTrap::Replace).unwrap(); @@ -420,7 +430,7 @@ impl AsyncResponseListener for ParserContext { } } - fn response_complete(&mut self, status: Result<(), NetworkError>) { + fn process_response_eof(&mut self, status: Result<(), NetworkError>) { let parser = match self.parser.as_ref() { Some(parser) => parser.root(), None => return, diff --git a/components/script/network_listener.rs b/components/script/network_listener.rs index 4ff65bf8073..d69b7334bad 100644 --- a/components/script/network_listener.rs +++ b/components/script/network_listener.rs @@ -2,8 +2,7 @@ * 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 net_traits::{Action, AsyncResponseListener, FetchResponseListener}; -use net_traits::{FetchResponseMsg, ResponseAction}; +use net_traits::{Action, FetchResponseListener, FetchResponseMsg}; use script_runtime::{CommonScriptMsg, ScriptChan}; use script_runtime::ScriptThreadEventCategory::NetworkEvent; use script_thread::{Runnable, RunnableWrapper}; @@ -34,13 +33,6 @@ impl NetworkListener { } } -// helps type inference -impl NetworkListener { - pub fn notify_action(&self, action: ResponseAction) { - self.notify(action); - } -} - // helps type inference impl NetworkListener { pub fn notify_fetch(&self, action: FetchResponseMsg) { diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index d98298d0cb7..ec3bc5b1b34 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -57,7 +57,7 @@ use dom::window::{ReflowReason, Window}; use dom::worker::TrustedWorkerAddress; use euclid::Rect; use euclid::point::Point2D; -use hyper::header::{ContentType, Headers, HttpDate, LastModified}; +use hyper::header::{ContentType, HttpDate, LastModified}; use hyper::header::ReferrerPolicy as ReferrerPolicyHeader; use hyper::method::Method; use hyper::mime::{Mime, SubLevel, TopLevel}; @@ -72,10 +72,10 @@ use js::rust::Runtime; use layout_wrapper::ServoLayoutNode; use mem::heap_size_of_self_and_children; use msg::constellation_msg::{FrameType, PipelineId, PipelineNamespace, ReferrerPolicy}; -use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata, ResourceThreads}; -use net_traits::{IpcSend, LoadData as NetLoadData}; +use net_traits::{CoreResourceMsg, IpcSend, Metadata, ResourceThreads}; use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; +use net_traits::request::{CredentialsMode, Destination, RequestInit}; use network_listener::NetworkListener; use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan}; use profile_traits::time::{self, ProfilerCategory, profile}; @@ -2114,30 +2114,29 @@ impl ScriptThread { wrapper: None, }; ROUTER.add_route(action_receiver.to_opaque(), box move |message| { - listener.notify_action(message.to().unwrap()); + listener.notify_fetch(message.to().unwrap()); }); - let response_target = AsyncResponseTarget { - sender: action_sender, - }; if load_data.url.scheme() == "javascript" { load_data.url = Url::parse("about:blank").unwrap(); } - self.resource_threads.send(CoreResourceMsg::Load(NetLoadData { - context: LoadContext::Browsing, - url: load_data.url, + let request = RequestInit { + url: load_data.url.clone(), method: load_data.method, - headers: Headers::new(), - preserved_headers: load_data.headers, - data: load_data.data, - cors: None, + destination: Destination::Document, + credentials_mode: CredentialsMode::Include, + use_url_credentials: true, + origin: load_data.url, pipeline_id: Some(id), - credentials_flag: true, + referrer_url: load_data.referrer_url, referrer_policy: load_data.referrer_policy, - referrer_url: load_data.referrer_url - }, LoadConsumer::Listener(response_target), None)).unwrap(); + headers: load_data.headers, + body: load_data.data, + .. RequestInit::default() + }; + self.resource_threads.send(CoreResourceMsg::Fetch(request, action_sender)).unwrap(); self.incomplete_loads.borrow_mut().push(incomplete); } diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs index 60f6456ed0a..8ab9c4e8795 100644 --- a/tests/unit/net/fetch.rs +++ b/tests/unit/net/fetch.rs @@ -708,7 +708,7 @@ fn response_is_done(response: &Response) -> bool { (*response.body.lock().unwrap()).is_done() } // if the internal response cannot have a body, it shouldn't block the "done" state - ResponseType::Opaque | ResponseType::OpaqueRedirect | ResponseType::Error => true + ResponseType::Opaque | ResponseType::OpaqueRedirect | ResponseType::Error(..) => true }; let internal_complete = if let Some(ref res) = response.internal_response { diff --git a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function-src.html b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function-src.html index 4a15b3f0837..e21260cd353 100644 --- a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function-src.html +++ b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function-src.html @@ -6,12 +6,13 @@
diff --git a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html index b75062b8d93..c6fa765b89d 100644 --- a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html +++ b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/navigating-across-documents/source/navigate-child-function.html @@ -6,13 +6,14 @@