From 172f1770cfd927d16e55383a321455e0f41d4e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Wed, 19 Dec 2018 00:57:45 +0100 Subject: [PATCH] Embed the icon in the binary, no need to download when it's not going to change --- src/api/icons.rs | 61 +++++++++++------------------------ src/static/fallback-icon.png | Bin 0 -> 344 bytes 2 files changed, 19 insertions(+), 42 deletions(-) create mode 100644 src/static/fallback-icon.png diff --git a/src/api/icons.rs b/src/api/icons.rs index 517900fa..8680600f 100644 --- a/src/api/icons.rs +++ b/src/api/icons.rs @@ -1,11 +1,11 @@ -use std::io::prelude::*; -use std::fs::{symlink_metadata, create_dir_all, remove_file, File}; -use std::time::SystemTime; use std::error::Error; +use std::fs::{create_dir_all, remove_file, symlink_metadata, File}; +use std::io::prelude::*; +use std::time::SystemTime; -use rocket::Route; -use rocket::response::Content; use rocket::http::ContentType; +use rocket::response::Content; +use rocket::Route; use reqwest; @@ -15,13 +15,15 @@ pub fn routes() -> Vec { routes![icon] } +const FALLBACK_ICON: &[u8; 344] = include_bytes!("../static/fallback-icon.png"); + #[get("//icon.png")] fn icon(domain: String) -> Content> { let icon_type = ContentType::new("image", "x-icon"); // Validate the domain to avoid directory traversal attacks if domain.contains('/') || domain.contains("..") { - return Content(icon_type, get_fallback_icon()); + return Content(icon_type, FALLBACK_ICON.to_vec()); } let icon = get_icon(&domain); @@ -29,7 +31,7 @@ fn icon(domain: String) -> Content> { Content(icon_type, icon) } -fn get_icon (domain: &str) -> Vec { +fn get_icon(domain: &str) -> Vec { let path = format!("{}/{}.png", CONFIG.icon_cache_folder, domain); if let Some(icon) = get_cached_icon(&path) { @@ -43,11 +45,11 @@ fn get_icon (domain: &str) -> Vec { Ok(icon) => { save_icon(&path, &icon); icon - }, + } Err(e) => { error!("Error downloading icon: {:?}", e); mark_negcache(&path); - get_fallback_icon() + FALLBACK_ICON.to_vec() } } } @@ -55,12 +57,12 @@ fn get_icon (domain: &str) -> Vec { fn get_cached_icon(path: &str) -> Option> { // Check for expiration of negatively cached copy if icon_is_negcached(path) { - return Some(get_fallback_icon()); + return Some(FALLBACK_ICON.to_vec()); } // Check for expiration of successfully cached copy if icon_is_expired(path) { - return None + return None; } // Try to read the cached icon, and return it if it exists @@ -86,23 +88,19 @@ fn file_is_expired(path: &str, ttl: u64) -> Result> { fn icon_is_negcached(path: &str) -> bool { let miss_indicator = path.to_owned() + ".miss"; let expired = file_is_expired(&miss_indicator, CONFIG.icon_cache_negttl); + match expired { // No longer negatively cached, drop the marker Ok(true) => { - match remove_file(&miss_indicator) { - Ok(_) => {}, - Err(e) => { - error!("Could not remove negative cache indicator for icon {:?}: {:?}", path, e); - } + if let Err(e) = remove_file(&miss_indicator) { + error!("Could not remove negative cache indicator for icon {:?}: {:?}", path, e); } false - }, - + } // The marker hasn't expired yet. - Ok(false) => { true } - + Ok(false) => true, // The marker is missing or inaccessible in some way. - Err(_) => { false } + Err(_) => false, } } @@ -143,24 +141,3 @@ fn save_icon(path: &str, icon: &[u8]) { f.write_all(icon).expect("Error writing icon file"); }; } - -const FALLBACK_ICON_URL: &str = "https://raw.githubusercontent.com/bitwarden/web/master/src/images/fa-globe.png"; - -fn get_fallback_icon() -> Vec { - let path = format!("{}/default.png", CONFIG.icon_cache_folder); - - if let Some(icon) = get_cached_icon(&path) { - return icon; - } - - match download_icon(FALLBACK_ICON_URL) { - Ok(icon) => { - save_icon(&path, &icon); - icon - }, - Err(e) => { - error!("Error downloading fallback icon: {:?}", e); - vec![] - } - } -} diff --git a/src/static/fallback-icon.png b/src/static/fallback-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7ba709fd1ae2a7f467f948e9c3a9d69c2da3afef GIT binary patch literal 344 zcmV-e0jK_nP)e( zze@u_5QX2JLgEilk#L|QLO>A_1jR~8Zy{(asnSHW{~8NRI}t2`h5taX3)l%_pGG7g zB4Tj}M+&hB62e$yx$MPP&CGuL_RUI8gzQqIMa%=IL>d;$B((XYj?uv|t{L%xLyR&r zjFV@TI}F2kAwO_1)?7V-(V;+{9>zUEKSRQa=Qzg=fy5TS7zdIlVZ5f6k_aWHsnW$r z2*fRhksFF%ae0hL#2Cgx1~^LrV_R;;52oC4K!I-$DT!xSHdv9kq)W{MjCFCIHa~>y zP|g6xq$qlAlYJr{y~$Jm^+x7aiz^mca*>ODBu|ooz9fk;VvYw(&hq9VRYFR%A^TOM qT%<@$k9RioU*y>2hzfhm`}03sXXm+tt9(EJ0000