mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-07-16 14:03:28 +02:00
Made querying with paths possible (for wasier commandline usage)
This commit is contained in:
115
src/main.rs
115
src/main.rs
@ -1,10 +1,12 @@
|
||||
use axum::{
|
||||
extract::Query,
|
||||
extract::State,
|
||||
extract,
|
||||
response::Response,
|
||||
Router,
|
||||
routing::get,
|
||||
};
|
||||
use axum_client_ip::{SecureClientIp, SecureClientIpSource};
|
||||
|
||||
use tera::Tera;
|
||||
use trust_dns_resolver::{
|
||||
@ -13,13 +15,14 @@ use trust_dns_resolver::{
|
||||
config::ResolverConfig,
|
||||
};
|
||||
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::net::IpAddr;
|
||||
use std::sync::Arc;
|
||||
use std::path::Path;
|
||||
|
||||
mod simple_dns;
|
||||
mod templating_engine;
|
||||
mod geoip;
|
||||
mod config;
|
||||
|
||||
use crate::geoip::QueryAsn;
|
||||
use crate::geoip::QueryLocation;
|
||||
@ -30,15 +33,22 @@ use crate::templating_engine::View;
|
||||
use crate::templating_engine::ResponseFormat;
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct IpQuery {
|
||||
ip: Option<IpAddr>,
|
||||
pub struct BaseQuery {
|
||||
format: Option<ResponseFormat>,
|
||||
lang: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct IpQuery {
|
||||
format: Option<ResponseFormat>,
|
||||
lang: Option<String>,
|
||||
ip: IpAddr,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct DigQuery {
|
||||
name: String,
|
||||
format: Option<ResponseFormat>,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
@ -48,6 +58,7 @@ pub struct IpResult {
|
||||
location: Option<LocationResult>,
|
||||
}
|
||||
|
||||
|
||||
struct ServiceSharedState {
|
||||
templating_engine: templating_engine::Engine,
|
||||
dns_resolver: TokioAsyncResolver,
|
||||
@ -105,13 +116,17 @@ async fn main() {
|
||||
asn_db: asn_db,
|
||||
location_db: location_db,
|
||||
});
|
||||
|
||||
|
||||
// Initalize axum server
|
||||
let app = Router::new()
|
||||
.route("/", get(handle_default_route))
|
||||
.route("/dig", get(handle_dig_route))
|
||||
.route("/dig/:name", get(handle_dig_route_with_path))
|
||||
.route("/ip", get(handle_ip_route))
|
||||
.route("/ip/:address", get(handle_ip_route_with_path))
|
||||
.route("/hi", get(hello_world_handler))
|
||||
.with_state(shared_state)
|
||||
.layer(SecureClientIpSource::RightmostXForwardedFor.into_extension())
|
||||
;
|
||||
|
||||
println!("Starting Server ...");
|
||||
@ -134,13 +149,19 @@ async fn hello_world_handler(
|
||||
}
|
||||
|
||||
async fn handle_default_route(
|
||||
Query(ip_query): Query<IpQuery>,
|
||||
Query(query): Query<BaseQuery>,
|
||||
State(arc_state): State<Arc<ServiceSharedState>>,
|
||||
SecureClientIp(address): SecureClientIp
|
||||
) -> Response {
|
||||
|
||||
let address = ip_query.ip.unwrap_or(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));
|
||||
let format = ip_query.format.unwrap_or(ResponseFormat::TextHtml);
|
||||
let format = query.format.unwrap_or(ResponseFormat::TextHtml);
|
||||
|
||||
let ip_query = IpQuery {
|
||||
format: query.format,
|
||||
lang: query.lang,
|
||||
ip: address,
|
||||
};
|
||||
|
||||
let state = Arc::clone(&arc_state);
|
||||
|
||||
// do reverse lookup
|
||||
@ -150,7 +171,10 @@ async fn handle_default_route(
|
||||
let asn_result = state.asn_db.query_asn_for_ip(address);
|
||||
|
||||
// location lookup
|
||||
let location_result = state.location_db.query_location_for_ip(address, &vec!["en".to_string()]);
|
||||
let location_result = state.location_db.query_location_for_ip(
|
||||
address,
|
||||
&vec![&ip_query.lang.as_ref().unwrap_or(&"en".to_string()), &"en".to_string()]
|
||||
);
|
||||
|
||||
let result = IpResult{
|
||||
hostname: hostname.await,
|
||||
@ -164,11 +188,82 @@ async fn handle_default_route(
|
||||
).await
|
||||
}
|
||||
|
||||
async fn handle_ip_route(
|
||||
Query(ip_query): Query<IpQuery>,
|
||||
State(arc_state): State<Arc<ServiceSharedState>>,
|
||||
) -> Response {
|
||||
return handle_ip_request(ip_query, arc_state).await
|
||||
}
|
||||
|
||||
async fn handle_ip_route_with_path(
|
||||
Query(query): Query<BaseQuery>,
|
||||
State(arc_state): State<Arc<ServiceSharedState>>,
|
||||
extract::Path(address): extract::Path<IpAddr>,
|
||||
) -> Response {
|
||||
return handle_ip_request(IpQuery {
|
||||
format: query.format,
|
||||
lang: query.lang,
|
||||
ip: address,
|
||||
}, arc_state).await
|
||||
}
|
||||
|
||||
async fn handle_ip_request(
|
||||
ip_query: IpQuery,
|
||||
arc_state: Arc<ServiceSharedState>,
|
||||
) -> Response {
|
||||
|
||||
let address = ip_query.ip;
|
||||
let format = ip_query.format.unwrap_or(ResponseFormat::TextHtml);
|
||||
|
||||
let state = Arc::clone(&arc_state);
|
||||
|
||||
// do reverse lookup
|
||||
let hostname = simple_dns::reverse_lookup(&state.dns_resolver, &address);
|
||||
|
||||
// asn lookup
|
||||
let asn_result = state.asn_db.query_asn_for_ip(address);
|
||||
|
||||
// location lookup
|
||||
let location_result = state.location_db.query_location_for_ip(
|
||||
address,
|
||||
&vec![&ip_query.lang.as_ref().unwrap_or(&"en".to_string()), &"en".to_string()]
|
||||
);
|
||||
|
||||
let result = IpResult{
|
||||
hostname: hostname.await,
|
||||
asn: asn_result,
|
||||
location: location_result,
|
||||
};
|
||||
|
||||
state.templating_engine.render_view(
|
||||
format,
|
||||
View::Ip{query: ip_query, result: result}
|
||||
).await
|
||||
}
|
||||
|
||||
async fn handle_dig_route(
|
||||
Query(dig_query): Query<DigQuery>,
|
||||
State(arc_state): State<Arc<ServiceSharedState>>,
|
||||
) -> Response {
|
||||
|
||||
return handle_dig_request(dig_query, arc_state).await
|
||||
}
|
||||
|
||||
async fn handle_dig_route_with_path(
|
||||
Query(query): Query<BaseQuery>,
|
||||
State(arc_state): State<Arc<ServiceSharedState>>,
|
||||
extract::Path(name): extract::Path<String>,
|
||||
) -> Response {
|
||||
return handle_dig_request(DigQuery {
|
||||
format: query.format,
|
||||
name: name,
|
||||
}, arc_state).await
|
||||
}
|
||||
|
||||
async fn handle_dig_request(
|
||||
dig_query: DigQuery,
|
||||
arc_state: Arc<ServiceSharedState>,
|
||||
) -> Response {
|
||||
|
||||
let state = Arc::clone(&arc_state);
|
||||
let name = &dig_query.name;
|
||||
let format = dig_query.format.unwrap_or(ResponseFormat::TextHtml);
|
||||
|
Reference in New Issue
Block a user