diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-10-07 18:39:36 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-07 18:39:36 -0400 |
commit | 75548f40c622f8bc2b3ec6b212fd4b378fcdc22f (patch) | |
tree | b4843908c3ef75018418760a317a7289489bd831 /components/script/dom | |
parent | 95f65cdd3139651ac267494f47cc3ed1f2df9fae (diff) | |
parent | 6dd40962ea707dc0e02676fccd9156efa314141d (diff) | |
download | servo-75548f40c622f8bc2b3ec6b212fd4b378fcdc22f.tar.gz servo-75548f40c622f8bc2b3ec6b212fd4b378fcdc22f.zip |
Auto merge of #24340 - jdm:image-cache-cors, r=Manishearth
Allow using CORS filtered image responses as WebGL textures
More specifically, this makes the "is this image same origin?" check consider the CORS status of the original response, rather than relying on an overly-strict "is this image's response's URL same-origin with a particular global?" check. To do this, we make the image cache double keyed based on the requested URL as well as the requesting origin, and store the CORS status of the eventual response with the final image that eventually gets sent to the HTMLImageElement consumer.
---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #24330 and fix #24368
- [x] There are tests for these changes
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/24340)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/canvasrenderingcontext2d.rs | 62 | ||||
-rw-r--r-- | components/script/dom/element.rs | 12 | ||||
-rw-r--r-- | components/script/dom/eventsource.rs | 24 | ||||
-rw-r--r-- | components/script/dom/htmlanchorelement.rs | 8 | ||||
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 9 | ||||
-rw-r--r-- | components/script/dom/htmlimageelement.rs | 48 | ||||
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 15 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 20 | ||||
-rw-r--r-- | components/script/dom/htmlvideoelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/servoparser/prefetch.rs | 23 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 17 |
11 files changed, 162 insertions, 78 deletions
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 1faf9878b53..c964422c27c 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -19,11 +19,13 @@ use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom}; use crate::dom::bindings::str::DOMString; use crate::dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle}; use crate::dom::canvaspattern::CanvasPattern; +use crate::dom::element::cors_setting_for_element; use crate::dom::element::Element; use crate::dom::globalscope::GlobalScope; use crate::dom::htmlcanvaselement::{CanvasContext, HTMLCanvasElement}; use crate::dom::imagedata::ImageData; use crate::dom::node::{Node, NodeDamage}; +use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope; use crate::dom::textmetrics::TextMetrics; use crate::unpremultiplytable::UNPREMULTIPLY_TABLE; use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg}; @@ -44,10 +46,11 @@ use net_traits::image_cache::ImageOrMetadataAvailable; use net_traits::image_cache::ImageResponse; use net_traits::image_cache::ImageState; use net_traits::image_cache::UsePlaceholder; +use net_traits::request::CorsSettings; use pixels::PixelFormat; use profile_traits::ipc as profiled_ipc; use script_traits::ScriptMsg; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::cell::Cell; use std::str::FromStr; use std::sync::Arc; @@ -126,6 +129,7 @@ pub struct CanvasState { /// The base URL for resolving CSS image URL values. /// Needed because of https://github.com/servo/servo/issues/17625 base_url: ServoUrl, + origin: ImmutableOrigin, /// Any missing image URLs. missing_image_urls: DomRefCell<Vec<ServoUrl>>, saved_states: DomRefCell<Vec<CanvasContextState>>, @@ -143,6 +147,14 @@ impl CanvasState { .unwrap(); let (ipc_renderer, canvas_id) = receiver.recv().unwrap(); debug!("Done."); + // Worklets always receive a unique origin. This messes with fetching + // cached images in the case of paint worklets, since the image cache + // is keyed on the origin requesting the image data. + let origin = if global.is::<PaintWorkletGlobalScope>() { + global.api_base_url().origin() + } else { + global.origin().immutable().clone() + }; CanvasState { ipc_renderer: ipc_renderer, canvas_id: canvas_id, @@ -152,6 +164,7 @@ impl CanvasState { base_url: global.api_base_url(), missing_image_urls: DomRefCell::new(Vec::new()), saved_states: DomRefCell::new(Vec::new()), + origin, } } @@ -199,8 +212,12 @@ impl CanvasState { } } - fn fetch_image_data(&self, url: ServoUrl) -> Option<(Vec<u8>, Size2D<u32>)> { - let img = match self.request_image_from_cache(url) { + fn fetch_image_data( + &self, + url: ServoUrl, + cors_setting: Option<CorsSettings>, + ) -> Option<(Vec<u8>, Size2D<u32>)> { + let img = match self.request_image_from_cache(url, cors_setting) { ImageResponse::Loaded(img, _) => img, ImageResponse::PlaceholderLoaded(_, _) | ImageResponse::None | @@ -218,10 +235,15 @@ impl CanvasState { Some((image_data, image_size)) } - #[inline] - fn request_image_from_cache(&self, url: ServoUrl) -> ImageResponse { + fn request_image_from_cache( + &self, + url: ServoUrl, + cors_setting: Option<CorsSettings>, + ) -> ImageResponse { let response = self.image_cache.find_image_or_metadata( url.clone(), + self.origin.clone(), + cors_setting, UsePlaceholder::No, CanRequestImages::No, ); @@ -341,13 +363,28 @@ impl CanvasState { // If the image argument is an HTMLImageElement object that is in the broken state, // then throw an InvalidStateError exception let url = image.get_url().ok_or(Error::InvalidState)?; - self.fetch_and_draw_image_data(htmlcanvas, url, sx, sy, sw, sh, dx, dy, dw, dh) + let cors_setting = cors_setting_for_element(image.upcast()); + self.fetch_and_draw_image_data( + htmlcanvas, + url, + cors_setting, + sx, + sy, + sw, + sh, + dx, + dy, + dw, + dh, + ) }, CanvasImageSource::CSSStyleValue(ref value) => { let url = value .get_url(self.base_url.clone()) .ok_or(Error::InvalidState)?; - self.fetch_and_draw_image_data(htmlcanvas, url, sx, sy, sw, sh, dx, dy, dw, dh) + self.fetch_and_draw_image_data( + htmlcanvas, url, None, sx, sy, sw, sh, dx, dy, dw, dh, + ) }, }; @@ -423,6 +460,7 @@ impl CanvasState { &self, canvas: Option<&HTMLCanvasElement>, url: ServoUrl, + cors_setting: Option<CorsSettings>, sx: f64, sy: f64, sw: Option<f64>, @@ -433,7 +471,9 @@ impl CanvasState { dh: Option<f64>, ) -> ErrorResult { debug!("Fetching image {}.", url); - let (mut image_data, image_size) = self.fetch_image_data(url).ok_or(Error::InvalidState)?; + let (mut image_data, image_size) = self + .fetch_image_data(url, cors_setting) + .ok_or(Error::InvalidState)?; pixels::rgba8_premultiply_inplace(&mut image_data); let image_size = image_size.to_f64(); @@ -776,7 +816,9 @@ impl CanvasState { // then throw an InvalidStateError exception image .get_url() - .and_then(|url| self.fetch_image_data(url)) + .and_then(|url| { + self.fetch_image_data(url, cors_setting_for_element(image.upcast())) + }) .ok_or(Error::InvalidState)? }, CanvasImageSource::HTMLCanvasElement(ref canvas) => { @@ -788,7 +830,7 @@ impl CanvasState { }, CanvasImageSource::CSSStyleValue(ref value) => value .get_url(self.base_url.clone()) - .and_then(|url| self.fetch_image_data(url)) + .and_then(|url| self.fetch_image_data(url, None)) .ok_or(Error::InvalidState)?, }; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4b16db4699e..baf4fcd0878 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -35,7 +35,7 @@ use crate::dom::create::create_element; use crate::dom::customelementregistry::{ CallbackReaction, CustomElementDefinition, CustomElementReaction, CustomElementState, }; -use crate::dom::document::{Document, LayoutDocumentHelpers}; +use crate::dom::document::{determine_policy_for_token, Document, LayoutDocumentHelpers}; use crate::dom::documentfragment::DocumentFragment; use crate::dom::domrect::DOMRect; use crate::dom::domtokenlist::DOMTokenList; @@ -97,6 +97,7 @@ use js::jsapi::Heap; use js::jsval::JSVal; use msg::constellation_msg::InputMethodType; use net_traits::request::CorsSettings; +use net_traits::ReferrerPolicy; use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowGoal; use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; @@ -3606,7 +3607,14 @@ pub fn set_cross_origin_attribute(element: &Element, value: Option<DOMString>) { } } -pub fn cors_setting_for_element(element: &Element) -> Option<CorsSettings> { +pub(crate) fn referrer_policy_for_element(element: &Element) -> Option<ReferrerPolicy> { + element + .get_attribute_by_name(DOMString::from_string(String::from("referrerpolicy"))) + .and_then(|attribute: DomRoot<Attr>| determine_policy_for_token(&attribute.Value())) + .or_else(|| document_from_node(element).get_referrer_policy()) +} + +pub(crate) fn cors_setting_for_element(element: &Element) -> Option<CorsSettings> { reflect_cross_origin_attribute(element).map_or(None, |attr| match &*attr { "anonymous" => Some(CorsSettings::Anonymous), "use-credentials" => Some(CorsSettings::UseCredentials), diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 02283a3c190..92eb2c2f414 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -18,7 +18,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::messageevent::MessageEvent; use crate::dom::performanceresourcetiming::InitiatorType; -use crate::fetch::FetchCanceller; +use crate::fetch::{create_a_potential_CORS_request, FetchCanceller}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use crate::task_source::{TaskSource, TaskSourceName}; use crate::timers::OneshotTimerCallback; @@ -31,8 +31,7 @@ use ipc_channel::router::ROUTER; use js::conversions::ToJSValConvertible; use js::jsval::UndefinedValue; use mime::{self, Mime}; -use net_traits::request::{CacheMode, CorsSettings, CredentialsMode}; -use net_traits::request::{RequestBuilder, RequestMode}; +use net_traits::request::{CacheMode, CorsSettings, Destination, RequestBuilder}; use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata}; use net_traits::{FetchResponseListener, FetchResponseMsg, NetworkError}; use net_traits::{ResourceFetchTiming, ResourceTimingType}; @@ -516,17 +515,14 @@ impl EventSource { }; // Step 8 // TODO: Step 9 set request's client settings - let mut request = RequestBuilder::new(url_record) - .origin(global.origin().immutable().clone()) - .pipeline_id(Some(global.pipeline_id())) - // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request - .use_url_credentials(true) - .mode(RequestMode::CorsMode) - .credentials_mode(if cors_attribute_state == CorsSettings::Anonymous { - CredentialsMode::CredentialsSameOrigin - } else { - CredentialsMode::Include - }); + let mut request = create_a_potential_CORS_request( + url_record, + Destination::None, + Some(cors_attribute_state), + Some(true), + ) + .origin(global.origin().immutable().clone()) + .pipeline_id(Some(global.pipeline_id())); // Step 10 // TODO(eijebong): Replace once typed headers allow it diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index cb197a054f3..c5b3fb51362 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::activation::Activatable; -use crate::dom::attr::Attr; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use crate::dom::bindings::codegen::Bindings::HTMLAnchorElementBinding; @@ -14,10 +13,9 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::str::{DOMString, USVString}; -use crate::dom::document::determine_policy_for_token; use crate::dom::document::Document; use crate::dom::domtokenlist::DOMTokenList; -use crate::dom::element::Element; +use crate::dom::element::{referrer_policy_for_element, Element}; use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; @@ -669,9 +667,7 @@ pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) { }; // Step 12. - let referrer_policy = subject - .get_attribute_by_name(DOMString::from_string(String::from("referrerpolicy"))) - .and_then(|attribute: DomRoot<Attr>| (determine_policy_for_token(&attribute.Value()))); + let referrer_policy = referrer_policy_for_element(subject); // Step 13 let referrer = match subject.get_attribute(&ns!(), &local_name!("rel")) { diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 1c07a88cc1c..9e638539995 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -442,12 +442,19 @@ pub mod utils { use crate::dom::window::Window; use net_traits::image_cache::CanRequestImages; use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, UsePlaceholder}; + use net_traits::request::CorsSettings; use servo_url::ServoUrl; - pub fn request_image_from_cache(window: &Window, url: ServoUrl) -> ImageResponse { + pub fn request_image_from_cache( + window: &Window, + url: ServoUrl, + cors_setting: Option<CorsSettings>, + ) -> ImageResponse { let image_cache = window.image_cache(); let response = image_cache.find_image_or_metadata( url.into(), + window.origin().immutable().clone(), + cors_setting, UsePlaceholder::No, CanRequestImages::No, ); diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 14911650be6..525f35d3e95 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -20,6 +20,7 @@ use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::document::Document; +use crate::dom::element::{cors_setting_for_element, referrer_policy_for_element}; use crate::dom::element::{reflect_cross_origin_attribute, set_cross_origin_attribute}; use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; use crate::dom::event::Event; @@ -40,6 +41,7 @@ use crate::dom::performanceresourcetiming::InitiatorType; use crate::dom::values::UNSIGNED_LONG_MAX; use crate::dom::virtualmethods::VirtualMethods; use crate::dom::window::Window; +use crate::fetch::create_a_potential_CORS_request; use crate::image_listener::{add_cache_listener_for_element, ImageCacheListener}; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; @@ -56,11 +58,11 @@ use mime::{self, Mime}; use msg::constellation_msg::PipelineId; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache::UsePlaceholder; -use net_traits::image_cache::{CanRequestImages, ImageCache, ImageOrMetadataAvailable}; +use net_traits::image_cache::{CanRequestImages, CorsStatus, ImageCache, ImageOrMetadataAvailable}; use net_traits::image_cache::{ImageResponder, ImageResponse, ImageState, PendingImageId}; -use net_traits::request::RequestBuilder; +use net_traits::request::{CorsSettings, Destination, Initiator, RequestBuilder}; use net_traits::{FetchMetadata, FetchResponseListener, FetchResponseMsg, NetworkError}; -use net_traits::{ResourceFetchTiming, ResourceTimingType}; +use net_traits::{ReferrerPolicy, ResourceFetchTiming, ResourceTimingType}; use num_traits::ToPrimitive; use servo_url::origin::ImmutableOrigin; use servo_url::origin::MutableOrigin; @@ -184,6 +186,7 @@ impl FetchResponseListener for ImageContext { fn process_request_eof(&mut self) {} fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) { + debug!("got {:?} for {:?}", metadata.as_ref().map(|_| ()), self.url); self.image_cache .notify_pending_response(self.id, FetchResponseMsg::ProcessResponse(metadata.clone())); @@ -263,15 +266,31 @@ impl PreInvoke for ImageContext { } } +#[derive(PartialEq)] +pub(crate) enum FromPictureOrSrcSet { + Yes, + No, +} + +// https://html.spec.whatwg.org/multipage/#update-the-image-data steps 17-20 // This function is also used to prefetch an image in `script::dom::servoparser::prefetch`. pub(crate) fn image_fetch_request( img_url: ServoUrl, origin: ImmutableOrigin, pipeline_id: PipelineId, + cors_setting: Option<CorsSettings>, + referrer_policy: Option<ReferrerPolicy>, + from_picture_or_srcset: FromPictureOrSrcSet, ) -> RequestBuilder { - RequestBuilder::new(img_url) - .origin(origin) - .pipeline_id(Some(pipeline_id)) + let mut request = + create_a_potential_CORS_request(img_url, Destination::Image, cors_setting, None) + .origin(origin) + .pipeline_id(Some(pipeline_id)) + .referrer_policy(referrer_policy); + if from_picture_or_srcset == FromPictureOrSrcSet::Yes { + request = request.initiator(Initiator::ImageSet); + } + request } impl HTMLImageElement { @@ -281,6 +300,8 @@ impl HTMLImageElement { let image_cache = window.image_cache(); let response = image_cache.find_image_or_metadata( img_url.clone().into(), + window.origin().immutable().clone(), + cors_setting_for_element(self.upcast()), UsePlaceholder::Yes, CanRequestImages::Yes, ); @@ -343,6 +364,13 @@ impl HTMLImageElement { img_url.clone(), document.origin().immutable().clone(), document.global().pipeline_id(), + cors_setting_for_element(self.upcast()), + referrer_policy_for_element(self.upcast()), + if Self::uses_srcset_or_picture(self.upcast()) { + FromPictureOrSrcSet::Yes + } else { + FromPictureOrSrcSet::No + }, ); // This is a background load because the load blocker already fulfills the @@ -907,6 +935,8 @@ impl HTMLImageElement { let image_cache = window.image_cache(); let response = image_cache.find_image_or_metadata( img_url.clone().into(), + window.origin().immutable().clone(), + cors_setting_for_element(self.upcast()), UsePlaceholder::No, CanRequestImages::No, ); @@ -1062,6 +1092,8 @@ impl HTMLImageElement { // Step 14 let response = image_cache.find_image_or_metadata( img_url.clone().into(), + window.origin().immutable().clone(), + cors_setting_for_element(self.upcast()), UsePlaceholder::No, CanRequestImages::Yes, ); @@ -1268,6 +1300,10 @@ impl HTMLImageElement { } pub fn same_origin(&self, origin: &MutableOrigin) -> bool { + if let Some(ref image) = self.current_request.borrow().image { + return image.cors_status == CorsStatus::Safe; + } + self.current_request .borrow() .final_url diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 398a3ad40f1..13c5cd126c7 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -58,7 +58,7 @@ use crate::dom::url::URL; use crate::dom::videotrack::VideoTrack; use crate::dom::videotracklist::VideoTrackList; use crate::dom::virtualmethods::VirtualMethods; -use crate::fetch::FetchCanceller; +use crate::fetch::{create_a_potential_CORS_request, FetchCanceller}; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use crate::script_thread::ScriptThread; @@ -74,7 +74,7 @@ use ipc_channel::router::ROUTER; use media::{glplayer_channel, GLPlayerMsg, GLPlayerMsgForward}; use net_traits::image::base::Image; use net_traits::image_cache::ImageResponse; -use net_traits::request::{CredentialsMode, Destination, Referrer, RequestBuilder, RequestMode}; +use net_traits::request::{Destination, Referrer}; use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, Metadata}; use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType}; use script_layout_interface::HTMLMediaData; @@ -830,16 +830,9 @@ impl HTMLMediaElement { None => self.blob_url.borrow().as_ref().unwrap().clone(), }; - let request = RequestBuilder::new(url.clone()) + let cors_setting = cors_setting_for_element(self.upcast()); + let request = create_a_potential_CORS_request(url.clone(), destination, cors_setting, None) .headers(headers) - .destination(destination) - .credentials_mode(CredentialsMode::Include) - // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request - .mode(match cors_setting_for_element(self.upcast::<Element>()) { - Some(_) => RequestMode::CorsMode, - None => RequestMode::NoCors, - }) - .use_url_credentials(true) .origin(document.origin().immutable().clone()) .pipeline_id(Some(self.global().pipeline_id())) .referrer(Some(Referrer::ReferrerUrl(document.url()))) diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 4d2cf061804..1bd0101c03d 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -25,6 +25,7 @@ use crate::dom::node::{document_from_node, window_from_node}; use crate::dom::node::{BindContext, ChildrenMutation, CloneChildrenFlag, Node}; use crate::dom::performanceresourcetiming::InitiatorType; use crate::dom::virtualmethods::VirtualMethods; +use crate::fetch::create_a_potential_CORS_request; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; use dom_struct::dom_struct; use encoding_rs::Encoding; @@ -33,9 +34,7 @@ use ipc_channel::ipc; use ipc_channel::router::ROUTER; use js::jsval::UndefinedValue; use msg::constellation_msg::PipelineId; -use net_traits::request::{ - CorsSettings, CredentialsMode, Destination, Referrer, RequestBuilder, RequestMode, -}; +use net_traits::request::{CorsSettings, Destination, Referrer, RequestBuilder}; use net_traits::ReferrerPolicy; use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError}; use net_traits::{ResourceFetchTiming, ResourceTimingType}; @@ -306,20 +305,7 @@ pub(crate) fn script_fetch_request( referrer_policy: Option<ReferrerPolicy>, integrity_metadata: String, ) -> RequestBuilder { - RequestBuilder::new(url) - .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, - }) + create_a_potential_CORS_request(url, Destination::Script, cors_setting, None) .origin(origin) .pipeline_id(Some(pipeline_id)) .referrer(Some(referrer)) diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index bca18c35a2b..55990c1ffe5 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -159,6 +159,8 @@ impl HTMLVideoElement { let image_cache = window.image_cache(); let response = image_cache.find_image_or_metadata( poster_url.clone().into(), + window.origin().immutable().clone(), + None, UsePlaceholder::No, CanRequestImages::Yes, ); diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs index a2977cc15b1..716be8b0f51 100644 --- a/components/script/dom/servoparser/prefetch.rs +++ b/components/script/dom/servoparser/prefetch.rs @@ -4,8 +4,8 @@ use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::trace::JSTraceable; -use crate::dom::document::Document; -use crate::dom::htmlimageelement::image_fetch_request; +use crate::dom::document::{determine_policy_for_token, Document}; +use crate::dom::htmlimageelement::{image_fetch_request, FromPictureOrSrcSet}; use crate::dom::htmlscriptelement::script_fetch_request; use crate::stylesheet_loader::stylesheet_fetch_request; use html5ever::buffer_queue::BufferQueue; @@ -123,7 +123,14 @@ impl TokenSink for PrefetchSink { (TagKind::StartTag, local_name!("img")) if self.prefetching => { if let Some(url) = self.get_url(tag, local_name!("src")) { debug!("Prefetch {} {}", tag.name, url); - let request = image_fetch_request(url, self.origin.clone(), self.pipeline_id); + let request = image_fetch_request( + url, + self.origin.clone(), + self.pipeline_id, + self.get_cors_settings(tag, local_name!("crossorigin")), + self.get_referrer_policy(tag, LocalName::from("referrerpolicy")), + FromPictureOrSrcSet::No, + ); let _ = self .resource_threads .send(CoreResourceMsg::Fetch(request, FetchChannels::Prefetch)); @@ -137,6 +144,8 @@ impl TokenSink for PrefetchSink { debug!("Prefetch {} {}", tag.name, url); let cors_setting = self.get_cors_settings(tag, local_name!("crossorigin")); + let referrer_policy = + self.get_referrer_policy(tag, LocalName::from("referrerpolicy")); let integrity_metadata = self .get_attr(tag, local_name!("integrity")) .map(|attr| String::from(&attr.value)) @@ -147,7 +156,7 @@ impl TokenSink for PrefetchSink { self.origin.clone(), self.pipeline_id, self.referrer.clone(), - self.referrer_policy, + referrer_policy, integrity_metadata, ); let _ = self @@ -191,6 +200,12 @@ impl PrefetchSink { ServoUrl::parse_with_base(Some(base), &attr.value).ok() } + fn get_referrer_policy(&self, tag: &Tag, name: LocalName) -> Option<ReferrerPolicy> { + self.get_attr(tag, name) + .and_then(|attr| determine_policy_for_token(&*attr.value)) + .or(self.referrer_policy) + } + fn get_cors_settings(&self, tag: &Tag, name: LocalName) -> Option<CorsSettings> { let crossorigin = self.get_attr(tag, name)?; if crossorigin.value.eq_ignore_ascii_case("anonymous") { diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index f8350759dd8..d6d46eee0ef 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -19,6 +19,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomOnceCell, DomRoot, LayoutDom, MutNullableDom}; use crate::dom::bindings::str::DOMString; +use crate::dom::element::cors_setting_for_element; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::htmlcanvaselement::utils as canvas_utils; use crate::dom::htmlcanvaselement::HTMLCanvasElement; @@ -576,13 +577,15 @@ impl WebGLRenderingContext { }; let window = window_from_node(&*self.canvas); - - let img = match canvas_utils::request_image_from_cache(&window, img_url) { - ImageResponse::Loaded(img, _) => img, - ImageResponse::PlaceholderLoaded(_, _) | - ImageResponse::None | - ImageResponse::MetadataLoaded(_) => return Ok(None), - }; + let cors_setting = cors_setting_for_element(image.upcast()); + + let img = + match canvas_utils::request_image_from_cache(&window, img_url, cors_setting) { + ImageResponse::Loaded(img, _) => img, + ImageResponse::PlaceholderLoaded(_, _) | + ImageResponse::None | + ImageResponse::MetadataLoaded(_) => return Ok(None), + }; let size = Size2D::new(img.width, img.height); |