diff --git a/src/main.rs b/src/main.rs index d370a0c..99778c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ mod config; mod geoip; mod ipinfo; mod ratelimit; +mod settings; mod simple_dns; mod templating_engine; mod idna; @@ -51,12 +52,8 @@ use crate::geoip::{ }; use crate::idna::IdnaName; use crate::simple_dns::DnsLookupResult; -use crate::templating_engine::{ - View, - ResponseFormat, - TemplateSettings, - Selectable, -}; +use crate::settings::*; +use crate::templating_engine::View; use crate::ipinfo::{AddressCast,AddressInfo,AddressScope}; #[derive(Deserialize, Serialize, Clone)] @@ -66,13 +63,6 @@ pub struct SettingsQuery { dns: Option, } -#[derive(Clone, Serialize)] -pub struct QuerySettings { - #[serde(skip)] - template: TemplateSettings, - dns_resolver_id: String, -} - #[derive(Deserialize, Serialize, Clone)] pub struct SearchQuery { query: Option, @@ -414,12 +404,9 @@ async fn settings_query_middleware( } // Add the request settings extension req.extensions_mut().insert(QuerySettings{ - template: TemplateSettings{ - format: format.unwrap_or(ResponseFormat::TextHtml), - lang: query.lang.unwrap_or("en".to_string()), - available_dns_resolvers: derived_config.dns_resolver_selectables, - dns_resolver: dns_resolver_id.clone(), - }, + format: format.unwrap_or(ResponseFormat::TextHtml), + lang: query.lang.unwrap_or("en".to_string()), + available_dns_resolvers: derived_config.dns_resolver_selectables, dns_resolver_id: dns_resolver_id, }); next.run(req).await @@ -432,7 +419,7 @@ async fn not_found_handler( let state = Arc::clone(&arc_state); state.templating_engine.render_view( - &settings.template, + &settings, &View::NotFound, ).await } @@ -444,7 +431,7 @@ async fn hello_world_handler( let state = Arc::clone(&arc_state); state.templating_engine.render_view( - &settings.template, + &settings, &View::Message{ title: "Hey There!".to_string(), message: "You,You are an awesome Creature!".to_string() @@ -480,7 +467,7 @@ async fn handle_default_route( } } - let result = get_ip_result(&address, &settings.template.lang, &"default".to_string(), &state).await; + let result = get_ip_result(&address, &settings.lang, &"default".to_string(), &state).await; let user_agent: Option = match user_agent_header { Some(TypedHeader(user_agent)) => Some(user_agent.to_string()), @@ -488,7 +475,7 @@ async fn handle_default_route( }; state.templating_engine.render_view( - &settings.template, + &settings, &View::Index{ result: result, user_agent: user_agent, @@ -518,7 +505,7 @@ async fn handle_search_request( // Render a dummy template that can at least link to other pages let state = Arc::clone(&arc_state); return state.templating_engine.render_view( - &settings.template, + &settings, &View::Asn{asn: asn}, ).await } @@ -555,7 +542,7 @@ async fn handle_dns_resolver_route( ) -> Response { let state = Arc::clone(&arc_state); state.templating_engine.render_view( - &settings.template, + &settings, &View::DnsResolverList, ).await } @@ -569,12 +556,12 @@ async fn handle_dns_resolver_route_with_path( let state = Arc::clone(&arc_state); if let Some(resolver) = state.config.dns.resolver.get(&query) { state.templating_engine.render_view( - &settings.template, + &settings, &View::DnsResolver{ config: resolver.clone() }, ).await } else { state.templating_engine.render_view( - &settings.template, + &settings, &View::NotFound, ).await } @@ -601,12 +588,12 @@ async fn handle_ip_request( let state = Arc::clone(&arc_state); let result = get_ip_result( &address, - &settings.template.lang, + &settings.lang, &settings.dns_resolver_id, &state).await; state.templating_engine.render_view( - &settings.template, + &settings, &View::Ip{result: result} ).await } @@ -695,7 +682,7 @@ async fn handle_dig_request( ).await; state.templating_engine.render_view( - &settings.template, + &settings, &View::Dig{ query: dig_query, result: dig_result} ).await diff --git a/src/settings.rs b/src/settings.rs new file mode 100644 index 0000000..1806235 --- /dev/null +++ b/src/settings.rs @@ -0,0 +1,49 @@ +use serde::{Deserialize,Serialize}; +/* Response format */ + +#[derive(Deserialize, Serialize, Clone, Copy)] +pub enum ResponseFormat { + #[serde(rename="text/plain", alias="text")] + TextPlain, + #[serde(rename="text/html", alias="html")] + TextHtml, + #[serde(rename="application/json", alias="json")] + ApplicationJson, +} + +impl ToString for ResponseFormat { + fn to_string(&self) -> String { + match self { + ResponseFormat::TextPlain => "text/plain", + ResponseFormat::TextHtml => "text/html", + ResponseFormat::ApplicationJson => "application/json", + }.to_string() + } +} + +impl ResponseFormat { + pub fn to_file_extension(&self) -> String { + match self { + ResponseFormat::TextPlain => ".txt", + ResponseFormat::TextHtml => ".html", + ResponseFormat::ApplicationJson => ".json", + }.to_string() + } +} + +/* Query and Template Settings */ + +#[derive(Deserialize, Serialize, Clone)] +pub struct QuerySettings { + pub format: ResponseFormat, + pub lang: String, + pub available_dns_resolvers: Vec, + pub dns_resolver_id: String, +} + +#[derive(Deserialize, Serialize, Clone)] +pub struct Selectable { + pub id: String, + pub name: String, +} + diff --git a/src/templating_engine.rs b/src/templating_engine.rs index 9bb54a9..faf9a82 100644 --- a/src/templating_engine.rs +++ b/src/templating_engine.rs @@ -20,54 +20,8 @@ use toml::Table; use crate::DigResult; use crate::IpResult; use crate::config::DnsResolverConfig; +use crate::settings::*; -/* Response format */ - -#[derive(serde::Deserialize, serde::Serialize, Clone, Copy)] -pub enum ResponseFormat { - #[serde(rename="text/plain", alias="text")] - TextPlain, - #[serde(rename="text/html", alias="html")] - TextHtml, - #[serde(rename="application/json", alias="json")] - ApplicationJson, -} - -impl ToString for ResponseFormat { - fn to_string(&self) -> String { - match self { - ResponseFormat::TextPlain => "text/plain", - ResponseFormat::TextHtml => "text/html", - ResponseFormat::ApplicationJson => "application/json", - }.to_string() - } -} - -impl ResponseFormat { - fn to_file_extension(&self) -> String { - match self { - ResponseFormat::TextPlain => ".txt", - ResponseFormat::TextHtml => ".html", - ResponseFormat::ApplicationJson => ".json", - }.to_string() - } -} - -/* Template Settings */ - -#[derive(serde::Deserialize, serde::Serialize, Clone)] -pub struct TemplateSettings { - pub format: ResponseFormat, - pub lang: String, - pub available_dns_resolvers: Vec, - pub dns_resolver: String, -} - -#[derive(serde::Deserialize, serde::Serialize, Clone)] -pub struct Selectable { - pub id: String, - pub name: String, -} /* The echoip view */ @@ -111,7 +65,7 @@ pub struct Engine { impl Engine { pub async fn render_view( &self, - settings: &TemplateSettings, + settings: &QuerySettings, view: &View, ) -> Response { let mut response = match settings.format { @@ -124,7 +78,7 @@ impl Engine { context.insert("format", &settings.format.to_string()); context.insert("language", &settings.lang); context.insert("dns_resolvers", &settings.available_dns_resolvers); - context.insert("dns_resolver_id", &settings.dns_resolver); + context.insert("dns_resolver_id", &settings.dns_resolver_id); context.insert("data", &view); context.insert("extra", &self.template_config); @@ -166,7 +120,7 @@ impl Engine { View::NotFound => *response.status_mut() = StatusCode::NOT_FOUND, _ => {}, } - let cookie = Cookie::build("dns_resolver",settings.dns_resolver.clone()) + let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.clone()) .path("/") .same_site(cookie::SameSite::Strict) .finish();