From 5443c0cc3ff0b3a5d9d9d761e13ec90e086e6ca4 Mon Sep 17 00:00:00 2001 From: knidarkness Date: Sat, 12 Oct 2019 12:32:59 +0300 Subject: [PATCH] Added loading of the links given as url(...) in css files --- src/html.rs | 16 +++++++++++++--- src/http.rs | 4 ++-- src/utils.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/html.rs b/src/html.rs index fa10175..1c0f325 100644 --- a/src/html.rs +++ b/src/html.rs @@ -8,7 +8,7 @@ use html5ever::{local_name, namespace_url, ns}; use http::retrieve_asset; use js::attr_is_event_handler; use std::default::Default; -use utils::{data_to_dataurl, is_valid_url, resolve_url, url_has_protocol}; +use utils::{data_to_dataurl, is_valid_url, resolve_url, url_has_protocol, resolve_css_imports}; lazy_static! { static ref EMPTY_STRING: String = String::new(); @@ -127,7 +127,7 @@ pub fn walk_and_embed_assets( .unwrap_or(EMPTY_STRING.clone()); let (css_dataurl, _) = retrieve_asset( &href_full_url, - true, + false, "text/css", opt_user_agent, opt_silent, @@ -135,7 +135,17 @@ pub fn walk_and_embed_assets( ) .unwrap_or((EMPTY_STRING.clone(), EMPTY_STRING.clone())); attr.value.clear(); - attr.value.push_slice(css_dataurl.as_str()); + + let css_resolved = resolve_css_imports( + &css_dataurl, + &href_full_url, + opt_user_agent, + opt_silent, + opt_insecure, + ) + .unwrap_or(css_dataurl); + + attr.value.push_slice(css_resolved.as_str()); } } } diff --git a/src/http.rs b/src/http.rs index 19bf902..a5a9475 100644 --- a/src/http.rs +++ b/src/http.rs @@ -45,11 +45,11 @@ pub fn retrieve_asset( }; Ok(( - data_to_dataurl(&mimetype, &data), + if response.status() != 200 { "".to_string() } else { data_to_dataurl(&mimetype, &data) }, response.url().to_string(), )) } else { - Ok((response.text().unwrap(), response.url().to_string())) + Ok((if response.status() != 200 { "".to_string() } else { response.text().unwrap() }, response.url().to_string())) } } } diff --git a/src/utils.rs b/src/utils.rs index 61a5d83..f93800c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,11 +2,13 @@ extern crate base64; use self::base64::encode; use regex::Regex; +use http::retrieve_asset; use url::{ParseError, Url}; lazy_static! { static ref HAS_PROTOCOL: Regex = Regex::new(r"^[a-z0-9]+:").unwrap(); static ref REGEX_URL: Regex = Regex::new(r"^https?://").unwrap(); + static ref EMPTY_STRING: String = String::new(); } static MAGIC: [[&[u8]; 2]; 19] = [ @@ -80,3 +82,31 @@ pub fn resolve_url(from: &str, to: &str) -> Result { Ok(result) } + +pub fn resolve_css_imports(css_string: &str, href: &str, opt_user_agent: &str, opt_silent: bool, opt_insecure: bool) -> Result { + let mut resolved_css = String::from(css_string); + let re = Regex::new(r###"url\((?:(?:https?|ftp)://)?"?[\w/\-?=%.]+\.[\w/\-?=%.]+"?\)"###).unwrap(); + + for link in re.captures_iter(&css_string) { + let target_link = if link[0].chars().nth(4) == Some('"') { &link[0][5..link[0].len()-2] } else {&link[0][4..link[0].len()-1]}; + let embedded_url = String::from([href, "/../", &target_link.to_string()].concat()); + + let (css_dataurl, _) = retrieve_asset( + &embedded_url, + true, // true + "", + opt_user_agent, + opt_silent, + opt_insecure, + ) + .unwrap_or((EMPTY_STRING.clone(), EMPTY_STRING.clone())); + + let replacement = &["\"", &css_dataurl.replace("\"",&["\\", "\""].concat()).to_string(), "\""].concat(); + let t = resolved_css.replace(&link[0][4..link[0].len() - 1], &replacement).to_string(); + resolved_css = t.clone(); + } + + let encoded_css = data_to_dataurl("text/css", resolved_css.as_bytes()); + + Ok(encoded_css.to_string()) +} \ No newline at end of file