diff options
Diffstat (limited to 'components/shared')
-rw-r--r-- | components/shared/base/id.rs | 5 | ||||
-rw-r--r-- | components/shared/compositing/display_list.rs | 154 | ||||
-rw-r--r-- | components/shared/compositing/lib.rs | 2 | ||||
-rw-r--r-- | components/shared/compositing/tests/compositor.rs | 43 | ||||
-rw-r--r-- | components/shared/constellation/lib.rs | 2 | ||||
-rw-r--r-- | components/shared/constellation/structured_data/mod.rs | 4 | ||||
-rw-r--r-- | components/shared/constellation/structured_data/serializable.rs | 6 | ||||
-rw-r--r-- | components/shared/constellation/structured_data/transferable.rs | 10 | ||||
-rw-r--r-- | components/shared/embedder/resources.rs | 4 | ||||
-rw-r--r-- | components/shared/net/Cargo.toml | 1 | ||||
-rw-r--r-- | components/shared/net/fetch/headers.rs | 93 | ||||
-rw-r--r-- | components/shared/net/pub_domains.rs | 8 | ||||
-rw-r--r-- | components/shared/net/response.rs | 10 | ||||
-rw-r--r-- | components/shared/net/storage_thread.rs | 4 |
14 files changed, 264 insertions, 82 deletions
diff --git a/components/shared/base/id.rs b/components/shared/base/id.rs index cc4ad947494..b6ad1b3de9b 100644 --- a/components/shared/base/id.rs +++ b/components/shared/base/id.rs @@ -17,7 +17,7 @@ use malloc_size_of::MallocSizeOfOps; use malloc_size_of_derive::MallocSizeOf; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; -use webrender_api::{ExternalScrollId, PipelineId as WebRenderPipelineId, SpatialId}; +use webrender_api::{ExternalScrollId, PipelineId as WebRenderPipelineId}; /// Asserts the size of a type at compile time. macro_rules! size_of_test { @@ -397,7 +397,4 @@ pub const TEST_WEBVIEW_ID: WebViewId = WebViewId(TEST_BROWSING_CONTEXT_ID); pub struct ScrollTreeNodeId { /// The index of this scroll tree node in the tree's array of nodes. pub index: usize, - - /// The WebRender spatial id of this scroll tree node. - pub spatial_id: SpatialId, } diff --git a/components/shared/compositing/display_list.rs b/components/shared/compositing/display_list.rs index 6aa822cb145..4fb0d5e94db 100644 --- a/components/shared/compositing/display_list.rs +++ b/components/shared/compositing/display_list.rs @@ -6,11 +6,17 @@ use base::id::ScrollTreeNodeId; use embedder_traits::Cursor; +use euclid::SideOffsets2D; use malloc_size_of_derive::MallocSizeOf; use serde::{Deserialize, Serialize}; use style::values::specified::Overflow; -use webrender_api::units::{LayoutSize, LayoutVector2D}; -use webrender_api::{Epoch, ExternalScrollId, PipelineId, ScrollLocation, SpatialId}; +use webrender_api::units::{ + LayoutPixel, LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, +}; +use webrender_api::{ + Epoch, ExternalScrollId, PipelineId, ReferenceFrameKind, ScrollLocation, SpatialId, + StickyOffsetBounds, TransformStyle, +}; /// The scroll sensitivity of a scroll node in a particular axis ie whether it can be scrolled due to /// input events and script events or only script events. @@ -56,6 +62,29 @@ pub struct HitTestInfo { pub scroll_tree_node: ScrollTreeNodeId, } +#[derive(Debug, Deserialize, Serialize)] +pub enum SpatialTreeNodeInfo { + ReferenceFrame(ReferenceFrameNodeInfo), + Scroll(ScrollableNodeInfo), + Sticky(StickyNodeInfo), +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct StickyNodeInfo { + pub frame_rect: LayoutRect, + pub margins: SideOffsets2D<Option<f32>, LayoutPixel>, + pub vertical_offset_bounds: StickyOffsetBounds, + pub horizontal_offset_bounds: StickyOffsetBounds, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct ReferenceFrameNodeInfo { + pub origin: LayoutPoint, + pub transform_style: TransformStyle, + pub transform: LayoutTransform, + pub kind: ReferenceFrameKind, +} + /// Data stored for nodes in the [ScrollTree] that actually scroll, /// as opposed to reference frames and sticky nodes which do not. #[derive(Debug, Deserialize, Serialize)] @@ -64,8 +93,11 @@ pub struct ScrollableNodeInfo { /// it between successive re-layouts. pub external_id: ExternalScrollId, - /// Amount that this `ScrollableNode` can scroll in both directions. - pub scrollable_size: LayoutSize, + /// The content rectangle for this scroll node; + pub content_rect: LayoutRect, + + /// The clip rectange for this scroll node. + pub clip_rect: LayoutRect, /// Whether this `ScrollableNode` is sensitive to input events. pub scroll_sensitivity: AxesScrollSensitivity, @@ -74,6 +106,12 @@ pub struct ScrollableNodeInfo { pub offset: LayoutVector2D, } +impl ScrollableNodeInfo { + fn scrollable_size(&self) -> LayoutSize { + self.content_rect.size() - self.clip_rect.size() + } +} + #[derive(Debug, Deserialize, Serialize)] /// A node in a tree of scroll nodes. This may either be a scrollable /// node which responds to scroll events or a non-scrollable one. @@ -82,35 +120,51 @@ pub struct ScrollTreeNode { /// None then this is the root node. pub parent: Option<ScrollTreeNodeId>, - /// Scrolling data which will not be None if this is a scrolling node. - pub scroll_info: Option<ScrollableNodeInfo>, + /// The WebRender id, which is filled in when this tree is serialiezd + /// into a WebRender display list. + pub webrender_id: Option<SpatialId>, + + /// Specific information about this node, depending on whether it is a scroll node + /// or a reference frame. + pub info: SpatialTreeNodeInfo, } impl ScrollTreeNode { + /// Get the WebRender [`SpatialId`] for the given [`ScrollNodeId`]. This will + /// panic if [`ScrollTree::build_display_list`] has not been called yet. + pub fn webrender_id(&self) -> SpatialId { + self.webrender_id + .expect("Should have called ScrollTree::build_display_list before querying SpatialId") + } + /// Get the external id of this node. pub fn external_id(&self) -> Option<ExternalScrollId> { - self.scroll_info.as_ref().map(|info| info.external_id) + match self.info { + SpatialTreeNodeInfo::Scroll(ref info) => Some(info.external_id), + _ => None, + } } /// Get the offset id of this node if it applies. pub fn offset(&self) -> Option<LayoutVector2D> { - self.scroll_info.as_ref().map(|info| info.offset) + match self.info { + SpatialTreeNodeInfo::Scroll(ref info) => Some(info.offset), + _ => None, + } } /// Set the offset for this node, returns false if this was a /// non-scrolling node for which you cannot set the offset. pub fn set_offset(&mut self, new_offset: LayoutVector2D) -> bool { - match self.scroll_info { - Some(ref mut info) => { - let scrollable_width = info.scrollable_size.width; - let scrollable_height = info.scrollable_size.height; - - if scrollable_width > 0. { - info.offset.x = (new_offset.x).min(0.0).max(-scrollable_width); + match self.info { + SpatialTreeNodeInfo::Scroll(ref mut info) => { + let scrollable_size = info.scrollable_size(); + if scrollable_size.width > 0. { + info.offset.x = (new_offset.x).min(0.0).max(-scrollable_size.width); } - if scrollable_height > 0. { - info.offset.y = (new_offset.y).min(0.0).max(-scrollable_height); + if scrollable_size.height > 0. { + info.offset.y = (new_offset.y).min(0.0).max(-scrollable_size.height); } true }, @@ -125,9 +179,9 @@ impl ScrollTreeNode { &mut self, scroll_location: ScrollLocation, ) -> Option<(ExternalScrollId, LayoutVector2D)> { - let info = match self.scroll_info { - Some(ref mut data) => data, - None => return None, + let info = match self.info { + SpatialTreeNodeInfo::Scroll(ref mut info) => info, + _ => return None, }; if info.scroll_sensitivity.x != ScrollSensitivity::ScriptAndInputEvents && @@ -148,7 +202,7 @@ impl ScrollTreeNode { return Some((info.external_id, info.offset)); }, ScrollLocation::End => { - let end_pos = -info.scrollable_size.height; + let end_pos = -info.scrollable_size().height; if info.offset.y.round() <= end_pos { // Nothing to do on this layer. return None; @@ -159,20 +213,23 @@ impl ScrollTreeNode { }, }; - let scrollable_width = info.scrollable_size.width; - let scrollable_height = info.scrollable_size.height; + let scrollable_size = info.scrollable_size(); let original_layer_scroll_offset = info.offset; - if scrollable_width > 0. && + if scrollable_size.width > 0. && info.scroll_sensitivity.x == ScrollSensitivity::ScriptAndInputEvents { - info.offset.x = (info.offset.x + delta.x).min(0.0).max(-scrollable_width); + info.offset.x = (info.offset.x + delta.x) + .min(0.0) + .max(-scrollable_size.width); } - if scrollable_height > 0. && + if scrollable_size.height > 0. && info.scroll_sensitivity.y == ScrollSensitivity::ScriptAndInputEvents { - info.offset.y = (info.offset.y + delta.y).min(0.0).max(-scrollable_height); + info.offset.y = (info.offset.y + delta.y) + .min(0.0) + .max(-scrollable_size.height); } if info.offset != original_layer_scroll_offset { @@ -199,16 +256,23 @@ impl ScrollTree { pub fn add_scroll_tree_node( &mut self, parent: Option<&ScrollTreeNodeId>, - spatial_id: SpatialId, - scroll_info: Option<ScrollableNodeInfo>, + info: SpatialTreeNodeInfo, ) -> ScrollTreeNodeId { self.nodes.push(ScrollTreeNode { parent: parent.cloned(), - scroll_info, + webrender_id: None, + info, }); ScrollTreeNodeId { index: self.nodes.len() - 1, - spatial_id, + } + } + + /// Once WebRender display list construction is complete for this [`ScrollTree`], update + /// the mapping of nodes to WebRender [`SpatialId`]s. + pub fn update_mapping(&mut self, mapping: Vec<SpatialId>) { + for (spatial_id, node) in mapping.into_iter().zip(self.nodes.iter_mut()) { + node.webrender_id = Some(spatial_id); } } @@ -218,10 +282,16 @@ impl ScrollTree { } /// Get an immutable reference to the node with the given index. - pub fn get_node(&mut self, id: &ScrollTreeNodeId) -> &ScrollTreeNode { + pub fn get_node(&self, id: &ScrollTreeNodeId) -> &ScrollTreeNode { &self.nodes[id.index] } + /// Get the WebRender [`SpatialId`] for the given [`ScrollNodeId`]. This will + /// panic if [`ScrollTree::build_display_list`] has not been called yet. + pub fn webrender_id(&self, id: &ScrollTreeNodeId) -> SpatialId { + self.get_node(id).webrender_id() + } + /// Scroll the given scroll node on this scroll tree. If the node cannot be scrolled, /// because it isn't a scrollable node or it's already scrolled to the maximum scroll /// extent, try to scroll an ancestor of this node. Returns the node scrolled and the @@ -251,8 +321,10 @@ impl ScrollTree { offset: LayoutVector2D, ) -> bool { for node in self.nodes.iter_mut() { - match node.scroll_info { - Some(ref mut scroll_info) if scroll_info.external_id == external_scroll_id => { + match node.info { + SpatialTreeNodeInfo::Scroll(ref mut scroll_info) + if scroll_info.external_id == external_scroll_id => + { scroll_info.offset = offset; return true; }, @@ -320,15 +392,19 @@ impl CompositorDisplayListInfo { let mut scroll_tree = ScrollTree::default(); let root_reference_frame_id = scroll_tree.add_scroll_tree_node( None, - SpatialId::root_reference_frame(pipeline_id), - None, + SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo { + origin: Default::default(), + transform_style: TransformStyle::Flat, + transform: LayoutTransform::identity(), + kind: ReferenceFrameKind::default(), + }), ); let root_scroll_node_id = scroll_tree.add_scroll_tree_node( Some(&root_reference_frame_id), - SpatialId::root_scroll_node(pipeline_id), - Some(ScrollableNodeInfo { + SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo { external_id: ExternalScrollId(0, pipeline_id), - scrollable_size: content_size - viewport_size, + content_rect: LayoutRect::from_origin_and_size(LayoutPoint::zero(), content_size), + clip_rect: LayoutRect::from_origin_and_size(LayoutPoint::zero(), viewport_size), scroll_sensitivity: viewport_scroll_sensitivity, offset: LayoutVector2D::zero(), }), diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs index a6701ca2b52..061dfe023df 100644 --- a/components/shared/compositing/lib.rs +++ b/components/shared/compositing/lib.rs @@ -236,7 +236,7 @@ impl CrossProcessCompositorApi { pub fn send_display_list( &self, webview_id: WebViewId, - display_list_info: CompositorDisplayListInfo, + display_list_info: &CompositorDisplayListInfo, list: BuiltDisplayList, ) { let (display_list_data, display_list_descriptor) = list.into_data(); diff --git a/components/shared/compositing/tests/compositor.rs b/components/shared/compositing/tests/compositor.rs index 4d2ecfd99c9..e04f1770964 100644 --- a/components/shared/compositing/tests/compositor.rs +++ b/components/shared/compositing/tests/compositor.rs @@ -4,11 +4,12 @@ use base::id::ScrollTreeNodeId; use compositing_traits::display_list::{ - AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo, + AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo, SpatialTreeNodeInfo, + StickyNodeInfo, }; -use euclid::Size2D; +use euclid::{SideOffsets2D, Size2D}; use webrender_api::units::LayoutVector2D; -use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId}; +use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, StickyOffsetBounds}; fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId { let pipeline_id = PipelineId(0, 0); @@ -16,7 +17,6 @@ fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId { let parent = if num_nodes > 0 { Some(ScrollTreeNodeId { index: num_nodes - 1, - spatial_id: SpatialId::new(num_nodes - 1, pipeline_id), }) } else { None @@ -24,10 +24,10 @@ fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId { tree.add_scroll_tree_node( parent.as_ref(), - SpatialId::new(num_nodes, pipeline_id), - Some(ScrollableNodeInfo { + SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo { external_id: ExternalScrollId(num_nodes as u64, pipeline_id), - scrollable_size: Size2D::new(100.0, 100.0), + content_rect: Size2D::new(200.0, 200.0).into(), + clip_rect: Size2D::new(100.0, 100.0).into(), scroll_sensitivity: AxesScrollSensitivity { x: ScrollSensitivity::ScriptAndInputEvents, y: ScrollSensitivity::ScriptAndInputEvents, @@ -78,8 +78,15 @@ fn test_scroll_tree_simple_scroll_chaining() { let pipeline_id = PipelineId(0, 0); let parent_id = add_mock_scroll_node(&mut scroll_tree); - let unscrollable_child_id = - scroll_tree.add_scroll_tree_node(Some(&parent_id), SpatialId::new(1, pipeline_id), None); + let unscrollable_child_id = scroll_tree.add_scroll_tree_node( + Some(&parent_id), + SpatialTreeNodeInfo::Sticky(StickyNodeInfo { + frame_rect: Size2D::new(100.0, 100.0).into(), + margins: SideOffsets2D::default(), + vertical_offset_bounds: StickyOffsetBounds::new(0.0, 0.0), + horizontal_offset_bounds: StickyOffsetBounds::new(0.0, 0.0), + }), + ); let (scrolled_id, offset) = scroll_tree .scroll_node_or_ancestor( @@ -157,16 +164,14 @@ fn test_scroll_tree_chain_through_overflow_hidden() { let pipeline_id = PipelineId(0, 0); let parent_id = add_mock_scroll_node(&mut scroll_tree); let overflow_hidden_id = add_mock_scroll_node(&mut scroll_tree); - scroll_tree - .get_node_mut(&overflow_hidden_id) - .scroll_info - .as_mut() - .map(|info| { - info.scroll_sensitivity = AxesScrollSensitivity { - x: ScrollSensitivity::Script, - y: ScrollSensitivity::Script, - }; - }); + let node = scroll_tree.get_node_mut(&overflow_hidden_id); + + if let SpatialTreeNodeInfo::Scroll(ref mut scroll_node_info) = node.info { + scroll_node_info.scroll_sensitivity = AxesScrollSensitivity { + x: ScrollSensitivity::Script, + y: ScrollSensitivity::Script, + }; + } let (scrolled_id, offset) = scroll_tree .scroll_node_or_ancestor( diff --git a/components/shared/constellation/lib.rs b/components/shared/constellation/lib.rs index d85fbe31bdf..005295000c9 100644 --- a/components/shared/constellation/lib.rs +++ b/components/shared/constellation/lib.rs @@ -152,7 +152,7 @@ pub enum TraversalDirection { } /// A task on the <https://html.spec.whatwg.org/multipage/#port-message-queue> -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] pub struct PortMessageTask { /// The origin of this task. pub origin: ImmutableOrigin, diff --git a/components/shared/constellation/structured_data/mod.rs b/components/shared/constellation/structured_data/mod.rs index 3fb9d0c5f67..81e3849e476 100644 --- a/components/shared/constellation/structured_data/mod.rs +++ b/components/shared/constellation/structured_data/mod.rs @@ -20,7 +20,7 @@ pub use transferable::*; /// A data-holder for serialized data and transferred objects. /// <https://html.spec.whatwg.org/multipage/#structuredserializewithtransfer> -#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)] pub struct StructuredSerializedData { /// Data serialized by SpiderMonkey. pub serialized: Vec<u8>, @@ -32,6 +32,8 @@ pub struct StructuredSerializedData { pub exceptions: Option<HashMap<DomExceptionId, DomException>>, /// Transferred objects. pub ports: Option<HashMap<MessagePortId, MessagePortImpl>>, + /// Transform streams transferred objects. + pub transform_streams: Option<HashMap<MessagePortId, TransformStreamData>>, } impl StructuredSerializedData { diff --git a/components/shared/constellation/structured_data/serializable.rs b/components/shared/constellation/structured_data/serializable.rs index 194f0567c51..22370087665 100644 --- a/components/shared/constellation/structured_data/serializable.rs +++ b/components/shared/constellation/structured_data/serializable.rs @@ -88,7 +88,7 @@ impl Clone for BroadcastMsg { } /// File-based blob -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] pub struct FileBlob { #[ignore_malloc_size_of = "Uuid are hard(not really)"] id: Uuid, @@ -164,7 +164,7 @@ impl BroadcastClone for BlobImpl { } /// The data backing a DOM Blob. -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] pub struct BlobImpl { /// UUID of the blob. blob_id: BlobId, @@ -177,7 +177,7 @@ pub struct BlobImpl { } /// Different backends of Blob -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] pub enum BlobData { /// File-based blob, whose content lives in the net process File(FileBlob), diff --git a/components/shared/constellation/structured_data/transferable.rs b/components/shared/constellation/structured_data/transferable.rs index 528c1e79e65..3210a41a538 100644 --- a/components/shared/constellation/structured_data/transferable.rs +++ b/components/shared/constellation/structured_data/transferable.rs @@ -15,6 +15,12 @@ use strum::EnumIter; use crate::PortMessageTask; +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] +pub struct TransformStreamData { + pub readable: (MessagePortId, MessagePortImpl), + pub writable: (MessagePortId, MessagePortImpl), +} + /// All the DOM interfaces that can be transferred. #[derive(Clone, Copy, Debug, EnumIter)] pub enum Transferrable { @@ -28,7 +34,7 @@ pub enum Transferrable { TransformStream, } -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] enum MessagePortState { /// <https://html.spec.whatwg.org/multipage/#detached> Detached, @@ -42,7 +48,7 @@ enum MessagePortState { Disabled(bool), } -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] /// The data and logic backing the DOM managed MessagePort. pub struct MessagePortImpl { /// The current state of the port. diff --git a/components/shared/embedder/resources.rs b/components/shared/embedder/resources.rs index 830a403698e..28464a95d1a 100644 --- a/components/shared/embedder/resources.rs +++ b/components/shared/embedder/resources.rs @@ -116,7 +116,7 @@ impl Resource { match self { Resource::BluetoothBlocklist => "gatt_blocklist.txt", Resource::DomainList => "public_domains.txt", - Resource::HstsPreloadList => "hsts_preload.json", + Resource::HstsPreloadList => "hsts_preload.fstmap", Resource::BadCertHTML => "badcert.html", Resource::NetErrorHTML => "neterror.html", Resource::RippyPNG => "rippy.png", @@ -155,7 +155,7 @@ fn resources_for_tests() -> Box<dyn ResourceReaderMethods + Sync + Send> { &include_bytes!("../../../resources/public_domains.txt")[..] }, Resource::HstsPreloadList => { - &include_bytes!("../../../resources/hsts_preload.json")[..] + &include_bytes!("../../../resources/hsts_preload.fstmap")[..] }, Resource::BadCertHTML => &include_bytes!("../../../resources/badcert.html")[..], Resource::NetErrorHTML => &include_bytes!("../../../resources/neterror.html")[..], diff --git a/components/shared/net/Cargo.toml b/components/shared/net/Cargo.toml index 79ea936a688..0dfad486455 100644 --- a/components/shared/net/Cargo.toml +++ b/components/shared/net/Cargo.toml @@ -19,6 +19,7 @@ compositing_traits = { workspace = true } content-security-policy = { workspace = true } cookie = { workspace = true } crossbeam-channel = { workspace = true } +data-url = { workspace = true } embedder_traits = { workspace = true } headers = { workspace = true } http = { workspace = true } diff --git a/components/shared/net/fetch/headers.rs b/components/shared/net/fetch/headers.rs index 11bb68d5d0a..5ffd537adf8 100644 --- a/components/shared/net/fetch/headers.rs +++ b/components/shared/net/fetch/headers.rs @@ -3,8 +3,9 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::iter::Peekable; -use std::str::Chars; +use std::str::{Chars, FromStr}; +use data_url::mime::Mime as DataUrlMime; use headers::HeaderMap; /// <https://fetch.spec.whatwg.org/#http-tab-or-space> @@ -184,3 +185,93 @@ fn collect_http_quoted_string(position: &mut Peekable<Chars>, extract_value: boo // Step 6, 7 value } + +/// <https://fetch.spec.whatwg.org/#concept-header-extract-mime-type> +/// This function uses data_url::Mime to parse the MIME Type because +/// mime::Mime does not provide a parser following the Fetch spec +/// see <https://github.com/hyperium/mime/issues/106> +pub fn extract_mime_type_as_dataurl_mime(headers: &HeaderMap) -> Option<DataUrlMime> { + // > 1: Let charset be null. + let mut charset = None; + // > 2: Let essence be null. + let mut essence = String::new(); + // > 3: Let mimeType be null. + let mut mime_type = None; + + // > 4: Let values be the result of getting, decoding, and splitting `Content-Type` + // from headers. + // > 5: If values is null, then return failure. + let headers_values = get_decode_and_split_header_name("content-type", headers)?; + + // > 6: For each value of values: + for header_value in headers_values.iter() { + // > 6.1: Let temporaryMimeType be the result of parsing value. + match DataUrlMime::from_str(header_value) { + // > 6.2: If temporaryMimeType is failure or its essence is "*/*", then continue. + Err(_) => continue, + Ok(temp_mime) => { + let temp_essence = format!("{}/{}", temp_mime.type_, temp_mime.subtype); + + // > 6.2: If temporaryMimeType is failure or its essence is "*/*", then + // continue. + if temp_essence == "*/*" { + continue; + } + + // > 6.3: Set mimeType to temporaryMimeType. + mime_type = Some(DataUrlMime { + type_: temp_mime.type_.to_string(), + subtype: temp_mime.subtype.to_string(), + parameters: temp_mime.parameters.clone(), + }); + + // > 6.4: If mimeType’s essence is not essence, then: + let temp_charset = &temp_mime.get_parameter("charset"); + if temp_essence != essence { + // > 6.4.1: Set charset to null. + // > 6.4.2: If mimeType’s parameters["charset"] exists, then set + // charset to mimeType’s parameters["charset"]. + charset = temp_charset.map(|c| c.to_string()); + // > 6.4.3: Set essence to mimeType’s essence. + essence = temp_essence.to_owned(); + } else { + // > 6.5: Otherwise, if mimeType’s parameters["charset"] does not exist, + // and charset is non-null, set mimeType’s parameters["charset"] to charset. + if temp_charset.is_none() && charset.is_some() { + let DataUrlMime { + type_: t, + subtype: st, + parameters: p, + } = mime_type.unwrap(); + let mut params = p; + params.push(("charset".to_string(), charset.clone().unwrap())); + mime_type = Some(DataUrlMime { + type_: t.to_string(), + subtype: st.to_string(), + parameters: params, + }) + } + } + }, + } + } + + // > 7: If mimeType is null, then return failure. + // > 8: Return mimeType. + mime_type +} + +pub fn extract_mime_type(headers: &HeaderMap) -> Option<Vec<u8>> { + extract_mime_type_as_dataurl_mime(headers).map(|m| format!("{}", m).into_bytes()) +} + +pub fn extract_mime_type_as_mime(headers: &HeaderMap) -> Option<mime::Mime> { + extract_mime_type_as_dataurl_mime(headers).and_then(|mime: DataUrlMime| { + // Try to transform a data-url::mime::Mime into a mime::Mime + let mut mime_as_str = format!("{}/{}", mime.type_, mime.subtype); + for p in mime.parameters { + mime_as_str.push_str(format!("; {}={}", p.0, p.1).as_str()); + } + mime_as_str.parse().ok() + }) +} diff --git a/components/shared/net/pub_domains.rs b/components/shared/net/pub_domains.rs index cbbb2b465b2..6e6f883cd2f 100644 --- a/components/shared/net/pub_domains.rs +++ b/components/shared/net/pub_domains.rs @@ -19,9 +19,11 @@ use std::iter::FromIterator; use std::sync::LazyLock; use embedder_traits::resources::{self, Resource}; +use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; +use malloc_size_of_derive::MallocSizeOf; use servo_url::{Host, ImmutableOrigin, ServoUrl}; -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, MallocSizeOf)] pub struct PubDomainRules { rules: HashSet<String>, wildcards: HashSet<String>, @@ -30,6 +32,10 @@ pub struct PubDomainRules { static PUB_DOMAINS: LazyLock<PubDomainRules> = LazyLock::new(load_pub_domains); +pub fn public_suffix_list_size_of(ops: &mut MallocSizeOfOps) -> usize { + PUB_DOMAINS.size_of(ops) +} + impl<'a> FromIterator<&'a str> for PubDomainRules { fn from_iter<T>(iter: T) -> Self where diff --git a/components/shared/net/response.rs b/components/shared/net/response.rs index f91993ddccb..9a01fbbf965 100644 --- a/components/shared/net/response.rs +++ b/components/shared/net/response.rs @@ -7,7 +7,6 @@ use std::sync::Mutex; use std::sync::atomic::AtomicBool; -use headers::{ContentType, HeaderMapExt}; use http::HeaderMap; use hyper_serde::Serde; use malloc_size_of_derive::MallocSizeOf; @@ -15,6 +14,7 @@ use serde::{Deserialize, Serialize}; use servo_arc::Arc; use servo_url::ServoUrl; +use crate::fetch::headers::extract_mime_type_as_mime; use crate::http_status::HttpStatus; use crate::{ FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy, ResourceFetchTiming, @@ -300,13 +300,7 @@ impl Response { pub fn metadata(&self) -> Result<FetchMetadata, NetworkError> { fn init_metadata(response: &Response, url: &ServoUrl) -> Metadata { let mut metadata = Metadata::default(url.clone()); - metadata.set_content_type( - response - .headers - .typed_get::<ContentType>() - .map(|v| v.into()) - .as_ref(), - ); + metadata.set_content_type(extract_mime_type_as_mime(&response.headers).as_ref()); metadata.location_url.clone_from(&response.location_url); metadata.headers = Some(Serde(response.headers.clone())); metadata.status.clone_from(&response.status); diff --git a/components/shared/net/storage_thread.rs b/components/shared/net/storage_thread.rs index 0253603016e..2ba0aa12445 100644 --- a/components/shared/net/storage_thread.rs +++ b/components/shared/net/storage_thread.rs @@ -4,6 +4,7 @@ use ipc_channel::ipc::IpcSender; use malloc_size_of_derive::MallocSizeOf; +use profile_traits::mem::ReportsChan; use serde::{Deserialize, Serialize}; use servo_url::ServoUrl; @@ -45,4 +46,7 @@ pub enum StorageThreadMsg { /// send a reply when done cleaning up thread resources and then shut it down Exit(IpcSender<()>), + + /// Measure memory used by this thread and send the report over the provided channel. + CollectMemoryReport(ReportsChan), } |