Added loading of the links given as url(...) in css files

This commit is contained in:
knidarkness 2019-10-12 12:32:59 +03:00
parent 9c006f3258
commit 5443c0cc3f
3 changed files with 45 additions and 5 deletions

View File

@ -8,7 +8,7 @@ use html5ever::{local_name, namespace_url, ns};
use http::retrieve_asset; use http::retrieve_asset;
use js::attr_is_event_handler; use js::attr_is_event_handler;
use std::default::Default; 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! { lazy_static! {
static ref EMPTY_STRING: String = String::new(); static ref EMPTY_STRING: String = String::new();
@ -127,7 +127,7 @@ pub fn walk_and_embed_assets(
.unwrap_or(EMPTY_STRING.clone()); .unwrap_or(EMPTY_STRING.clone());
let (css_dataurl, _) = retrieve_asset( let (css_dataurl, _) = retrieve_asset(
&href_full_url, &href_full_url,
true, false,
"text/css", "text/css",
opt_user_agent, opt_user_agent,
opt_silent, opt_silent,
@ -135,7 +135,17 @@ pub fn walk_and_embed_assets(
) )
.unwrap_or((EMPTY_STRING.clone(), EMPTY_STRING.clone())); .unwrap_or((EMPTY_STRING.clone(), EMPTY_STRING.clone()));
attr.value.clear(); 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());
} }
} }
} }

View File

@ -45,11 +45,11 @@ pub fn retrieve_asset(
}; };
Ok(( Ok((
data_to_dataurl(&mimetype, &data), if response.status() != 200 { "".to_string() } else { data_to_dataurl(&mimetype, &data) },
response.url().to_string(), response.url().to_string(),
)) ))
} else { } else {
Ok((response.text().unwrap(), response.url().to_string())) Ok((if response.status() != 200 { "".to_string() } else { response.text().unwrap() }, response.url().to_string()))
} }
} }
} }

View File

@ -2,11 +2,13 @@ extern crate base64;
use self::base64::encode; use self::base64::encode;
use regex::Regex; use regex::Regex;
use http::retrieve_asset;
use url::{ParseError, Url}; use url::{ParseError, Url};
lazy_static! { lazy_static! {
static ref HAS_PROTOCOL: Regex = Regex::new(r"^[a-z0-9]+:").unwrap(); static ref HAS_PROTOCOL: Regex = Regex::new(r"^[a-z0-9]+:").unwrap();
static ref REGEX_URL: Regex = Regex::new(r"^https?://").unwrap(); static ref REGEX_URL: Regex = Regex::new(r"^https?://").unwrap();
static ref EMPTY_STRING: String = String::new();
} }
static MAGIC: [[&[u8]; 2]; 19] = [ static MAGIC: [[&[u8]; 2]; 19] = [
@ -80,3 +82,31 @@ pub fn resolve_url(from: &str, to: &str) -> Result<String, ParseError> {
Ok(result) Ok(result)
} }
pub fn resolve_css_imports(css_string: &str, href: &str, opt_user_agent: &str, opt_silent: bool, opt_insecure: bool) -> Result<String, String> {
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())
}