mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2024-11-10 00:27:21 +01: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 geoip;
|
||||
mod idna;
|
||||
mod ipinfo;
|
||||
mod mycelium;
|
||||
mod ratelimit;
|
||||
mod settings;
|
||||
mod simple_dns;
|
||||
mod templating_engine;
|
||||
mod idna;
|
||||
mod view;
|
||||
|
||||
use crate::geoip::{
|
||||
QueryAsn,
|
||||
@ -54,7 +56,7 @@ use crate::geoip::{
|
||||
use crate::idna::IdnaName;
|
||||
use crate::simple_dns::DnsLookupResult;
|
||||
use crate::settings::*;
|
||||
use crate::templating_engine::View;
|
||||
use crate::view::View;
|
||||
use crate::ipinfo::{AddressCast,AddressInfo,AddressScope};
|
||||
|
||||
#[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 toml::Table;
|
||||
|
||||
use crate::DigResult;
|
||||
use crate::IpResult;
|
||||
use crate::config::DnsResolverConfig;
|
||||
use crate::settings::*;
|
||||
|
||||
|
||||
/* 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()
|
||||
}
|
||||
}
|
||||
use crate::view::View;
|
||||
use crate::mycelium::MycView;
|
||||
use crate::settings::QuerySettings;
|
||||
use crate::settings::ResponseFormat;
|
||||
|
||||
/* The engine itself */
|
||||
|
||||
@ -70,7 +38,7 @@ impl Engine {
|
||||
) -> Response {
|
||||
let mut response = match settings.format {
|
||||
ResponseFormat::TextHtml | ResponseFormat::TextPlain => {
|
||||
let template_name = view.template_name();
|
||||
let template_name = view.get_template_name();
|
||||
|
||||
let mut context = tera::Context::new();
|
||||
context.insert("view", &template_name);
|
||||
@ -82,17 +50,17 @@ impl Engine {
|
||||
context.insert("data", &view);
|
||||
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) =>
|
||||
match settings.format {
|
||||
ResponseFormat::TextHtml => Html(text).into_response(),
|
||||
_ => text.into_response(),
|
||||
}
|
||||
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,
|
||||
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()
|
||||
}
|
||||
}
|
||||
@ -116,10 +84,12 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
};
|
||||
match view {
|
||||
View::NotFound => *response.status_mut() = StatusCode::NOT_FOUND,
|
||||
_ => {},
|
||||
// Set status code
|
||||
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())
|
||||
.path("/")
|
||||
.same_site(cookie::SameSite::Strict)
|
||||
@ -130,6 +100,7 @@ impl Engine {
|
||||
header_value,
|
||||
);
|
||||
}
|
||||
// return 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…
Reference in New Issue
Block a user