diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 481da031056..621a5c266af 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -110,11 +110,8 @@ fn main_fetch(request: Rc, cors_flag: bool, recursive_flag: bool) -> Re let mut response = None; // Step 2 - if request.local_urls_only { - match &*request.current_url().scheme { - "about" | "blob" | "data" | "filesystem" => response = Some(Response::network_error()), - _ => { } - }; + if request.local_urls_only && !url_is_local(&request.current_url()) { + response = Some(Response::network_error()); } // Step 3 @@ -1047,6 +1044,13 @@ fn includes_credentials(url: &Url) -> bool { false } +fn url_is_local(url: &Url) -> bool { + match &*url.scheme { + "about" | "blob" | "data" | "filesystem" => true, + _ => false + } +} + fn response_needs_revalidation(_response: &Response) -> bool { // TODO this function false diff --git a/components/net_traits/request.rs b/components/net_traits/request.rs index 74742703035..11710942420 100644 --- a/components/net_traits/request.rs +++ b/components/net_traits/request.rs @@ -152,7 +152,7 @@ impl Request { pub fn new(url: Url, origin: Option, is_service_worker_global_scope: bool) -> Request { - Request { + Request { method: RefCell::new(Method::Get), local_urls_only: false, sandboxed_storage_area_urls: false, @@ -257,4 +257,8 @@ impl Request { _ => false } } + + pub fn set_local_urls_only(&mut self, local_urls_only: bool) { + self.local_urls_only = local_urls_only; + } } diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs index 010d49e5732..0c586797cb3 100644 --- a/tests/unit/net/fetch.rs +++ b/tests/unit/net/fetch.rs @@ -268,6 +268,35 @@ fn test_fetch_response_is_opaque_redirect_filtered() { } } +#[test] +fn test_fetch_with_local_urls_only() { + // If flag `local_urls_only` is set, fetching a non-local URL must result in network error. + + static MESSAGE: &'static [u8] = b""; + let handler = move |_: HyperRequest, response: HyperResponse| { + response.send(MESSAGE).unwrap(); + }; + let (mut server, server_url) = make_server(handler); + + let do_fetch = |url: Url| { + let origin = Origin::Origin(url.origin()); + let mut request = Request::new(url, Some(origin), false); + request.referer = Referer::NoReferer; + + // Set the flag. + request.set_local_urls_only(true); + + let wrapped_request = Rc::new(request); + fetch(wrapped_request) + }; + + let local_url = Url::parse("about:config").unwrap(); + assert!(do_fetch(local_url).is_network_error()); + assert!(!do_fetch(server_url).is_network_error()); + + let _ = server.close(); +} + fn test_fetch_redirect_count(message: &'static [u8], redirect_cap: u32) -> Response { let handler = move |request: HyperRequest, mut response: HyperResponse| {