geforkt von mirrored/vaultwarden
Embed the icon in the binary, no need to download when it's not going to change
Dieser Commit ist enthalten in:
Ursprung
1b5134dfe2
Commit
172f1770cf
2 geänderte Dateien mit 19 neuen und 42 gelöschten Zeilen
|
@ -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::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::http::ContentType;
|
||||||
|
use rocket::response::Content;
|
||||||
|
use rocket::Route;
|
||||||
|
|
||||||
use reqwest;
|
use reqwest;
|
||||||
|
|
||||||
|
@ -15,13 +15,15 @@ pub fn routes() -> Vec<Route> {
|
||||||
routes![icon]
|
routes![icon]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FALLBACK_ICON: &[u8; 344] = include_bytes!("../static/fallback-icon.png");
|
||||||
|
|
||||||
#[get("/<domain>/icon.png")]
|
#[get("/<domain>/icon.png")]
|
||||||
fn icon(domain: String) -> Content<Vec<u8>> {
|
fn icon(domain: String) -> Content<Vec<u8>> {
|
||||||
let icon_type = ContentType::new("image", "x-icon");
|
let icon_type = ContentType::new("image", "x-icon");
|
||||||
|
|
||||||
// Validate the domain to avoid directory traversal attacks
|
// Validate the domain to avoid directory traversal attacks
|
||||||
if domain.contains('/') || domain.contains("..") {
|
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);
|
let icon = get_icon(&domain);
|
||||||
|
@ -29,7 +31,7 @@ fn icon(domain: String) -> Content<Vec<u8>> {
|
||||||
Content(icon_type, icon)
|
Content(icon_type, icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_icon (domain: &str) -> Vec<u8> {
|
fn get_icon(domain: &str) -> Vec<u8> {
|
||||||
let path = format!("{}/{}.png", CONFIG.icon_cache_folder, domain);
|
let path = format!("{}/{}.png", CONFIG.icon_cache_folder, domain);
|
||||||
|
|
||||||
if let Some(icon) = get_cached_icon(&path) {
|
if let Some(icon) = get_cached_icon(&path) {
|
||||||
|
@ -43,11 +45,11 @@ fn get_icon (domain: &str) -> Vec<u8> {
|
||||||
Ok(icon) => {
|
Ok(icon) => {
|
||||||
save_icon(&path, &icon);
|
save_icon(&path, &icon);
|
||||||
icon
|
icon
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error downloading icon: {:?}", e);
|
error!("Error downloading icon: {:?}", e);
|
||||||
mark_negcache(&path);
|
mark_negcache(&path);
|
||||||
get_fallback_icon()
|
FALLBACK_ICON.to_vec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,12 +57,12 @@ fn get_icon (domain: &str) -> Vec<u8> {
|
||||||
fn get_cached_icon(path: &str) -> Option<Vec<u8>> {
|
fn get_cached_icon(path: &str) -> Option<Vec<u8>> {
|
||||||
// Check for expiration of negatively cached copy
|
// Check for expiration of negatively cached copy
|
||||||
if icon_is_negcached(path) {
|
if icon_is_negcached(path) {
|
||||||
return Some(get_fallback_icon());
|
return Some(FALLBACK_ICON.to_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for expiration of successfully cached copy
|
// Check for expiration of successfully cached copy
|
||||||
if icon_is_expired(path) {
|
if icon_is_expired(path) {
|
||||||
return None
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to read the cached icon, and return it if it exists
|
// 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<bool, Box<Error>> {
|
||||||
fn icon_is_negcached(path: &str) -> bool {
|
fn icon_is_negcached(path: &str) -> bool {
|
||||||
let miss_indicator = path.to_owned() + ".miss";
|
let miss_indicator = path.to_owned() + ".miss";
|
||||||
let expired = file_is_expired(&miss_indicator, CONFIG.icon_cache_negttl);
|
let expired = file_is_expired(&miss_indicator, CONFIG.icon_cache_negttl);
|
||||||
|
|
||||||
match expired {
|
match expired {
|
||||||
// No longer negatively cached, drop the marker
|
// No longer negatively cached, drop the marker
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
match remove_file(&miss_indicator) {
|
if let Err(e) = remove_file(&miss_indicator) {
|
||||||
Ok(_) => {},
|
|
||||||
Err(e) => {
|
|
||||||
error!("Could not remove negative cache indicator for icon {:?}: {:?}", path, e);
|
error!("Could not remove negative cache indicator for icon {:?}: {:?}", path, e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
false
|
false
|
||||||
},
|
}
|
||||||
|
|
||||||
// The marker hasn't expired yet.
|
// The marker hasn't expired yet.
|
||||||
Ok(false) => { true }
|
Ok(false) => true,
|
||||||
|
|
||||||
// The marker is missing or inaccessible in some way.
|
// 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");
|
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<u8> {
|
|
||||||
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![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
BIN
src/static/fallback-icon.png
Normale Datei
BIN
src/static/fallback-icon.png
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 344 B |
Laden …
In neuem Issue referenzieren