From b98bb67b4c1ac573b4b77c09a0e5a557a28d0d9d Mon Sep 17 00:00:00 2001 From: Slatian Date: Sun, 9 Feb 2025 15:43:09 +0100 Subject: [PATCH] Make clippy happy Mostly cleaning up type system crimes from when I was still learning rust: * Abuse of `match` and loops * Non-use of helper functions (`is_empty`, `is_none`) * Use of borrowed owned types (`&String`) * Implementing `Into` instead of `From` --- src/config/dns.rs | 16 +++++----- src/geoip.rs | 19 ++++++------ src/idna.rs | 12 ++++---- src/main.rs | 74 +++++++++++++++++++++++++---------------------- src/simple_dns.rs | 2 +- 5 files changed, 63 insertions(+), 60 deletions(-) diff --git a/src/config/dns.rs b/src/config/dns.rs index d8b4e74..7f4572b 100644 --- a/src/config/dns.rs +++ b/src/config/dns.rs @@ -73,14 +73,14 @@ impl Default for DnsConfig { } } -impl Into for DnsProtocol { - fn into(self) -> Protocol { - match self { - Self::Udp => Protocol::Udp, - Self::Tcp => Protocol::Tcp, - Self::Tls => Protocol::Tls, - Self::Https => Protocol::Https, - Self::Quic => Protocol::Quic, +impl From for Protocol { + fn from(value: DnsProtocol) -> Self { + match value { + DnsProtocol::Udp => Protocol::Udp, + DnsProtocol::Tcp => Protocol::Tcp, + DnsProtocol::Tls => Protocol::Tls, + DnsProtocol::Https => Protocol::Https, + DnsProtocol::Quic => Protocol::Quic, } } } diff --git a/src/geoip.rs b/src/geoip.rs index bfc3821..5e07f71 100644 --- a/src/geoip.rs +++ b/src/geoip.rs @@ -4,7 +4,6 @@ */ use log::{info,warn,error}; -use maxminddb; use maxminddb::geoip2; use parking_lot::RwLock; @@ -56,7 +55,7 @@ pub struct MMDBCarrier { } pub trait QueryLocation { - fn query_location_for_ip(&self, address: &IpAddr, laguages: &Vec<&String>) -> Option; + fn query_location_for_ip(&self, address: &IpAddr, laguages: &[&str]) -> Option; } pub trait QueryAsn { @@ -67,12 +66,12 @@ pub trait QueryAsn { pub fn extract_localized_name( names: &Option>, - languages: &Vec<&String>) + languages: &[&str]) -> Option { match names { Some(names) => { for language in languages { - if let Some(name) = names.get(language.as_str()){ + if let Some(name) = names.get(language){ return Some(name.to_string()) } } @@ -82,7 +81,7 @@ names: &Option>, } } -pub fn geoip2_city_to_named_location(item: geoip2::city::City, languages: &Vec<&String>) -> NamedLocation { +pub fn geoip2_city_to_named_location(item: geoip2::city::City, languages: &[&str]) -> NamedLocation { NamedLocation { iso_code: None, geoname_id: item.geoname_id, @@ -90,7 +89,7 @@ pub fn geoip2_city_to_named_location(item: geoip2::city::City, languages: &Vec<& } } -pub fn geoip2_continent_to_named_location(item: geoip2::country::Continent, languages: &Vec<&String>) -> NamedLocation { +pub fn geoip2_continent_to_named_location(item: geoip2::country::Continent, languages: &[&str]) -> NamedLocation { NamedLocation { iso_code: item.code.map(ToString::to_string), geoname_id: item.geoname_id, @@ -98,7 +97,7 @@ pub fn geoip2_continent_to_named_location(item: geoip2::country::Continent, lang } } -pub fn geoip2_country_to_named_location(item: geoip2::country::Country, languages: &Vec<&String>) -> NamedLocation { +pub fn geoip2_country_to_named_location(item: geoip2::country::Country, languages: &[&str]) -> NamedLocation { NamedLocation { iso_code: item.iso_code.map(ToString::to_string), geoname_id: item.geoname_id, @@ -106,7 +105,7 @@ pub fn geoip2_country_to_named_location(item: geoip2::country::Country, language } } -pub fn geoip2_represented_country_to_named_location(item: geoip2::country::RepresentedCountry, languages: &Vec<&String>) -> NamedLocation { +pub fn geoip2_represented_country_to_named_location(item: geoip2::country::RepresentedCountry, languages: &[&str]) -> NamedLocation { NamedLocation { iso_code: item.iso_code.map(ToString::to_string), geoname_id: item.geoname_id, @@ -114,7 +113,7 @@ pub fn geoip2_represented_country_to_named_location(item: geoip2::country::Repre } } -pub fn geoip2_subdivision_to_named_location(item: geoip2::city::Subdivision, languages: &Vec<&String>) -> NamedLocation { +pub fn geoip2_subdivision_to_named_location(item: geoip2::city::Subdivision, languages: &[&str]) -> NamedLocation { NamedLocation { iso_code: item.iso_code.map(ToString::to_string), geoname_id: item.geoname_id, @@ -148,7 +147,7 @@ impl QueryAsn for MMDBCarrier { } impl QueryLocation for MMDBCarrier { - fn query_location_for_ip(&self, address: &IpAddr, languages: &Vec<&String>) -> Option { + fn query_location_for_ip(&self, address: &IpAddr, languages: &[&str]) -> Option { let mmdb = self.mmdb.read(); match &*mmdb { Some(mmdb) => { diff --git a/src/idna.rs b/src/idna.rs index 9235420..7311dcd 100644 --- a/src/idna.rs +++ b/src/idna.rs @@ -14,7 +14,7 @@ pub enum NameType { #[default] Ascii, Unicode, - IDN, + Idn, } // Note, that the @@ -32,8 +32,8 @@ pub struct IdnaName { } impl IdnaName { - pub fn from_string(s: &String) -> Self { - if s == "" { + pub fn from_str(s: &str) -> Self { + if s.is_empty() { return Default::default(); } @@ -41,17 +41,17 @@ impl IdnaName { let unicode: String; let decoder_error; if s.starts_with("xn--") && s.is_ascii() { - original_was = NameType::IDN; + original_was = NameType::Idn; let (uc, ures) = idna::domain_to_unicode(s); unicode = uc; decoder_error = ures.map_or_else(|e| Some(e.to_string()), |_| None); } else { - unicode = s.clone(); + unicode = s.to_owned(); decoder_error = None; }; let (idn, encoder_error) = match idna::domain_to_ascii(s) { Ok(idn) => { - if &idn != s || original_was == NameType::IDN { + if idn != s || original_was == NameType::Idn { (Some(idn), None) } else { original_was = NameType::Ascii; diff --git a/src/main.rs b/src/main.rs index f61a0f4..1aa0fc8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,7 @@ + +#![allow(clippy::redundant_field_names)] +#![allow(clippy::needless_return)] + use axum::{ body::Body, extract::{ @@ -61,7 +65,7 @@ use crate::idna::IdnaName; use crate::simple_dns::DnsLookupResult; use crate::settings::*; use crate::view::View; -use crate::ipinfo::{AddressCast,AddressInfo,AddressScope}; +use crate::ipinfo::{AddressInfo,AddressScope}; type TemplatingEngine = HumusEngine; @@ -133,7 +137,7 @@ struct CliArgs { static_location: Option, } -fn match_domain_hidden_list(domain: &String, hidden_list: &Vec) -> bool { +fn match_domain_hidden_list(domain: &str, hidden_list: &Vec) -> bool { let name = domain.trim_end_matches("."); for suffix in hidden_list { if name.ends_with(suffix) { @@ -265,7 +269,7 @@ async fn main() { }); dns_resolver_selectables.sort_by(|a,b| b.weight.cmp(&a.weight)); - let default_resolver = dns_resolver_selectables.get(0) + let default_resolver = dns_resolver_selectables.first() .map(|s| s.id.clone() ) .unwrap_or("none".into()); let derived_config = DerivedConfiguration { @@ -286,7 +290,7 @@ async fn main() { } }; loop { - if None == signal_stream.recv().await { return; } + if signal_stream.recv().await.is_none() { return; } info!("Received signal USR1, reloading geoip databses!"); signal_usr1_handlers_state.location_db.reload_database().ok(); signal_usr1_handlers_state.asn_db.reload_database().ok(); @@ -436,10 +440,8 @@ async fn handle_default_route( &state, ).await; - let user_agent: Option = match user_agent_header { - Some(TypedHeader(user_agent)) => Some(user_agent.to_string()), - None => None, - }; + let user_agent: Option = user_agent_header + .map(|TypedHeader(user_agent)| user_agent.to_string()); state.templating_engine.render_view( &settings, @@ -466,7 +468,7 @@ async fn handle_search_request( //If someone asked for an asn, give an asn answer if let Some(asn_cap) = ASN_REGEX.captures(&search_query) { - if let Some(asn) = asn_cap.get(1).map_or(None, |m| m.as_str().parse::().ok()) { + if let Some(asn) = asn_cap.get(1).and_then(|m| m.as_str().parse::().ok()) { // Render a dummy template that can at least link to other pages let state = Arc::clone(&arc_state); return state.templating_engine.render_view( @@ -571,7 +573,7 @@ async fn handle_ip_request( async fn get_ip_result( address: &IpAddr, - lang: &String, + lang: &str, dns_resolver_name: &Arc, dns_disable_self_lookup: bool, client_ip: &IpAddr, @@ -580,34 +582,36 @@ async fn get_ip_result( let mut reverse_dns_disabled_for_privacy = false; - if state.config.dns.allow_reverse_lookup { - if address == client_ip && dns_disable_self_lookup { - reverse_dns_disabled_for_privacy = true; - } + if state.config.dns.allow_reverse_lookup && + address == client_ip && + dns_disable_self_lookup + { + reverse_dns_disabled_for_privacy = true; } - let ip_info = AddressInfo::new(&address); + let ip_info = AddressInfo::new(address); - if !(ip_info.scope == AddressScope::Global || ip_info.scope == AddressScope::Shared) || ip_info.cast != AddressCast::Unicast { - if !((ip_info.scope == AddressScope::Private || ip_info.scope == AddressScope::LinkLocal) && state.config.server.allow_private_ip_lookup) { - return IpResult { - address: *address, - hostname: None, - asn: None, - location: None, - ip_info: ip_info, - used_dns_resolver: None, - reverse_dns_disabled_for_privacy: reverse_dns_disabled_for_privacy, - } + // Return dummy result if: + // + // The address falls into a private range and lookup of private addresses is not allowed. + if (!state.config.server.allow_private_ip_lookup) && (ip_info.scope == AddressScope::Private || ip_info.scope == AddressScope::LinkLocal) { + return IpResult { + address: *address, + hostname: None, + asn: None, + location: None, + ip_info: ip_info, + used_dns_resolver: None, + reverse_dns_disabled_for_privacy: reverse_dns_disabled_for_privacy, } - } + } // do reverse lookup let mut hostname: Option = None; let mut used_dns_resolver: Option> = None; if state.config.dns.allow_reverse_lookup && !reverse_dns_disabled_for_privacy { if let Some(dns_resolver) = &state.dns_resolvers.get(dns_resolver_name) { - hostname = simple_dns::reverse_lookup(&dns_resolver, &address).await; + hostname = simple_dns::reverse_lookup(dns_resolver, address).await; used_dns_resolver = Some(dns_resolver_name.clone()); } } @@ -618,12 +622,12 @@ async fn get_ip_result( // location lookup let location_result = state.location_db.query_location_for_ip( address, - &vec![lang, &"en".to_string()] + &[lang, "en"] ); // filter reverse lookup if let Some(name) = &hostname { - if match_domain_hidden_list(&name, &state.config.dns.hidden_suffixes) { + if match_domain_hidden_list(name, &state.config.dns.hidden_suffixes) { hostname = None; used_dns_resolver = None; } @@ -672,21 +676,21 @@ async fn handle_dig_request( } async fn get_dig_result( - dig_query: &String, + dig_query: &str, dns_resolver_name: &Arc, state: &ServiceSharedState, do_full_lookup: bool, ) -> DigResult { let name = &dig_query.trim().trim_end_matches(".").to_string(); - let idna_name = IdnaName::from_string(&name); + let idna_name = IdnaName::from_str(name); if let Some(dns_resolver) = state.dns_resolvers.get(dns_resolver_name) { if let Ok(domain_name) = Name::from_str_relaxed(name.to_owned()+".") { - if match_domain_hidden_list(&name, &state.config.dns.hidden_suffixes) { + if match_domain_hidden_list(name, &state.config.dns.hidden_suffixes) { // Try to hide the fact that we didn't do dns resolution at all // We resolve example.org as basic avoidance of timing sidechannels. // WARNING: this timing sidechannel avoidance is very crude. simple_dns::lookup( - &dns_resolver, + dns_resolver, &Name::from_ascii("example.org.").expect("Static Dummy Name"), do_full_lookup).await; return DigResult { @@ -698,7 +702,7 @@ async fn get_dig_result( } else { return DigResult { records: simple_dns::lookup( - &dns_resolver, + dns_resolver, &domain_name, do_full_lookup).await, idn: idna_name, diff --git a/src/simple_dns.rs b/src/simple_dns.rs index 9b6fdeb..4683cdb 100644 --- a/src/simple_dns.rs +++ b/src/simple_dns.rs @@ -80,7 +80,7 @@ pub async fn reverse_lookup( let revese_res = resolver.reverse_lookup(*address); match revese_res.await { Ok(lookup) => { - for name in lookup { + if let Some(name) = lookup.iter().next() { return Some(name.to_string()) } None