mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-04-28 15:28:56 +02:00
First step to detaching the templating from the logic.
This commit is contained in:
parent
c5a7597561
commit
20fb7ee2ff
@ -38,12 +38,14 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod geoip;
|
mod geoip;
|
||||||
|
mod idna;
|
||||||
mod ipinfo;
|
mod ipinfo;
|
||||||
|
mod mycelium;
|
||||||
mod ratelimit;
|
mod ratelimit;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod simple_dns;
|
mod simple_dns;
|
||||||
mod templating_engine;
|
mod templating_engine;
|
||||||
mod idna;
|
mod view;
|
||||||
|
|
||||||
use crate::geoip::{
|
use crate::geoip::{
|
||||||
QueryAsn,
|
QueryAsn,
|
||||||
@ -54,7 +56,7 @@ use crate::geoip::{
|
|||||||
use crate::idna::IdnaName;
|
use crate::idna::IdnaName;
|
||||||
use crate::simple_dns::DnsLookupResult;
|
use crate::simple_dns::DnsLookupResult;
|
||||||
use crate::settings::*;
|
use crate::settings::*;
|
||||||
use crate::templating_engine::View;
|
use crate::view::View;
|
||||||
use crate::ipinfo::{AddressCast,AddressInfo,AddressScope};
|
use crate::ipinfo::{AddressCast,AddressInfo,AddressScope};
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone)]
|
||||||
|
3
src/mycelium/mod.rs
Normal file
3
src/mycelium/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod view;
|
||||||
|
|
||||||
|
pub use self::view::MycView;
|
47
src/mycelium/view.rs
Normal file
47
src/mycelium/view.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use axum::response::IntoResponse;
|
||||||
|
use axum::response::Json;
|
||||||
|
use axum::response::Response;
|
||||||
|
use axum::http::status::StatusCode;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
pub trait MycView: Serialize + Sized {
|
||||||
|
|
||||||
|
/// Returns the template name that will be used to select
|
||||||
|
/// the template file.
|
||||||
|
///
|
||||||
|
/// If the name is "404" for an html response the template
|
||||||
|
/// file "404.html" will be used.
|
||||||
|
///
|
||||||
|
/// Also ends up as the `view` variable in the template.
|
||||||
|
fn get_template_name(&self) -> String;
|
||||||
|
|
||||||
|
//TODO: Add query settings to these
|
||||||
|
|
||||||
|
/// Returns the reponse code for the view.
|
||||||
|
///
|
||||||
|
/// The numeric value will be useable as `http_status` in the template.
|
||||||
|
fn get_status_code(&self) -> StatusCode;
|
||||||
|
|
||||||
|
/// If this returns a String it will be used as the cookie header.
|
||||||
|
///
|
||||||
|
/// See: [axum: Constructing a Cookie](https://docs.rs/axum-extra/0.8.0/axum_extra/extract/cookie/struct.Cookie.html#constructing-a-cookie)
|
||||||
|
fn get_cookie_header(&self) -> Option<String> { None }
|
||||||
|
|
||||||
|
/// Update non-API responses after they have been built.
|
||||||
|
///
|
||||||
|
/// Useful for setting extra headers. Does noting by default.
|
||||||
|
fn update_response(&self, _response: &mut Response) {}
|
||||||
|
|
||||||
|
/// Return an API-Response
|
||||||
|
///
|
||||||
|
/// By default causes the view to Serialize itself
|
||||||
|
/// to a json response using serde.
|
||||||
|
///
|
||||||
|
/// Response code and cookie headers are queried in
|
||||||
|
/// advance and set on the reulting response if it has a status code of 200.
|
||||||
|
/// Otherwise it is assumed that the response genrating logic
|
||||||
|
/// alredy took care of that.
|
||||||
|
fn get_api_response(self) -> Response {
|
||||||
|
Json(self).into_response()
|
||||||
|
}
|
||||||
|
}
|
@ -17,42 +17,10 @@ use axum_extra::extract::cookie;
|
|||||||
use tera::Tera;
|
use tera::Tera;
|
||||||
use toml::Table;
|
use toml::Table;
|
||||||
|
|
||||||
use crate::DigResult;
|
use crate::view::View;
|
||||||
use crate::IpResult;
|
use crate::mycelium::MycView;
|
||||||
use crate::config::DnsResolverConfig;
|
use crate::settings::QuerySettings;
|
||||||
use crate::settings::*;
|
use crate::settings::ResponseFormat;
|
||||||
|
|
||||||
|
|
||||||
/* The echoip view */
|
|
||||||
|
|
||||||
#[derive(serde::Serialize, Clone)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum View {
|
|
||||||
Asn { asn: u32 },
|
|
||||||
Dig { query: String, result: DigResult },
|
|
||||||
DnsResolver{ config: DnsResolverConfig },
|
|
||||||
DnsResolverList,
|
|
||||||
Index { result: IpResult, user_agent: Option<String> },
|
|
||||||
Ip { result: IpResult },
|
|
||||||
Message{ title: String, message: String },
|
|
||||||
#[serde(rename="404")]
|
|
||||||
NotFound,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl View {
|
|
||||||
pub fn template_name(&self) -> String {
|
|
||||||
match self {
|
|
||||||
View::Asn{..} => "asn",
|
|
||||||
View::Dig{..} => "dig",
|
|
||||||
View::DnsResolver{..} => "dns_resolver",
|
|
||||||
View::DnsResolverList => "dns_resolver_list",
|
|
||||||
View::Index{..} => "index",
|
|
||||||
View::Ip{..} => "ip",
|
|
||||||
View::Message{..} => "message",
|
|
||||||
View::NotFound => "404",
|
|
||||||
}.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The engine itself */
|
/* The engine itself */
|
||||||
|
|
||||||
@ -70,7 +38,7 @@ impl Engine {
|
|||||||
) -> Response {
|
) -> Response {
|
||||||
let mut response = match settings.format {
|
let mut response = match settings.format {
|
||||||
ResponseFormat::TextHtml | ResponseFormat::TextPlain => {
|
ResponseFormat::TextHtml | ResponseFormat::TextPlain => {
|
||||||
let template_name = view.template_name();
|
let template_name = view.get_template_name();
|
||||||
|
|
||||||
let mut context = tera::Context::new();
|
let mut context = tera::Context::new();
|
||||||
context.insert("view", &template_name);
|
context.insert("view", &template_name);
|
||||||
@ -82,17 +50,17 @@ impl Engine {
|
|||||||
context.insert("data", &view);
|
context.insert("data", &view);
|
||||||
context.insert("extra", &self.template_config);
|
context.insert("extra", &self.template_config);
|
||||||
|
|
||||||
match self.tera.render(&(template_name+&settings.format.to_file_extension()), &context) {
|
match self.tera.render(&(template_name.clone()+&settings.format.to_file_extension()), &context) {
|
||||||
Ok(text) =>
|
Ok(text) =>
|
||||||
match settings.format {
|
match settings.format {
|
||||||
ResponseFormat::TextHtml => Html(text).into_response(),
|
ResponseFormat::TextHtml => Html(text).into_response(),
|
||||||
_ => text.into_response(),
|
_ => text.into_response(),
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("There was an error while rendering template {}: {e:?}", view.template_name());
|
println!("There was an error while rendering template {}: {e:?}", template_name);
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("Template error in {}, contact owner or see logs.\n", view.template_name())
|
format!("Template error in {}, contact owner or see logs.\n", template_name)
|
||||||
).into_response()
|
).into_response()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,10 +84,12 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match view {
|
// Set status code
|
||||||
View::NotFound => *response.status_mut() = StatusCode::NOT_FOUND,
|
let status_code = view.get_status_code();
|
||||||
_ => {},
|
if status_code != StatusCode::OK {
|
||||||
|
*response.status_mut() = status_code;
|
||||||
}
|
}
|
||||||
|
// Set cookies
|
||||||
let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.to_string())
|
let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.to_string())
|
||||||
.path("/")
|
.path("/")
|
||||||
.same_site(cookie::SameSite::Strict)
|
.same_site(cookie::SameSite::Strict)
|
||||||
@ -130,6 +100,7 @@ impl Engine {
|
|||||||
header_value,
|
header_value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// return response
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
45
src/view.rs
Normal file
45
src/view.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
use axum::http::status::StatusCode;
|
||||||
|
|
||||||
|
use crate::DigResult;
|
||||||
|
use crate::IpResult;
|
||||||
|
use crate::config::DnsResolverConfig;
|
||||||
|
|
||||||
|
use crate::mycelium::MycView;
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, Clone)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum View {
|
||||||
|
Asn { asn: u32 },
|
||||||
|
Dig { query: String, result: DigResult },
|
||||||
|
DnsResolver{ config: DnsResolverConfig },
|
||||||
|
DnsResolverList,
|
||||||
|
Index { result: IpResult, user_agent: Option<String> },
|
||||||
|
Ip { result: IpResult },
|
||||||
|
Message{ title: String, message: String },
|
||||||
|
#[serde(rename="404")]
|
||||||
|
NotFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MycView for View {
|
||||||
|
fn get_template_name(&self) -> String {
|
||||||
|
match self {
|
||||||
|
View::Asn{..} => "asn",
|
||||||
|
View::Dig{..} => "dig",
|
||||||
|
View::DnsResolver{..} => "dns_resolver",
|
||||||
|
View::DnsResolverList => "dns_resolver_list",
|
||||||
|
View::Index{..} => "index",
|
||||||
|
View::Ip{..} => "ip",
|
||||||
|
View::Message{..} => "message",
|
||||||
|
View::NotFound => "404",
|
||||||
|
}.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_status_code(&self) -> StatusCode {
|
||||||
|
match self {
|
||||||
|
Self::NotFound => StatusCode::NOT_FOUND,
|
||||||
|
_ => StatusCode::OK,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user