| 
						
						
						
					 | 
				
				 | 
				
					@ -1,12 +1,13 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::fs::{create_dir_all, remove_file, symlink_metadata, File}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::io::prelude::*; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::net::ToSocketAddrs; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use std::time::{Duration, SystemTime}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use rocket::http::ContentType; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use rocket::response::Content; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use rocket::Route; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use reqwest::{header::HeaderMap, Client, Response}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use reqwest::{header::HeaderMap, Client, Response, Url}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					use rocket::http::Cookie; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -60,22 +61,47 @@ fn icon(domain: String) -> Content<Vec<u8>> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return Content(icon_type, FALLBACK_ICON.to_vec()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if let Some(blacklist) = CONFIG.icon_blacklist_regex() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        info!("Icon blacklist enabled: {:#?}", blacklist); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let regex = Regex::new(&blacklist).expect("Valid Regex"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if regex.is_match(&domain) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            warn!("Blacklisted domain: {:#?}", domain); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if check_icon_domain_is_blacklisted(&domain) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        warn!("Domain is blacklisted: {:#?}", domain); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return Content(icon_type, FALLBACK_ICON.to_vec()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let icon = get_icon(&domain); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Content(icon_type, icon) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					fn check_icon_domain_is_blacklisted(domain: &str) -> bool { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let mut is_blacklisted = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if CONFIG.icon_blacklist_non_global_ips() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        is_blacklisted = (domain, 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            .to_socket_addrs() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            .map(|x| { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for ip_port in x { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if !ip_port.ip().is_global() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        warn!("IP {} for domain '{}' is not a global IP!", ip_port.ip(), domain); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                false | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            }) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            .unwrap_or(false); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Skip the regex check if the previous one is true already
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if !is_blacklisted { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if let Some(blacklist) = CONFIG.icon_blacklist_regex() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            let regex = Regex::new(&blacklist).expect("Valid Regex"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if regex.is_match(&domain) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                warn!("Blacklisted domain: {:#?} matched {:#?}", domain, blacklist); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                is_blacklisted = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    is_blacklisted | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					fn get_icon(domain: &str) -> Vec<u8> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let path = format!("{}/{}.png", CONFIG.icon_cache_folder(), domain); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -202,6 +228,7 @@ fn get_icon_url(domain: &str) -> Result<(Vec<Icon>, String), Error> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if let Ok(content) = resp { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // Extract the URL from the respose in case redirects occured (like @ gitlab.com)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let url = content.url().clone(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let raw_cookies = content.headers().get_all("set-cookie"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        cookie_str = raw_cookies | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            .iter() | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -253,6 +280,9 @@ fn get_page(url: &str) -> Result<Response, Error> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					fn get_page_with_cookies(url: &str, cookie_str: &str) -> Result<Response, Error> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if check_icon_domain_is_blacklisted(Url::parse(url).unwrap().host_str().unwrap_or_default()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        err!("Favicon rel linked to a non blacklisted domain!"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    CLIENT | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .get(url) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .header("cookie", cookie_str) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |