diff options
-rw-r--r-- | components/net/http_loader.rs | 33 | ||||
-rw-r--r-- | components/net_traits/request.rs | 20 | ||||
-rw-r--r-- | components/script/dom/request.rs | 36 | ||||
-rw-r--r-- | components/script/fetch.rs | 13 | ||||
-rw-r--r-- | tests/unit/net/data_loader.rs | 2 | ||||
-rw-r--r-- | tests/unit/net/fetch.rs | 52 |
6 files changed, 85 insertions, 71 deletions
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 5489a49594b..73ef5b46451 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -34,7 +34,7 @@ use msg::constellation_msg::PipelineId; use net_traits::{CookieSource, FetchMetadata, NetworkError, ReferrerPolicy}; use net_traits::request::{CacheMode, CredentialsMode, Destination, Origin}; use net_traits::request::{RedirectMode, Referrer, Request, RequestMode}; -use net_traits::request::{ResponseTainting, Type}; +use net_traits::request::{ResponseTainting, ServiceWorkersMode, Type}; use net_traits::response::{HttpsState, Response, ResponseBody, ResponseType}; use resource_thread::AuthCache; use servo_url::{ImmutableOrigin, ServoUrl}; @@ -521,15 +521,29 @@ pub fn http_fetch(request: &mut Request, // nothing to do, since actual_response is a function on response // Step 3 - if !request.skip_service_worker && !request.is_service_worker_global_scope { + if request.service_workers_mode != ServiceWorkersMode::None { // Substep 1 - // TODO (handle fetch unimplemented) + if request.service_workers_mode == ServiceWorkersMode::All { + // TODO (handle fetch unimplemented) + } + // Substep 2 + if response.is_none() && request.is_subresource_request() && match request.origin { + Origin::Origin(ref origin) if *origin == request.url().origin() => true, + _ => false, + } { + // TODO (handle foreign fetch unimplemented) + } + + // Substep 3 if let Some(ref res) = response { - // Substep 2 + // Subsubstep 1 + // TODO: transmit body for request + + // Subsubstep 2 // nothing to do, since actual_response is a function on response - // Substep 3 + // Subsubstep 3 if (res.response_type == ResponseType::Opaque && request.mode != RequestMode::NoCors) || (res.response_type == ResponseType::OpaqueRedirect && @@ -539,7 +553,7 @@ pub fn http_fetch(request: &mut Request, return Response::network_error(NetworkError::Internal("Request failed".into())); } - // Substep 4 + // Subsubstep 4 // TODO: set response's CSP list on actual_response } } @@ -576,7 +590,9 @@ pub fn http_fetch(request: &mut Request, } // Substep 2 - request.skip_service_worker = true; + if request.redirect_mode == RedirectMode::Follow { + request.service_workers_mode = ServiceWorkersMode::Foreign; + } // Substep 3 let mut fetch_result = http_network_or_cache_fetch( @@ -1238,8 +1254,7 @@ fn cors_preflight_fetch(request: &Request, context: &FetchContext) -> Response { // Step 1 - let mut preflight = Request::new(request.current_url(), Some(request.origin.clone()), - request.is_service_worker_global_scope, request.pipeline_id); + let mut preflight = Request::new(request.current_url(), Some(request.origin.clone()), request.pipeline_id); preflight.method = Method::Options; preflight.initiator = request.initiator.clone(); preflight.type_ = request.type_.clone(); diff --git a/components/net_traits/request.rs b/components/net_traits/request.rs index 74f58d6f0c1..bc035ec5c3e 100644 --- a/components/net_traits/request.rs +++ b/components/net_traits/request.rs @@ -97,6 +97,14 @@ pub enum CacheMode { OnlyIfCached, } +/// [Service-workers mode](https://fetch.spec.whatwg.org/#request-service-workers-mode) +#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)] +pub enum ServiceWorkersMode { + All, + Foreign, + None, +} + /// [Redirect mode](https://fetch.spec.whatwg.org/#concept-request-redirect-mode) #[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)] pub enum RedirectMode { @@ -140,6 +148,7 @@ pub struct RequestInit { pub headers: Headers, pub unsafe_request: bool, pub body: Option<Vec<u8>>, + pub service_workers_mode: ServiceWorkersMode, // TODO: client object pub type_: Type, pub destination: Destination, @@ -170,6 +179,7 @@ impl Default for RequestInit { headers: Headers::new(), unsafe_request: false, body: None, + service_workers_mode: ServiceWorkersMode::All, type_: Type::None, destination: Destination::None, synchronous: false, @@ -208,12 +218,12 @@ pub struct Request { /// https://fetch.spec.whatwg.org/#concept-request-body pub body: Option<Vec<u8>>, // TODO: client object - pub is_service_worker_global_scope: bool, pub window: Window, // TODO: target browsing context /// https://fetch.spec.whatwg.org/#request-keepalive-flag pub keep_alive: bool, - pub skip_service_worker: bool, + // https://fetch.spec.whatwg.org/#request-service-workers-mode + pub service_workers_mode: ServiceWorkersMode, /// https://fetch.spec.whatwg.org/#concept-request-initiator pub initiator: Initiator, /// https://fetch.spec.whatwg.org/#concept-request-type @@ -257,7 +267,6 @@ pub struct Request { impl Request { pub fn new(url: ServoUrl, origin: Option<Origin>, - is_service_worker_global_scope: bool, pipeline_id: Option<PipelineId>) -> Request { Request { @@ -267,10 +276,9 @@ impl Request { headers: Headers::new(), unsafe_request: false, body: None, - is_service_worker_global_scope: is_service_worker_global_scope, window: Window::Client, keep_alive: false, - skip_service_worker: false, + service_workers_mode: ServiceWorkersMode::All, initiator: Initiator::None, type_: Type::None, destination: Destination::None, @@ -295,12 +303,12 @@ impl Request { pub fn from_init(init: RequestInit) -> Request { let mut req = Request::new(init.url.clone(), Some(Origin::Origin(init.origin.origin())), - false, init.pipeline_id); req.method = init.method; req.headers = init.headers; req.unsafe_request = init.unsafe_request; req.body = init.body; + req.service_workers_mode = init.service_workers_mode; req.type_ = init.type_; req.destination = init.destination; req.synchronous = init.synchronous; diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 5894eae8de7..82b7773fc3e 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -55,14 +55,11 @@ pub struct Request { impl Request { fn new_inherited(global: &GlobalScope, - url: ServoUrl, - is_service_worker_global_scope: bool) -> Request { + url: ServoUrl) -> Request { Request { reflector_: Reflector::new(), request: DOMRefCell::new( - net_request_from_global(global, - url, - is_service_worker_global_scope)), + net_request_from_global(global, url)), body_used: Cell::new(false), headers: Default::default(), mime_type: DOMRefCell::new("".to_string().into_bytes()), @@ -71,11 +68,9 @@ impl Request { } pub fn new(global: &GlobalScope, - url: ServoUrl, - is_service_worker_global_scope: bool) -> Root<Request> { + url: ServoUrl) -> Root<Request> { reflect_dom_object(box Request::new_inherited(global, - url, - is_service_worker_global_scope), + url), global, RequestBinding::Wrap) } @@ -111,9 +106,7 @@ impl Request { return Err(Error::Type("Url includes credentials".to_string())) } // Step 5.4 - temporary_request = net_request_from_global(global, - url, - false); + temporary_request = net_request_from_global(global, url); // Step 5.5 fallback_mode = Some(NetTraitsRequestMode::CorsMode); // Step 5.6 @@ -152,9 +145,7 @@ impl Request { // Step 12 let mut request: NetTraitsRequest; - request = net_request_from_global(global, - temporary_request.current_url(), - false); + request = net_request_from_global(global, temporary_request.current_url()); request.method = temporary_request.method; request.headers = temporary_request.headers.clone(); request.unsafe_request = true; @@ -293,9 +284,7 @@ impl Request { } // Step 26 - let r = Request::from_net_request(global, - false, - request); + let r = Request::from_net_request(global, request); r.headers.or_init(|| Headers::for_request(&r.global())); // Step 27 @@ -421,11 +410,9 @@ impl Request { impl Request { fn from_net_request(global: &GlobalScope, - is_service_worker_global_scope: bool, net_request: NetTraitsRequest) -> Root<Request> { let r = Request::new(global, - net_request.current_url(), - is_service_worker_global_scope); + net_request.current_url()); *r.request.borrow_mut() = net_request; r } @@ -433,11 +420,10 @@ impl Request { fn clone_from(r: &Request) -> Fallible<Root<Request>> { let req = r.request.borrow(); let url = req.url(); - let is_service_worker_global_scope = req.is_service_worker_global_scope; let body_used = r.body_used.get(); let mime_type = r.mime_type.borrow().clone(); let headers_guard = r.Headers().get_guard(); - let r_clone = Request::new(&r.global(), url, is_service_worker_global_scope); + let r_clone = Request::new(&r.global(), url); r_clone.request.borrow_mut().pipeline_id = req.pipeline_id; { let mut borrowed_r_request = r_clone.request.borrow_mut(); @@ -457,13 +443,11 @@ impl Request { } fn net_request_from_global(global: &GlobalScope, - url: ServoUrl, - is_service_worker_global_scope: bool) -> NetTraitsRequest { + url: ServoUrl) -> NetTraitsRequest { let origin = Origin::Origin(global.get_url().origin()); let pipeline_id = global.pipeline_id(); NetTraitsRequest::new(url, Some(origin), - is_service_worker_global_scope, Some(pipeline_id)) } diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 39c5cbc8f97..5a5ca041acd 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -7,6 +7,7 @@ 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::error::Error; +use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::refcounted::{Trusted, TrustedPromise}; use dom::bindings::reflector::DomObject; @@ -16,13 +17,14 @@ use dom::headers::Guard; use dom::promise::Promise; use dom::request::Request; use dom::response::Response; +use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use js::jsapi::JSAutoCompartment; use net_traits::{FetchResponseListener, NetworkError}; use net_traits::{FilteredMetadata, FetchMetadata, Metadata}; use net_traits::CoreResourceMsg::Fetch as NetTraitsFetch; -use net_traits::request::Request as NetTraitsRequest; +use net_traits::request::{Request as NetTraitsRequest, ServiceWorkersMode}; use net_traits::request::RequestInit as NetTraitsRequestInit; use network_listener::{NetworkListener, PreInvoke}; use servo_url::ServoUrl; @@ -83,12 +85,17 @@ pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: RootedTraceableBox< }, Ok(r) => r.get_request(), }; - let request_init = request_init_from_request(request); + let mut request_init = request_init_from_request(request); // Step 3 - response.Headers().set_guard(Guard::Immutable); + if global.downcast::<ServiceWorkerGlobalScope>().is_some() { + request_init.service_workers_mode = ServiceWorkersMode::Foreign; + } // Step 4 + response.Headers().set_guard(Guard::Immutable); + + // Step 5 let (action_sender, action_receiver) = ipc::channel().unwrap(); let fetch_context = Arc::new(Mutex::new(FetchContext { fetch_promise: Some(TrustedPromise::new(promise.clone())), diff --git a/tests/unit/net/data_loader.rs b/tests/unit/net/data_loader.rs index 409757ee61f..4ad73dee080 100644 --- a/tests/unit/net/data_loader.rs +++ b/tests/unit/net/data_loader.rs @@ -19,7 +19,7 @@ fn assert_parse(url: &'static str, data: Option<&[u8]>) { let url = ServoUrl::parse(url).unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); let response = fetch(&mut request, None); diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs index 513295d7d6b..675ada47b5c 100644 --- a/tests/unit/net/fetch.rs +++ b/tests/unit/net/fetch.rs @@ -55,7 +55,7 @@ fn test_fetch_response_is_not_network_error() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); let _ = server.close(); @@ -69,7 +69,7 @@ fn test_fetch_response_is_not_network_error() { fn test_fetch_on_bad_port_is_network_error() { let url = ServoUrl::parse("http://www.example.org:6667").unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); assert!(fetch_response.is_network_error()); @@ -86,7 +86,7 @@ fn test_fetch_response_body_matches_const_message() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); let _ = server.close(); @@ -106,7 +106,7 @@ fn test_fetch_response_body_matches_const_message() { fn test_fetch_aboutblank() { let url = ServoUrl::parse("about:blank").unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); assert!(!fetch_response.is_network_error()); @@ -136,7 +136,7 @@ fn test_fetch_blob() { let url = ServoUrl::parse(&format!("blob:{}{}", origin.as_str(), id.simple())).unwrap(); - let mut request = Request::new(url, Some(Origin::Origin(origin.origin())), false, None); + let mut request = Request::new(url, Some(Origin::Origin(origin.origin())), None); let fetch_response = fetch_with_context(&mut request, &context); assert!(!fetch_response.is_network_error()); @@ -160,7 +160,7 @@ fn test_fetch_file() { let url = ServoUrl::from_file_path(path.clone()).unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); let fetch_response = fetch(&mut request, None); assert!(!fetch_response.is_network_error()); @@ -185,7 +185,7 @@ fn test_fetch_file() { fn test_fetch_ftp() { let url = ServoUrl::parse("ftp://not-supported").unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); assert!(fetch_response.is_network_error()); @@ -195,7 +195,7 @@ fn test_fetch_ftp() { fn test_fetch_bogus_scheme() { let url = ServoUrl::parse("bogus://whatever").unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); assert!(fetch_response.is_network_error()); @@ -223,7 +223,7 @@ fn test_cors_preflight_fetch() { let target_url = url.clone().join("a.html").unwrap(); let origin = Origin::Origin(ImmutableOrigin::new_opaque()); - let mut request = Request::new(url.clone(), Some(origin), false, None); + let mut request = Request::new(url.clone(), Some(origin), None); request.referrer = Referrer::ReferrerUrl(target_url); request.referrer_policy = Some(ReferrerPolicy::Origin); request.use_cors_preflight = true; @@ -260,7 +260,7 @@ fn test_cors_preflight_cache_fetch() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(ImmutableOrigin::new_opaque()); - let mut request = Request::new(url.clone(), Some(origin.clone()), false, None); + let mut request = Request::new(url.clone(), Some(origin.clone()), None); request.referrer = Referrer::NoReferrer; request.use_cors_preflight = true; request.mode = RequestMode::CorsMode; @@ -309,7 +309,7 @@ fn test_cors_preflight_fetch_network_error() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(ImmutableOrigin::new_opaque()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.method = Method::Extension("CHICKEN".to_owned()); request.referrer = Referrer::NoReferrer; request.use_cors_preflight = true; @@ -333,7 +333,7 @@ fn test_fetch_response_is_basic_filtered() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); let _ = server.close(); @@ -378,7 +378,7 @@ fn test_fetch_response_is_cors_filtered() { // an origin mis-match will stop it from defaulting to a basic filtered response let origin = Origin::Origin(ImmutableOrigin::new_opaque()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; request.mode = RequestMode::CorsMode; let fetch_response = fetch(&mut request, None); @@ -410,7 +410,7 @@ fn test_fetch_response_is_opaque_filtered() { // an origin mis-match will fall through to an Opaque filtered response let origin = Origin::Origin(ImmutableOrigin::new_opaque()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); let _ = server.close(); @@ -457,7 +457,7 @@ fn test_fetch_response_is_opaque_redirect_filtered() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; request.redirect_mode = RedirectMode::Manual; let fetch_response = fetch(&mut request, None); @@ -491,7 +491,7 @@ fn test_fetch_with_local_urls_only() { let do_fetch = |url: ServoUrl| { let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; // Set the flag. @@ -548,7 +548,7 @@ fn test_fetch_with_hsts() { let url_string = format!("http://localhost:{}", server.socket.port()); let url = ServoUrl::parse(&url_string).unwrap(); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; // Set the flag. request.local_urls_only = false; @@ -567,7 +567,7 @@ fn test_fetch_with_sri_network_error() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; // To calulate hash use : // echo -n "alert('Hello, Network Error');" | openssl dgst -sha384 -binary | openssl base64 -A @@ -591,7 +591,7 @@ fn test_fetch_with_sri_sucess() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; // To calulate hash use : // echo -n "alert('Hello, Network Error');" | openssl dgst -sha384 -binary | openssl base64 -A @@ -630,7 +630,7 @@ fn test_fetch_blocked_nosniff() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.type_ = request_type; let fetch_response = fetch(&mut request, None); let _ = server.close(); @@ -672,7 +672,7 @@ fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); let _ = server.close(); @@ -755,7 +755,7 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; request.method = method; @@ -830,7 +830,7 @@ fn test_fetch_async_returns_complete_response() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); @@ -849,7 +849,7 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() { // an origin mis-match will fall through to an Opaque filtered response let origin = Origin::Origin(ImmutableOrigin::new_opaque()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; let fetch_response = fetch(&mut request, None); @@ -884,7 +884,7 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url, Some(origin), false, None); + let mut request = Request::new(url, Some(origin), None); request.referrer = Referrer::NoReferrer; request.redirect_mode = RedirectMode::Manual; @@ -906,7 +906,7 @@ fn test_fetch_with_devtools() { let (mut server, url) = make_server(handler); let origin = Origin::Origin(url.origin()); - let mut request = Request::new(url.clone(), Some(origin), false, Some(TEST_PIPELINE_ID)); + let mut request = Request::new(url.clone(), Some(origin), Some(TEST_PIPELINE_ID)); request.referrer = Referrer::NoReferrer; let (devtools_chan, devtools_port) = channel::<DevtoolsControlMsg>(); |