mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-03-04 04:13:57 +01:00
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`
This commit is contained in:
parent
d902dae35d
commit
b98bb67b4c
@ -73,14 +73,14 @@ impl Default for DnsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Protocol> for DnsProtocol {
|
impl From<DnsProtocol> for Protocol {
|
||||||
fn into(self) -> Protocol {
|
fn from(value: DnsProtocol) -> Self {
|
||||||
match self {
|
match value {
|
||||||
Self::Udp => Protocol::Udp,
|
DnsProtocol::Udp => Protocol::Udp,
|
||||||
Self::Tcp => Protocol::Tcp,
|
DnsProtocol::Tcp => Protocol::Tcp,
|
||||||
Self::Tls => Protocol::Tls,
|
DnsProtocol::Tls => Protocol::Tls,
|
||||||
Self::Https => Protocol::Https,
|
DnsProtocol::Https => Protocol::Https,
|
||||||
Self::Quic => Protocol::Quic,
|
DnsProtocol::Quic => Protocol::Quic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
src/geoip.rs
19
src/geoip.rs
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use log::{info,warn,error};
|
use log::{info,warn,error};
|
||||||
use maxminddb;
|
|
||||||
use maxminddb::geoip2;
|
use maxminddb::geoip2;
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
@ -56,7 +55,7 @@ pub struct MMDBCarrier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait QueryLocation {
|
pub trait QueryLocation {
|
||||||
fn query_location_for_ip(&self, address: &IpAddr, laguages: &Vec<&String>) -> Option<LocationResult>;
|
fn query_location_for_ip(&self, address: &IpAddr, laguages: &[&str]) -> Option<LocationResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait QueryAsn {
|
pub trait QueryAsn {
|
||||||
@ -67,12 +66,12 @@ pub trait QueryAsn {
|
|||||||
|
|
||||||
pub fn extract_localized_name(
|
pub fn extract_localized_name(
|
||||||
names: &Option<BTreeMap<&str, &str>>,
|
names: &Option<BTreeMap<&str, &str>>,
|
||||||
languages: &Vec<&String>)
|
languages: &[&str])
|
||||||
-> Option<String> {
|
-> Option<String> {
|
||||||
match names {
|
match names {
|
||||||
Some(names) => {
|
Some(names) => {
|
||||||
for language in languages {
|
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())
|
return Some(name.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,7 +81,7 @@ names: &Option<BTreeMap<&str, &str>>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
NamedLocation {
|
||||||
iso_code: None,
|
iso_code: None,
|
||||||
geoname_id: item.geoname_id,
|
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 {
|
NamedLocation {
|
||||||
iso_code: item.code.map(ToString::to_string),
|
iso_code: item.code.map(ToString::to_string),
|
||||||
geoname_id: item.geoname_id,
|
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 {
|
NamedLocation {
|
||||||
iso_code: item.iso_code.map(ToString::to_string),
|
iso_code: item.iso_code.map(ToString::to_string),
|
||||||
geoname_id: item.geoname_id,
|
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 {
|
NamedLocation {
|
||||||
iso_code: item.iso_code.map(ToString::to_string),
|
iso_code: item.iso_code.map(ToString::to_string),
|
||||||
geoname_id: item.geoname_id,
|
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 {
|
NamedLocation {
|
||||||
iso_code: item.iso_code.map(ToString::to_string),
|
iso_code: item.iso_code.map(ToString::to_string),
|
||||||
geoname_id: item.geoname_id,
|
geoname_id: item.geoname_id,
|
||||||
@ -148,7 +147,7 @@ impl QueryAsn for MMDBCarrier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl QueryLocation for MMDBCarrier {
|
impl QueryLocation for MMDBCarrier {
|
||||||
fn query_location_for_ip(&self, address: &IpAddr, languages: &Vec<&String>) -> Option<LocationResult> {
|
fn query_location_for_ip(&self, address: &IpAddr, languages: &[&str]) -> Option<LocationResult> {
|
||||||
let mmdb = self.mmdb.read();
|
let mmdb = self.mmdb.read();
|
||||||
match &*mmdb {
|
match &*mmdb {
|
||||||
Some(mmdb) => {
|
Some(mmdb) => {
|
||||||
|
12
src/idna.rs
12
src/idna.rs
@ -14,7 +14,7 @@ pub enum NameType {
|
|||||||
#[default]
|
#[default]
|
||||||
Ascii,
|
Ascii,
|
||||||
Unicode,
|
Unicode,
|
||||||
IDN,
|
Idn,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note, that the
|
// Note, that the
|
||||||
@ -32,8 +32,8 @@ pub struct IdnaName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IdnaName {
|
impl IdnaName {
|
||||||
pub fn from_string(s: &String) -> Self {
|
pub fn from_str(s: &str) -> Self {
|
||||||
if s == "" {
|
if s.is_empty() {
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,17 +41,17 @@ impl IdnaName {
|
|||||||
let unicode: String;
|
let unicode: String;
|
||||||
let decoder_error;
|
let decoder_error;
|
||||||
if s.starts_with("xn--") && s.is_ascii() {
|
if s.starts_with("xn--") && s.is_ascii() {
|
||||||
original_was = NameType::IDN;
|
original_was = NameType::Idn;
|
||||||
let (uc, ures) = idna::domain_to_unicode(s);
|
let (uc, ures) = idna::domain_to_unicode(s);
|
||||||
unicode = uc;
|
unicode = uc;
|
||||||
decoder_error = ures.map_or_else(|e| Some(e.to_string()), |_| None);
|
decoder_error = ures.map_or_else(|e| Some(e.to_string()), |_| None);
|
||||||
} else {
|
} else {
|
||||||
unicode = s.clone();
|
unicode = s.to_owned();
|
||||||
decoder_error = None;
|
decoder_error = None;
|
||||||
};
|
};
|
||||||
let (idn, encoder_error) = match idna::domain_to_ascii(s) {
|
let (idn, encoder_error) = match idna::domain_to_ascii(s) {
|
||||||
Ok(idn) => {
|
Ok(idn) => {
|
||||||
if &idn != s || original_was == NameType::IDN {
|
if idn != s || original_was == NameType::Idn {
|
||||||
(Some(idn), None)
|
(Some(idn), None)
|
||||||
} else {
|
} else {
|
||||||
original_was = NameType::Ascii;
|
original_was = NameType::Ascii;
|
||||||
|
72
src/main.rs
72
src/main.rs
@ -1,3 +1,7 @@
|
|||||||
|
|
||||||
|
#![allow(clippy::redundant_field_names)]
|
||||||
|
#![allow(clippy::needless_return)]
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body,
|
body::Body,
|
||||||
extract::{
|
extract::{
|
||||||
@ -61,7 +65,7 @@ use crate::idna::IdnaName;
|
|||||||
use crate::simple_dns::DnsLookupResult;
|
use crate::simple_dns::DnsLookupResult;
|
||||||
use crate::settings::*;
|
use crate::settings::*;
|
||||||
use crate::view::View;
|
use crate::view::View;
|
||||||
use crate::ipinfo::{AddressCast,AddressInfo,AddressScope};
|
use crate::ipinfo::{AddressInfo,AddressScope};
|
||||||
|
|
||||||
type TemplatingEngine = HumusEngine<View,QuerySettings,ResponseFormat>;
|
type TemplatingEngine = HumusEngine<View,QuerySettings,ResponseFormat>;
|
||||||
|
|
||||||
@ -133,7 +137,7 @@ struct CliArgs {
|
|||||||
static_location: Option<String>,
|
static_location: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_domain_hidden_list(domain: &String, hidden_list: &Vec<String>) -> bool {
|
fn match_domain_hidden_list(domain: &str, hidden_list: &Vec<String>) -> bool {
|
||||||
let name = domain.trim_end_matches(".");
|
let name = domain.trim_end_matches(".");
|
||||||
for suffix in hidden_list {
|
for suffix in hidden_list {
|
||||||
if name.ends_with(suffix) {
|
if name.ends_with(suffix) {
|
||||||
@ -265,7 +269,7 @@ async fn main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dns_resolver_selectables.sort_by(|a,b| b.weight.cmp(&a.weight));
|
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() )
|
.map(|s| s.id.clone() )
|
||||||
.unwrap_or("none".into());
|
.unwrap_or("none".into());
|
||||||
let derived_config = DerivedConfiguration {
|
let derived_config = DerivedConfiguration {
|
||||||
@ -286,7 +290,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
if None == signal_stream.recv().await { return; }
|
if signal_stream.recv().await.is_none() { return; }
|
||||||
info!("Received signal USR1, reloading geoip databses!");
|
info!("Received signal USR1, reloading geoip databses!");
|
||||||
signal_usr1_handlers_state.location_db.reload_database().ok();
|
signal_usr1_handlers_state.location_db.reload_database().ok();
|
||||||
signal_usr1_handlers_state.asn_db.reload_database().ok();
|
signal_usr1_handlers_state.asn_db.reload_database().ok();
|
||||||
@ -436,10 +440,8 @@ async fn handle_default_route(
|
|||||||
&state,
|
&state,
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
let user_agent: Option<String> = match user_agent_header {
|
let user_agent: Option<String> = user_agent_header
|
||||||
Some(TypedHeader(user_agent)) => Some(user_agent.to_string()),
|
.map(|TypedHeader(user_agent)| user_agent.to_string());
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
state.templating_engine.render_view(
|
state.templating_engine.render_view(
|
||||||
&settings,
|
&settings,
|
||||||
@ -466,7 +468,7 @@ async fn handle_search_request(
|
|||||||
|
|
||||||
//If someone asked for an asn, give an asn answer
|
//If someone asked for an asn, give an asn answer
|
||||||
if let Some(asn_cap) = ASN_REGEX.captures(&search_query) {
|
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::<u32>().ok()) {
|
if let Some(asn) = asn_cap.get(1).and_then(|m| m.as_str().parse::<u32>().ok()) {
|
||||||
// Render a dummy template that can at least link to other pages
|
// Render a dummy template that can at least link to other pages
|
||||||
let state = Arc::clone(&arc_state);
|
let state = Arc::clone(&arc_state);
|
||||||
return state.templating_engine.render_view(
|
return state.templating_engine.render_view(
|
||||||
@ -571,7 +573,7 @@ async fn handle_ip_request(
|
|||||||
|
|
||||||
async fn get_ip_result(
|
async fn get_ip_result(
|
||||||
address: &IpAddr,
|
address: &IpAddr,
|
||||||
lang: &String,
|
lang: &str,
|
||||||
dns_resolver_name: &Arc<str>,
|
dns_resolver_name: &Arc<str>,
|
||||||
dns_disable_self_lookup: bool,
|
dns_disable_self_lookup: bool,
|
||||||
client_ip: &IpAddr,
|
client_ip: &IpAddr,
|
||||||
@ -580,25 +582,27 @@ async fn get_ip_result(
|
|||||||
|
|
||||||
let mut reverse_dns_disabled_for_privacy = false;
|
let mut reverse_dns_disabled_for_privacy = false;
|
||||||
|
|
||||||
if state.config.dns.allow_reverse_lookup {
|
if state.config.dns.allow_reverse_lookup &&
|
||||||
if address == client_ip && dns_disable_self_lookup {
|
address == client_ip &&
|
||||||
reverse_dns_disabled_for_privacy = true;
|
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 {
|
// Return dummy result if:
|
||||||
if !((ip_info.scope == AddressScope::Private || ip_info.scope == AddressScope::LinkLocal) && state.config.server.allow_private_ip_lookup) {
|
//
|
||||||
return IpResult {
|
// The address falls into a private range and lookup of private addresses is not allowed.
|
||||||
address: *address,
|
if (!state.config.server.allow_private_ip_lookup) && (ip_info.scope == AddressScope::Private || ip_info.scope == AddressScope::LinkLocal) {
|
||||||
hostname: None,
|
return IpResult {
|
||||||
asn: None,
|
address: *address,
|
||||||
location: None,
|
hostname: None,
|
||||||
ip_info: ip_info,
|
asn: None,
|
||||||
used_dns_resolver: None,
|
location: None,
|
||||||
reverse_dns_disabled_for_privacy: reverse_dns_disabled_for_privacy,
|
ip_info: ip_info,
|
||||||
}
|
used_dns_resolver: None,
|
||||||
|
reverse_dns_disabled_for_privacy: reverse_dns_disabled_for_privacy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +611,7 @@ async fn get_ip_result(
|
|||||||
let mut used_dns_resolver: Option<Arc<str>> = None;
|
let mut used_dns_resolver: Option<Arc<str>> = None;
|
||||||
if state.config.dns.allow_reverse_lookup && !reverse_dns_disabled_for_privacy {
|
if state.config.dns.allow_reverse_lookup && !reverse_dns_disabled_for_privacy {
|
||||||
if let Some(dns_resolver) = &state.dns_resolvers.get(dns_resolver_name) {
|
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());
|
used_dns_resolver = Some(dns_resolver_name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,12 +622,12 @@ async fn get_ip_result(
|
|||||||
// location lookup
|
// location lookup
|
||||||
let location_result = state.location_db.query_location_for_ip(
|
let location_result = state.location_db.query_location_for_ip(
|
||||||
address,
|
address,
|
||||||
&vec![lang, &"en".to_string()]
|
&[lang, "en"]
|
||||||
);
|
);
|
||||||
|
|
||||||
// filter reverse lookup
|
// filter reverse lookup
|
||||||
if let Some(name) = &hostname {
|
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;
|
hostname = None;
|
||||||
used_dns_resolver = None;
|
used_dns_resolver = None;
|
||||||
}
|
}
|
||||||
@ -672,21 +676,21 @@ async fn handle_dig_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_dig_result(
|
async fn get_dig_result(
|
||||||
dig_query: &String,
|
dig_query: &str,
|
||||||
dns_resolver_name: &Arc<str>,
|
dns_resolver_name: &Arc<str>,
|
||||||
state: &ServiceSharedState,
|
state: &ServiceSharedState,
|
||||||
do_full_lookup: bool,
|
do_full_lookup: bool,
|
||||||
) -> DigResult {
|
) -> DigResult {
|
||||||
let name = &dig_query.trim().trim_end_matches(".").to_string();
|
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 Some(dns_resolver) = state.dns_resolvers.get(dns_resolver_name) {
|
||||||
if let Ok(domain_name) = Name::from_str_relaxed(name.to_owned()+".") {
|
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
|
// Try to hide the fact that we didn't do dns resolution at all
|
||||||
// We resolve example.org as basic avoidance of timing sidechannels.
|
// We resolve example.org as basic avoidance of timing sidechannels.
|
||||||
// WARNING: this timing sidechannel avoidance is very crude.
|
// WARNING: this timing sidechannel avoidance is very crude.
|
||||||
simple_dns::lookup(
|
simple_dns::lookup(
|
||||||
&dns_resolver,
|
dns_resolver,
|
||||||
&Name::from_ascii("example.org.").expect("Static Dummy Name"),
|
&Name::from_ascii("example.org.").expect("Static Dummy Name"),
|
||||||
do_full_lookup).await;
|
do_full_lookup).await;
|
||||||
return DigResult {
|
return DigResult {
|
||||||
@ -698,7 +702,7 @@ async fn get_dig_result(
|
|||||||
} else {
|
} else {
|
||||||
return DigResult {
|
return DigResult {
|
||||||
records: simple_dns::lookup(
|
records: simple_dns::lookup(
|
||||||
&dns_resolver,
|
dns_resolver,
|
||||||
&domain_name,
|
&domain_name,
|
||||||
do_full_lookup).await,
|
do_full_lookup).await,
|
||||||
idn: idna_name,
|
idn: idna_name,
|
||||||
|
@ -80,7 +80,7 @@ pub async fn reverse_lookup(
|
|||||||
let revese_res = resolver.reverse_lookup(*address);
|
let revese_res = resolver.reverse_lookup(*address);
|
||||||
match revese_res.await {
|
match revese_res.await {
|
||||||
Ok(lookup) => {
|
Ok(lookup) => {
|
||||||
for name in lookup {
|
if let Some(name) = lookup.iter().next() {
|
||||||
return Some(name.to_string())
|
return Some(name.to_string())
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user