From f0ef7fc0d423a13ac4b7dcd8f9d93b94cbf7eea8 Mon Sep 17 00:00:00 2001 From: Andrius Aucinas Date: Mon, 28 Oct 2019 11:52:14 +0000 Subject: [PATCH] moves resources into a module --- native/src/lib.rs | 2 +- src/blocker.rs | 3 +- src/engine.rs | 3 +- src/lib.rs | 2 - src/redirect_resources.rs | 97 ----------- src/resources.rs | 98 ----------- src/resources/mod.rs | 196 ++++++++++++++++++++++ src/{ => resources}/resource_assembler.rs | 0 tests/live.rs | 2 +- tests/ublock-coverage.rs | 2 +- 10 files changed, 201 insertions(+), 204 deletions(-) delete mode 100644 src/redirect_resources.rs delete mode 100644 src/resources.rs create mode 100644 src/resources/mod.rs rename src/{ => resources}/resource_assembler.rs (100%) diff --git a/native/src/lib.rs b/native/src/lib.rs index 72ab2940..d48160ad 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -11,7 +11,7 @@ use std::path::Path; use adblock::engine::Engine; use adblock::filter_lists; use adblock::resources::Resource; -use adblock::resource_assembler::{assemble_web_accessible_resources, assemble_scriptlet_resources}; +use adblock::resources::resource_assembler::{assemble_web_accessible_resources, assemble_scriptlet_resources}; #[derive(Serialize, Deserialize)] diff --git a/src/blocker.rs b/src/blocker.rs index f8552112..8a83a32f 100644 --- a/src/blocker.rs +++ b/src/blocker.rs @@ -11,8 +11,7 @@ use crate::filters::network::{NetworkFilter, NetworkMatchable, FilterError}; use crate::request::Request; use crate::utils::{fast_hash, Hash}; use crate::optimizer; -use crate::resources::Resource; -use crate::redirect_resources::{RedirectResourceStorage, RedirectResource}; +use crate::resources::{Resource, RedirectResourceStorage, RedirectResource}; use crate::utils; pub struct BlockerOptions { diff --git a/src/engine.rs b/src/engine.rs index 9153b678..5cbf8148 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -3,8 +3,7 @@ use crate::blocker::{Blocker, BlockerError, BlockerOptions, BlockerResult}; use crate::lists::parse_filters; use crate::request::Request; use crate::filters::network::NetworkFilter; -use crate::resources::Resource; -use crate::redirect_resources::{RedirectResource}; +use crate::resources::{Resource, RedirectResource}; use rmps; use flate2::write::GzEncoder; use flate2::read::GzDecoder; diff --git a/src/lib.rs b/src/lib.rs index 1abaa8da..b0511042 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,4 @@ pub mod optimizer; pub mod url_parser; pub mod engine; pub mod filter_lists; -pub mod redirect_resources; pub mod resources; -pub mod resource_assembler; diff --git a/src/redirect_resources.rs b/src/redirect_resources.rs deleted file mode 100644 index 0016ed93..00000000 --- a/src/redirect_resources.rs +++ /dev/null @@ -1,97 +0,0 @@ -use std::collections::HashMap; -use serde::{Deserialize, Serialize}; -use crate::resources::{Resource, ResourceType}; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -pub struct RedirectResource { - pub content_type: String, - pub data: String -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Default)] -pub struct RedirectResourceStorage { - pub resources: HashMap, -} - -impl RedirectResourceStorage { - pub fn from_resources(resources: &[Resource]) -> Self { - let mut redirectable_resources: HashMap = HashMap::new(); - - resources.iter().filter_map(|descriptor| { - if let ResourceType::Mime(ref content_type) = descriptor.kind { - let resource = RedirectResource { - content_type: content_type.clone().into(), - data: descriptor.content.to_owned(), - }; - Some((descriptor.name.to_owned(), descriptor.aliases.to_owned(), resource)) - } else { - None - } - }).for_each(|(name, res_aliases, resource)| { - res_aliases.iter().for_each(|alias| { - redirectable_resources.insert(alias.to_owned(), resource.clone()); - }); - redirectable_resources.insert(name, resource); - }); - - Self { - resources: redirectable_resources, - } - } - - pub fn get_resource(&self, name: &str) -> Option<&RedirectResource> { - self.resources.get(name) - } - - pub fn add_resource(&mut self, resource: Resource) { - if let ResourceType::Mime(content_type) = resource.kind { - let name = resource.name.to_owned(); - let redirect_resource = RedirectResource { - content_type: content_type.into(), - data: resource.content.to_owned(), - }; - resource.aliases.iter().for_each(|alias| { - self.resources.insert(alias.to_owned(), redirect_resource.clone()); - }); - self.resources.insert(name, redirect_resource); - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::resources::MimeType; - - #[test] - fn get_resource_by_name() { - let mut storage = RedirectResourceStorage::default(); - storage.add_resource(Resource { - name: "name.js".to_owned(), - aliases: vec![], - kind: ResourceType::Mime(MimeType::ApplicationJavascript), - content: base64::encode("resource data"), - }); - - assert_eq!(storage.get_resource("name.js"), Some(&RedirectResource { - content_type: "application/javascript".to_owned(), - data: base64::encode("resource data"), - })); - } - - #[test] - fn get_resource_by_alias() { - let mut storage = RedirectResourceStorage::default(); - storage.add_resource(Resource { - name: "name.js".to_owned(), - aliases: vec!["alias.js".to_owned()], - kind: ResourceType::Mime(MimeType::ApplicationJavascript), - content: base64::encode("resource data"), - }); - - assert_eq!(storage.get_resource("alias.js"), Some(&RedirectResource { - content_type: "application/javascript".to_owned(), - data: base64::encode("resource data"), - })); - } -} diff --git a/src/resources.rs b/src/resources.rs deleted file mode 100644 index 84faad90..00000000 --- a/src/resources.rs +++ /dev/null @@ -1,98 +0,0 @@ -use serde::{Serialize, Deserialize}; - -/// Struct representing a resource that can be used by an adblocking engine. -/// -/// - `name`: Represents the primary name of the resource, often a filename -/// -/// - `aliases`: Represents secondary names that can be used to access the resource -/// -/// - `kind`: How to interpret the resource data within `content` -/// -/// - `content`: The resource data, encoded using standard base64 configuration -#[derive(Serialize, Deserialize)] -pub struct Resource { - pub name: String, - pub aliases: Vec, - pub kind: ResourceType, - pub content: String, -} - -/// Different ways that the data within the `content` field of a `Resource` can be interpreted. -/// -/// - `Mime(type)` - interpret the data according to the MIME type represented by `type` -/// -/// - `Template` - interpret the data as a Javascript scriptlet template, with embedded template -/// parameters in the form of `{{1}}`, `{{2}}`, etc. -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -#[serde(rename_all = "lowercase")] -pub enum ResourceType { - Mime(MimeType), - Template, -} - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -#[serde(into = "String")] -#[serde(from = "&str")] -pub enum MimeType { - ImageGif, - TextHtml, - ApplicationJavascript, - AudioMp3, - VideoMp4, - ImagePng, - TextPlain, - Unknown, -} - -impl MimeType { - /// Infers a resource's MIME type according to the extension of its path - pub fn from_extension(resource_path: &str) -> Self { - if let Some(extension_index) = resource_path.rfind('.') { - match &resource_path[extension_index + 1..] { - "gif" => MimeType::ImageGif, - "html" => MimeType::TextHtml, - "js" => MimeType::ApplicationJavascript, - "mp3" => MimeType::AudioMp3, - "mp4" => MimeType::VideoMp4, - "png" => MimeType::ImagePng, - "txt" => MimeType::TextPlain, - _ => { - eprintln!("Unrecognized file extension on: {:?}", resource_path); - MimeType::Unknown - } - } - } else { - return MimeType::Unknown - } - } -} - -impl From<&str> for MimeType { - fn from(v: &str) -> Self { - match v { - "image/gif" => MimeType::ImageGif, - "text/html" => MimeType::TextHtml, - "application/javascript" => MimeType::ApplicationJavascript, - "audio/mp3" => MimeType::AudioMp3, - "video/mp4" => MimeType::VideoMp4, - "image/png" => MimeType::ImagePng, - "text/plain" => MimeType::TextPlain, - _ => MimeType::Unknown, - } - } -} - -impl From for String { - fn from(v: MimeType) -> Self { - match v { - MimeType::ImageGif => "image/gif", - MimeType::TextHtml => "text/html", - MimeType::ApplicationJavascript => "application/javascript", - MimeType::AudioMp3 => "audio/mp3", - MimeType::VideoMp4 => "video/mp4", - MimeType::ImagePng => "image/png", - MimeType::TextPlain => "text/plain", - MimeType::Unknown => "application/octet-stream", - }.to_owned() - } -} diff --git a/src/resources/mod.rs b/src/resources/mod.rs new file mode 100644 index 00000000..a51bda8a --- /dev/null +++ b/src/resources/mod.rs @@ -0,0 +1,196 @@ +pub mod resource_assembler; + +use serde::{Serialize, Deserialize}; +use std::collections::HashMap; + +/// Struct representing a resource that can be used by an adblocking engine. +/// +/// - `name`: Represents the primary name of the resource, often a filename +/// +/// - `aliases`: Represents secondary names that can be used to access the resource +/// +/// - `kind`: How to interpret the resource data within `content` +/// +/// - `content`: The resource data, encoded using standard base64 configuration +#[derive(Serialize, Deserialize)] +pub struct Resource { + pub name: String, + pub aliases: Vec, + pub kind: ResourceType, + pub content: String, +} + +/// Different ways that the data within the `content` field of a `Resource` can be interpreted. +/// +/// - `Mime(type)` - interpret the data according to the MIME type represented by `type` +/// +/// - `Template` - interpret the data as a Javascript scriptlet template, with embedded template +/// parameters in the form of `{{1}}`, `{{2}}`, etc. +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum ResourceType { + Mime(MimeType), + Template, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(into = "String")] +#[serde(from = "&str")] +pub enum MimeType { + ImageGif, + TextHtml, + ApplicationJavascript, + AudioMp3, + VideoMp4, + ImagePng, + TextPlain, + Unknown, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +pub struct RedirectResource { + pub content_type: String, + pub data: String +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Default)] +pub struct RedirectResourceStorage { + pub resources: HashMap, +} + + +impl MimeType { + /// Infers a resource's MIME type according to the extension of its path + pub fn from_extension(resource_path: &str) -> Self { + if let Some(extension_index) = resource_path.rfind('.') { + match &resource_path[extension_index + 1..] { + "gif" => MimeType::ImageGif, + "html" => MimeType::TextHtml, + "js" => MimeType::ApplicationJavascript, + "mp3" => MimeType::AudioMp3, + "mp4" => MimeType::VideoMp4, + "png" => MimeType::ImagePng, + "txt" => MimeType::TextPlain, + _ => { + eprintln!("Unrecognized file extension on: {:?}", resource_path); + MimeType::Unknown + } + } + } else { + return MimeType::Unknown + } + } +} + +impl RedirectResourceStorage { + pub fn from_resources(resources: &[Resource]) -> Self { + let mut redirectable_resources: HashMap = HashMap::new(); + + resources.iter().filter_map(|descriptor| { + if let ResourceType::Mime(ref content_type) = descriptor.kind { + let resource = RedirectResource { + content_type: content_type.clone().into(), + data: descriptor.content.to_owned(), + }; + Some((descriptor.name.to_owned(), descriptor.aliases.to_owned(), resource)) + } else { + None + } + }).for_each(|(name, res_aliases, resource)| { + res_aliases.iter().for_each(|alias| { + redirectable_resources.insert(alias.to_owned(), resource.clone()); + }); + redirectable_resources.insert(name, resource); + }); + + Self { + resources: redirectable_resources, + } + } + + pub fn get_resource(&self, name: &str) -> Option<&RedirectResource> { + self.resources.get(name) + } + + pub fn add_resource(&mut self, resource: Resource) { + if let ResourceType::Mime(content_type) = resource.kind { + let name = resource.name.to_owned(); + let redirect_resource = RedirectResource { + content_type: content_type.into(), + data: resource.content.to_owned(), + }; + resource.aliases.iter().for_each(|alias| { + self.resources.insert(alias.to_owned(), redirect_resource.clone()); + }); + self.resources.insert(name, redirect_resource); + } + } +} + +impl From<&str> for MimeType { + fn from(v: &str) -> Self { + match v { + "image/gif" => MimeType::ImageGif, + "text/html" => MimeType::TextHtml, + "application/javascript" => MimeType::ApplicationJavascript, + "audio/mp3" => MimeType::AudioMp3, + "video/mp4" => MimeType::VideoMp4, + "image/png" => MimeType::ImagePng, + "text/plain" => MimeType::TextPlain, + _ => MimeType::Unknown, + } + } +} + +impl From for String { + fn from(v: MimeType) -> Self { + match v { + MimeType::ImageGif => "image/gif", + MimeType::TextHtml => "text/html", + MimeType::ApplicationJavascript => "application/javascript", + MimeType::AudioMp3 => "audio/mp3", + MimeType::VideoMp4 => "video/mp4", + MimeType::ImagePng => "image/png", + MimeType::TextPlain => "text/plain", + MimeType::Unknown => "application/octet-stream", + }.to_owned() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn get_resource_by_name() { + let mut storage = RedirectResourceStorage::default(); + storage.add_resource(Resource { + name: "name.js".to_owned(), + aliases: vec![], + kind: ResourceType::Mime(MimeType::ApplicationJavascript), + content: base64::encode("resource data"), + }); + + assert_eq!(storage.get_resource("name.js"), Some(&RedirectResource { + content_type: "application/javascript".to_owned(), + data: base64::encode("resource data"), + })); + } + + #[test] + fn get_resource_by_alias() { + let mut storage = RedirectResourceStorage::default(); + storage.add_resource(Resource { + name: "name.js".to_owned(), + aliases: vec!["alias.js".to_owned()], + kind: ResourceType::Mime(MimeType::ApplicationJavascript), + content: base64::encode("resource data"), + }); + + assert_eq!(storage.get_resource("alias.js"), Some(&RedirectResource { + content_type: "application/javascript".to_owned(), + data: base64::encode("resource data"), + })); + } +} + diff --git a/src/resource_assembler.rs b/src/resources/resource_assembler.rs similarity index 100% rename from src/resource_assembler.rs rename to src/resources/resource_assembler.rs diff --git a/tests/live.rs b/tests/live.rs index c5d99e20..9f365e3e 100644 --- a/tests/live.rs +++ b/tests/live.rs @@ -4,7 +4,7 @@ extern crate reqwest; use adblock::blocker::{Blocker, BlockerOptions}; use adblock::engine::Engine; use adblock::filters::network::NetworkFilter; -use adblock::resource_assembler::assemble_web_accessible_resources; +use adblock::resources::resource_assembler::assemble_web_accessible_resources; use serde::{Deserialize}; use std::fs::File; diff --git a/tests/ublock-coverage.rs b/tests/ublock-coverage.rs index d2f72d4a..b4ffdd70 100644 --- a/tests/ublock-coverage.rs +++ b/tests/ublock-coverage.rs @@ -108,7 +108,7 @@ fn check_specific_rules() { let mut engine = Engine::from_rules_debug(&[ String::from("||cdn.taboola.com/libtrc/*/loader.js$script,redirect=noopjs,important,domain=cnet.com"), ]); - let resources = adblock::resource_assembler::assemble_web_accessible_resources( + let resources = adblock::resources::resource_assembler::assemble_web_accessible_resources( Path::new("data/test/fake-uBO-files/web_accessible_resources"), Path::new("data/test/fake-uBO-files/redirect-engine.js") );